diff --git a/softpack_core/service.py b/softpack_core/service.py index d9108ca..217b63c 100644 --- a/softpack_core/service.py +++ b/softpack_core/service.py @@ -189,7 +189,9 @@ async def request_recipe( # type: ignore[no-untyped-def] + f'URL: {data["url"]}\n' + f'Description: {data["description"]}' ) - msg["Subject"] = f'SoftPack Recipe Request: {data["name"]}@{data["version"]}' + msg[ + "Subject" + ] = f'SoftPack Recipe Request: {data["name"]}@{data["version"]}' msg["From"] = recipeConfig["fromAddr"] msg["To"] = recipeConfig["toAddr"] @@ -198,8 +200,9 @@ async def request_recipe( # type: ignore[no-untyped-def] if recipeConfig["localHostname"] is not None: localhostname = recipeConfig["localHostname"] - - s = smtplib.SMTP(recipeConfig["smtp"], local_hostname=localhostname) + s = smtplib.SMTP( + recipeConfig["smtp"], local_hostname=localhostname + ) s.sendmail( recipeConfig["fromAddr"], [recipeConfig["toAddr"]], @@ -233,7 +236,12 @@ async def fulfil_recipe( # type: ignore[no-untyped-def] data["requestedName"], data["requestedVersion"] ) - if r is None: + if r is None or not any( + version == data["version"] + for pkg in app.spack.stored_packages + if pkg.name == data["name"] + for version in pkg.versions + ): return {"error": "Unknown Recipe"} for env in Environment.iter(): diff --git a/softpack_core/spack.py b/softpack_core/spack.py index d10bd43..088471b 100644 --- a/softpack_core/spack.py +++ b/softpack_core/spack.py @@ -43,11 +43,15 @@ def __init__(self) -> None: self.versions: list[Package] = list() self.descriptions: dict[str, str] = dict() - def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: + def handle_starttag( + self, tag: str, attrs: list[tuple[str, str | None]] + ) -> None: """Handle open tags.""" if tag == "div": self.recipe = next( - attr[1] for attr in attrs if attr[0] == "id" and isinstance(attr[1], str) + attr[1] + for attr in attrs + if attr[0] == "id" and isinstance(attr[1], str) ) elif tag == "dt": self.onDT = True diff --git a/tests/integration/test_recipe_requests.py b/tests/integration/test_recipe_requests.py index 909b223..4b50022 100644 --- a/tests/integration/test_recipe_requests.py +++ b/tests/integration/test_recipe_requests.py @@ -14,6 +14,7 @@ EnvironmentInput, PackageInput, ) +from softpack_core.spack import Package from tests.integration.utils import builder_called_correctly pytestmark = pytest.mark.repo @@ -124,82 +125,125 @@ def test_request_recipe(httpx_post, testable_env_input): httpx_post.assert_not_called() - resp = client.post( - url="/fulfilRequestedRecipe", - json={ - "name": "finalRecipe", - "version": "1.2.1", - "requestedName": "a_recipe", - "requestedVersion": "1.2", - }, + app.spack.stored_packages.append( + Package(name="finalRecipe", versions=["1.2.1"]) ) - assert resp.json() == {"message": "Recipe Fulfilled"} - - httpx_post.assert_called_once() - - env.name = "my_env-1" - env.packages[1] = PackageInput.from_name("finalRecipe@1.2.1") - - builder_called_correctly(httpx_post, env) - - envs = Environment.iter() - - assert len(envs) == 3 - assert len(envs[0].packages) == 2 - assert envs[0].packages[0].name == "pkg" - assert envs[0].packages[0].version == "1" - assert envs[0].packages[1].name == "finalRecipe" - assert envs[0].packages[1].version == "1.2.1" - - resp = client.get(url="/requestedRecipes") - - assert resp.json() == [ - { - "name": "b_recipe", - "version": "1.4", - "description": "Another description", - "url": "http://example.com", - "username": "me2", + try: + resp = client.post( + url="/fulfilRequestedRecipe", + json={ + "name": "finalRecipe", + "version": "1.2.1", + "requestedName": "a_recipe", + "requestedVersion": "1.2", + }, + ) + + assert resp.json() == {"message": "Recipe Fulfilled"} + + httpx_post.assert_called_once() + + env.name = "my_env-1" + env.packages[1] = PackageInput.from_name("finalRecipe@1.2.1") + + builder_called_correctly(httpx_post, env) + + envs = Environment.iter() + + assert len(envs) == 3 + assert len(envs[0].packages) == 2 + assert envs[0].packages[0].name == "pkg" + assert envs[0].packages[0].version == "1" + assert envs[0].packages[1].name == "finalRecipe" + assert envs[0].packages[1].version == "1.2.1" + + resp = client.get(url="/requestedRecipes") + + assert resp.json() == [ + { + "name": "b_recipe", + "version": "1.4", + "description": "Another description", + "url": "http://example.com", + "username": "me2", + } + ] + + resp = client.post( + url="/removeRequestedRecipe", + json={"name": "b_recipe", "version": "1.4"}, + ) + + assert resp.json() == {"message": "Request Removed"} + + resp = client.get(url="/requestedRecipes") + + assert resp.json() == [] + + resp = client.post( + url="/requestRecipe", + json={ + "name": "c_recipe", + "version": "0.9", + "description": "Lorem ipsum.", + "url": "http://example.com", + "username": "me", + }, + ) + + env = EnvironmentInput.from_path("users/me/my_env-2") + env.packages = [ + PackageInput.from_name("pkg@1"), + PackageInput.from_name("*c_recipe@0.9"), + ] + + assert isinstance(Environment.create(env), CreateEnvironmentSuccess) + + resp = client.post( + url="/removeRequestedRecipe", + json={"name": "c_recipe", "version": "0.9"}, + ) + + assert resp.json() == { + "error": "There are environments relying on this requested recipe;" + + " can not delete." } - ] - - resp = client.post( - url="/removeRequestedRecipe", - json={"name": "b_recipe", "version": "1.4"}, - ) - - assert resp.json() == {"message": "Request Removed"} - - resp = client.get(url="/requestedRecipes") - - assert resp.json() == [] - - resp = client.post( - url="/requestRecipe", - json={ - "name": "c_recipe", - "version": "0.9", - "description": "Lorem ipsum.", - "url": "http://example.com", - "username": "me", - }, - ) - - env = EnvironmentInput.from_path("users/me/my_env-2") - env.packages = [ - PackageInput.from_name("pkg@1"), - PackageInput.from_name("*c_recipe@0.9"), - ] - - assert isinstance(Environment.create(env), CreateEnvironmentSuccess) - - resp = client.post( - url="/removeRequestedRecipe", - json={"name": "c_recipe", "version": "0.9"}, - ) - assert resp.json() == { - "error": "There are environments relying on this requested recipe; " - + "can not delete." - } + resp = client.post( + url="/fulfilRequestedRecipe", + json={ + "name": "no_recipe", + "version": "1", + "requestedName": "c_recipe", + "requestedVersion": "0.9", + }, + ) + + assert resp.json() == {"error": "Unknown Recipe"} + + resp = client.post( + url="/fulfilRequestedRecipe", + json={ + "name": "finalRecipe", + "version": "1", + "requestedName": "c_recipe", + "requestedVersion": "0.9", + }, + ) + + assert resp.json() == {"error": "Unknown Recipe"} + + resp = client.post( + url="/fulfilRequestedRecipe", + json={ + "name": "finalRecipe", + "version": "1.2.1", + "requestedName": "c_recipe", + "requestedVersion": "0.9", + }, + ) + + assert resp.json() == {"message": "Recipe Fulfilled"} + finally: + app.spack.stored_packages.pop()