fix: process list patch values in http requests

This commit parses values from post request as well as always serializes
values for the web interface
This commit is contained in:
2024-11-22 17:22:37 +02:00
parent 3c1fdec0e9
commit 45a620c40b
7 changed files with 29 additions and 6 deletions

View File

@ -163,7 +163,7 @@
const variableValueInput = document.createElement("input");
variableValueInput.classList.add("form-control");
variableValueInput.readOnly = true;
variableValueInput.value = variable.value;
variableValueInput.value = JSON.stringify(variable.value);
const variableButtonRemove = document.createElement("button");
variableButtonRemove.type = "button";

View File

@ -100,11 +100,11 @@ class PkgbuildPatch:
return cls(**filter_json(dump, known_fields))
@classmethod
def parse(cls, key: str | None, source: str) -> Self:
def parse(cls, key: str | None, source: str | list[str]) -> Self:
"""
parse string value to the PKGBUILD patch value. This method simply takes string, tries to identify it as array
or just string and return the respective value. Functions are returned as is. Shell arrays and single values
are returned without quotes
are returned without quotes. If source is ``list``, then value is returned as is
Args:
key(str | None): variable key
@ -118,6 +118,9 @@ class PkgbuildPatch:
case function if key is not None and key.endswith("()"):
# the key looks like a function, no further processing should be applied here
return function
case list():
# do not try to perform operations on the list, just return as is
return source
case shell_array if shell_array.startswith("(") and shell_array.endswith(")"):
# the source value looks like shell array, remove brackets and parse with shlex
return shlex.split(shell_array[1:-1])

View File

@ -101,6 +101,6 @@ class PatchesView(StatusViewGuard, BaseView):
except Exception as ex:
raise HTTPBadRequest(reason=str(ex))
self.service().package_patches_update(package_base, PkgbuildPatch(key, value))
self.service().package_patches_update(package_base, PkgbuildPatch.parse(key, value))
raise HTTPNoContent

View File

@ -68,7 +68,7 @@ class AddView(BaseView):
try:
data = await self.request.json()
packages = self.get_non_empty(lambda key: [package for package in data[key] if package], "packages")
patches = [PkgbuildPatch(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])]
patches = [PkgbuildPatch.parse(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])]
except Exception as ex:
raise HTTPBadRequest(reason=str(ex))

View File

@ -68,7 +68,7 @@ class RequestView(BaseView):
try:
data = await self.request.json()
packages = self.get_non_empty(lambda key: [package for package in data[key] if package], "packages")
patches = [PkgbuildPatch(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])]
patches = [PkgbuildPatch.parse(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])]
except Exception as ex:
raise HTTPBadRequest(reason=str(ex))

View File

@ -61,6 +61,7 @@ def test_parse() -> None:
assert PkgbuildPatch.parse("key", """("QU'OUTED" ARRAY VALUE)""").value == ["QU'OUTED", "ARRAY", "VALUE"]
assert PkgbuildPatch.parse("key()", """{ function with " quotes }""").value == """{ function with " quotes }"""
assert PkgbuildPatch.parse("key", json.dumps(["array", "value"])).value == ["array", "value"]
assert PkgbuildPatch.parse("key", ["array", "value"]).value == ["array", "value"]
def test_quote() -> None:

View File

@ -82,6 +82,25 @@ async def test_post_full_diff(client: TestClient, package_ahriman: Package) -> N
assert patches == [payload]
async def test_post_array(client: TestClient, package_ahriman: Package) -> None:
"""
must create patch from list variable
"""
await client.post(f"/api/v1/packages/{package_ahriman.base}",
json={"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()})
request_schema = pytest.helpers.schema_request(PatchesView.post)
payload = {"key": "k", "value": "(array value)"}
assert not request_schema.validate(payload)
response = await client.post(f"/api/v1/packages/{package_ahriman.base}/patches", json=payload)
assert response.status == 204
response = await client.get(f"/api/v1/packages/{package_ahriman.base}/patches")
patches = await response.json()
parsed = [PkgbuildPatch(patch["key"], patch["value"]) for patch in patches]
assert parsed == [PkgbuildPatch("k", ["array", "value"])]
async def test_post_exception(client: TestClient, package_ahriman: Package) -> None:
"""
must raise exception on invalid payload