From 2be6bd8217b00566ca66822022b080d799fd0811 Mon Sep 17 00:00:00 2001 From: ChristopherSpelt Date: Wed, 6 Nov 2024 10:58:57 +0100 Subject: [PATCH] Change TaskRegisty Client endpoints --- amt/clients/clients.py | 4 +- tests/api/routes/test_project.py | 75 ++++++++++++++++++++-- tests/clients/test_clients.py | 4 +- tests/constants.py | 34 ++++++++++ tests/services/test_instruments_service.py | 18 ++++-- tests/services/test_instruments_state.py | 60 +++++++++++++++-- 6 files changed, 175 insertions(+), 20 deletions(-) diff --git a/amt/clients/clients.py b/amt/clients/clients.py index 0d498203..c8768db9 100644 --- a/amt/clients/clients.py +++ b/amt/clients/clients.py @@ -30,7 +30,9 @@ def get_instrument_list(self) -> RepositoryContent: return RepositoryContent.model_validate(response.json()["entries"]) def get_instrument(self, urn: str, version: str = "latest") -> Instrument: - response = self.client.get(f"{TaskRegistryAPIClient.base_url}/urns/", params={"version": version, "urn": urn}) + response = self.client.get( + f"{TaskRegistryAPIClient.base_url}/instruments/urn/{urn}", params={"version": version} + ) if response.status_code != 200: raise AMTNotFound() diff --git a/tests/api/routes/test_project.py b/tests/api/routes/test_project.py index 8e230c96..9a6e159b 100644 --- a/tests/api/routes/test_project.py +++ b/tests/api/routes/test_project.py @@ -4,9 +4,17 @@ from amt.api.routes.project import set_path from amt.models import Project from httpx import AsyncClient +from pytest_httpx import HTTPXMock from pytest_mock import MockFixture -from tests.constants import default_project, default_project_with_system_card, default_task +from tests.constants import ( + TASK_REGISTRY_AIIA_CONTENT_PAYLOAD, + TASK_REGISTRY_CONTENT_PAYLOAD, + TASK_REGISTRY_LIST_PAYLOAD, + default_project, + default_project_with_system_card, + default_task, +) from tests.database_test_utils import DatabaseTestUtils @@ -67,7 +75,18 @@ async def test_get_system_card_unknown_project(client: AsyncClient) -> None: @pytest.mark.asyncio -async def test_get_assessment_card(client: AsyncClient, db: DatabaseTestUtils) -> None: +async def test_get_assessment_card(client: AsyncClient, httpx_mock: HTTPXMock, db: DatabaseTestUtils) -> None: + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) # given await db.given([default_project_with_system_card("testproject1")]) @@ -109,7 +128,18 @@ async def test_get_assessment_card_unknown_assessment(client: AsyncClient, db: D @pytest.mark.asyncio -async def test_get_model_card(client: AsyncClient, db: DatabaseTestUtils) -> None: +async def test_get_model_card(client: AsyncClient, httpx_mock: HTTPXMock, db: DatabaseTestUtils) -> None: + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) # given await db.given([default_project_with_system_card("testproject1")]) @@ -161,7 +191,18 @@ async def test_get_project_details(client: AsyncClient, db: DatabaseTestUtils) - @pytest.mark.asyncio -async def test_get_system_card_requirements(client: AsyncClient, db: DatabaseTestUtils) -> None: +async def test_get_system_card_requirements(client: AsyncClient, httpx_mock: HTTPXMock, db: DatabaseTestUtils) -> None: + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) # given await db.given([default_project_with_system_card("testproject1"), default_task(project_id=1, status_id=1)]) @@ -175,7 +216,18 @@ async def test_get_system_card_requirements(client: AsyncClient, db: DatabaseTes @pytest.mark.asyncio -async def test_get_system_card_data_page(client: AsyncClient, db: DatabaseTestUtils) -> None: +async def test_get_system_card_data_page(client: AsyncClient, httpx_mock: HTTPXMock, db: DatabaseTestUtils) -> None: + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) # given await db.given([default_project_with_system_card("testproject1"), default_task(project_id=1, status_id=1)]) @@ -189,7 +241,18 @@ async def test_get_system_card_data_page(client: AsyncClient, db: DatabaseTestUt @pytest.mark.asyncio -async def test_get_system_card_instruments(client: AsyncClient, db: DatabaseTestUtils) -> None: +async def test_get_system_card_instruments(client: AsyncClient, httpx_mock: HTTPXMock, db: DatabaseTestUtils) -> None: + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) # given await db.given([default_project_with_system_card("testproject1"), default_task(project_id=1, status_id=1)]) diff --git a/tests/clients/test_clients.py b/tests/clients/test_clients.py index 6f158698..17bc2f2b 100644 --- a/tests/clients/test_clients.py +++ b/tests/clients/test_clients.py @@ -32,7 +32,7 @@ def test_task_registry_api_client_get_instrument(httpx_mock: HTTPXMock): # given task_registry_api_client = TaskRegistryAPIClient() httpx_mock.add_response( - url="https://task-registry.apps.digilab.network/urns/?version=latest&urn=urn%3Anl%3Aaivt%3Atr%3Aiama%3A1.0", + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), ) @@ -48,7 +48,7 @@ def test_task_registry_api_client_get_instrument_not_succesfull(httpx_mock: HTTP task_registry_api_client = TaskRegistryAPIClient() httpx_mock.add_response( status_code=408, - url="https://task-registry.apps.digilab.network/urns/?version=latest&urn=urn%3Anl%3Aaivt%3Atr%3Aiama%3A1.0", + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", ) urn = "urn:nl:aivt:tr:iama:1.0" diff --git a/tests/constants.py b/tests/constants.py index 9c88c1fd..f2143ab5 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -91,6 +91,17 @@ def default_task( "_links": { "self": "https://minbzk.github.io/task-registry/instruments/iama.yaml" } + }, + { + "type": "file", + "size": 32897, + "name": "aiia.yaml", + "path": "instruments/aiia.yaml", + "urn": "urn:nl:aivt:tr:aiia:1.0", + "download_url": "https://minbzk.github.io/task-registry/instruments/aiia.yaml", + "_links": { + "self": "https://minbzk.github.io/task-registry/instruments/aiia.yaml" + } } ] } @@ -118,3 +129,26 @@ def default_task( "tasks": [] } """ + +TASK_REGISTRY_AIIA_CONTENT_PAYLOAD = """ +{ + "systemcard_path": ".assessments[]", + "schema_version": "1.1.0", + "name": "AI Impact Assessment (AIIA)", + "description": "Het IAMA helpt om de risico's voor mensenrechten bij het gebruik van algoritmen \ + in kaart te brengen en maatregelen te nemen om deze aan te pakken.", + "urn": "urn:nl:aivt:tr:aiia:1.0", + "language": "nl", + "owners": [ + { + "organization": "", + "name": "", + "email": "", + "role": "" + } + ], + "date": "", + "url": "https://www.rijksoverheid.nl/documenten/rapporten/2021/02/25/impact-assessment-mensenrechten-en-algoritmes", + "tasks": [] +} +""" diff --git a/tests/services/test_instruments_service.py b/tests/services/test_instruments_service.py index 5a039991..29c92039 100644 --- a/tests/services/test_instruments_service.py +++ b/tests/services/test_instruments_service.py @@ -3,6 +3,7 @@ from amt.services.instruments import InstrumentsService from pytest_httpx import HTTPXMock from tests.constants import ( + TASK_REGISTRY_AIIA_CONTENT_PAYLOAD, TASK_REGISTRY_CONTENT_PAYLOAD, TASK_REGISTRY_LIST_PAYLOAD, ) @@ -21,8 +22,9 @@ def test_fetch_urns(httpx_mock: HTTPXMock): result = instruments_service.fetch_urns() # then - assert len(result) == 1 + assert len(result) == 2 assert result[0] == "urn:nl:aivt:tr:iama:1.0" + assert result[1] == "urn:nl:aivt:tr:aiia:1.0" def test_fetch_instruments(httpx_mock: HTTPXMock): @@ -33,15 +35,19 @@ def test_fetch_instruments(httpx_mock: HTTPXMock): ) httpx_mock.add_response( - url="https://task-registry.apps.digilab.network/urns/?version=latest&urn=urn%3Anl%3Aaivt%3Atr%3Aiama%3A1.0", + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) # when result = instruments_service.fetch_instruments() # then - assert len(result) == 1 + assert len(result) == 2 def test_fetch_instrument_with_urn(httpx_mock: HTTPXMock): @@ -51,7 +57,7 @@ def test_fetch_instrument_with_urn(httpx_mock: HTTPXMock): url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() ) httpx_mock.add_response( - url="https://task-registry.apps.digilab.network/urns/?version=latest&urn=urn%3Anl%3Aaivt%3Atr%3Aiama%3A1.0", + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), ) @@ -70,7 +76,7 @@ def test_fetch_instruments_with_urns(httpx_mock: HTTPXMock): url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() ) httpx_mock.add_response( - url="https://task-registry.apps.digilab.network/urns/?version=latest&urn=urn%3Anl%3Aaivt%3Atr%3Aiama%3A1.0", + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), ) @@ -105,7 +111,7 @@ def test_fetch_instruments_invalid(httpx_mock: HTTPXMock): ) httpx_mock.add_response( - url="https://task-registry.apps.digilab.network/urns/?version=latest&urn=urn%3Anl%3Aaivt%3Atr%3Aiama%3A1.0", + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", content=b'{"test": 1}', ) diff --git a/tests/services/test_instruments_state.py b/tests/services/test_instruments_state.py index f1122a9e..8cd9598b 100644 --- a/tests/services/test_instruments_state.py +++ b/tests/services/test_instruments_state.py @@ -13,7 +13,13 @@ get_next_tasks_per_instrument, get_task_timestamp_from_assessment_card, ) -from tests.constants import default_instrument +from pytest_httpx import HTTPXMock +from tests.constants import ( + TASK_REGISTRY_AIIA_CONTENT_PAYLOAD, + TASK_REGISTRY_CONTENT_PAYLOAD, + TASK_REGISTRY_LIST_PAYLOAD, + default_instrument, +) # TODO: Add more cases of the system_card for coverage @@ -171,8 +177,19 @@ def test_find_next_tasks_for_instrument_correct_lifecycle(system_card: SystemCar assert tasks["tasks_per_lifecycle"][2] == test_tasks -def test_get_state_per_instrument(system_card: SystemCard): +def test_get_state_per_instrument(system_card: SystemCard, httpx_mock: HTTPXMock): instrument_state_service = InstrumentStateService(system_card) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) res = instrument_state_service.get_state_per_instrument() assert {"urn": "urn:nl:aivt:tr:aiia:1.0", "in_progress": 1, "name": "AI Impact Assessment (AIIA)"} in res assert { @@ -184,22 +201,55 @@ def test_get_state_per_instrument(system_card: SystemCard): assert {"in_progress": 0, "name": "URN not found in Task Registry.", "urn": "urn:instrument:assessment"} in res -def test_get_amount_completed_instruments(system_card: SystemCard): +def test_get_amount_completed_instruments(system_card: SystemCard, httpx_mock: HTTPXMock): instrument_state_service = InstrumentStateService(system_card) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) _ = instrument_state_service.get_state_per_instrument() res = instrument_state_service.get_amount_completed_instruments() assert res == 1 -def test_get_amount_total_instruments(system_card: SystemCard): +def test_get_amount_total_instruments(system_card: SystemCard, httpx_mock: HTTPXMock): instrument_state_service = InstrumentStateService(system_card) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) _ = instrument_state_service.get_state_per_instrument() res = instrument_state_service.get_amount_total_instruments() assert res == 3 -def test_get_amount_completed_instruments_one_completed(system_card: SystemCard): +def test_get_amount_completed_instruments_one_completed(system_card: SystemCard, httpx_mock: HTTPXMock): instrument_state_service = InstrumentStateService(system_card) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/", content=TASK_REGISTRY_LIST_PAYLOAD.encode() + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:iama:1.0?version=latest", + content=TASK_REGISTRY_CONTENT_PAYLOAD.encode(), + ) + httpx_mock.add_response( + url="https://task-registry.apps.digilab.network/instruments/urn/urn:nl:aivt:tr:aiia:1.0?version=latest", + content=TASK_REGISTRY_AIIA_CONTENT_PAYLOAD.encode(), + ) _ = instrument_state_service.get_state_per_instrument() instrument_state_service.instrument_states = [{"in_progress": 0}, {"in_progress": 1}] res = instrument_state_service.get_amount_completed_instruments()