From 87e3a9be39319ea76aef287823f14b3b8ac45a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Susana=20V=C3=A1zquez?= <3016283+svazquezco@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:16:02 +0100 Subject: [PATCH] refactor(tests): share the API context setup through a factory fixture Every agreement router test built its own autospecced `APIContext` and wired the two Marketplace services by hand. Move that into an `api_context_factory` fixture in the routers `conftest.py`, next to the service doubles it depends on, and add `agreement_id` and `vendor_external_id` so the ids stop being repeated literals. Take the agreement double from an `agreement_in_mpt` fixture, read the services back off the context as the schedule tests already do, and build the real `Pagination` and `PaginatedCollection` value objects instead of mocking them. --- backend/tests/routers/conftest.py | 26 ++++++++ backend/tests/routers/test_agreements.py | 81 ++++++++++++------------ 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/backend/tests/routers/conftest.py b/backend/tests/routers/conftest.py index 4a10543..a4ca03e 100644 --- a/backend/tests/routers/conftest.py +++ b/backend/tests/routers/conftest.py @@ -1,4 +1,6 @@ import pytest +from mpt_api_client.models.meta import Pagination +from mpt_extension_sdk.api.context import APIContext, AuthenticatedRequestContext from mpt_extension_sdk.services.mpt_api_service import MPTAPIService from mpt_extension_sdk.services.mpt_api_service.agreement import AgreementService @@ -21,3 +23,27 @@ def mpt_api_service(mpt_api_service_factory): @pytest.fixture def vendor_mpt_api_service(mpt_api_service_factory): return mpt_api_service_factory() + + +@pytest.fixture +def api_context_factory(mocker, mpt_api_service, vendor_mpt_api_service): + def factory(*, task=None, offset=0, limit=10): + ctx = mocker.create_autospec(APIContext, instance=True) + ctx.mpt_api_service = mpt_api_service + ctx.vendor_mpt_api_service = vendor_mpt_api_service + ctx.task = task + ctx.request = mocker.create_autospec(AuthenticatedRequestContext, instance=True) + ctx.request.pagination = Pagination(offset=offset, limit=limit) + return ctx + + return factory + + +@pytest.fixture +def agreement_id(agreement_payload): + return agreement_payload["id"] + + +@pytest.fixture +def vendor_external_id(): + return "ABC-2023-C07-dbeee0b302c0" diff --git a/backend/tests/routers/test_agreements.py b/backend/tests/routers/test_agreements.py index c74159b..88ba821 100644 --- a/backend/tests/routers/test_agreements.py +++ b/backend/tests/routers/test_agreements.py @@ -2,8 +2,6 @@ import pytest from mpt_api_client.exceptions import MPTAPIError -from mpt_api_client.models.meta import Pagination -from mpt_extension_sdk.api.context import APIContext, AuthenticatedRequestContext from mpt_extension_sdk.api.errors import NotFoundError from mpt_extension_sdk.models import Agreement from mpt_extension_sdk.models.external_id import ExternalIds @@ -16,22 +14,28 @@ ) -async def test_get_reads_marketplace(mocker, agreement_payload, mpt_api_service): - agreement = mocker.Mock(spec=Agreement) +@pytest.fixture +def agreement_in_mpt(mocker, agreement_payload, vendor_external_id, mpt_api_service): + agreement = mocker.create_autospec(Agreement, instance=True) agreement.to_dict.return_value = agreement_payload - ctx = mocker.create_autospec(APIContext, instance=True) - ctx.mpt_api_service = mpt_api_service + agreement.external_ids = ExternalIds(vendor=vendor_external_id) mpt_api_service.agreements.get_by_id.return_value = agreement + return agreement - result = await get_agreement("AGR-1234-5678", ctx) - mpt_api_service.agreements.get_by_id.assert_awaited_once_with("AGR-1234-5678") +async def test_get_reads_marketplace( + api_context_factory, agreement_id, agreement_in_mpt, agreement_payload +): + ctx = api_context_factory() + + result = await get_agreement(agreement_id, ctx) + + ctx.mpt_api_service.agreements.get_by_id.assert_awaited_once_with(agreement_id) assert result.payload == agreement_payload -async def test_get_maps_marketplace_not_found(mocker, mpt_api_service): - ctx = mocker.create_autospec(APIContext, instance=True) - ctx.mpt_api_service = mpt_api_service +async def test_get_maps_marketplace_not_found(api_context_factory, mpt_api_service): + ctx = api_context_factory() mpt_api_service.agreements.get_by_id.side_effect = MPTAPIError( HTTPStatus.NOT_FOUND, "Not Found", {"detail": "Entity for given id not-found not found"} ) @@ -40,39 +44,36 @@ async def test_get_maps_marketplace_not_found(mocker, mpt_api_service): await get_agreement("not-found", ctx) -async def test_sync_writes_back_as_the_vendor( - mocker, agreement_payload, mpt_api_service, vendor_mpt_api_service -): - agreement = mocker.Mock(spec=Agreement) - agreement.to_dict.return_value = agreement_payload - agreement.external_ids = ExternalIds(vendor="ABC-2023-C07-dbeee0b302c0") - ctx = mocker.create_autospec(APIContext, instance=True) - ctx.mpt_api_service = mpt_api_service - ctx.vendor_mpt_api_service = vendor_mpt_api_service - mpt_api_service.agreements.get_by_id.return_value = agreement +async def test_get_agreements_paginated(api_context_factory, agreement_payload): + page = PaginatedCollection(limit=10, offset=0, resources=[agreement_payload], total=2) + ctx = api_context_factory(offset=0, limit=10) + ctx.mpt_api_service.agreements.get_all.return_value = page - result = await sync_agreement("AGR-1234-5678", ctx) + result = await get_agreements(ctx) + + ctx.mpt_api_service.agreements.get_all.assert_awaited_once_with(offset=0, limit=10) + assert result.payload == [agreement_payload] + assert result.paginated_result.total == 2 + assert result.paginated_result.offset == 0 + assert result.paginated_result.limit == 10 + + +async def test_sync_answers_with_the_agreement( + api_context_factory, agreement_id, agreement_in_mpt, agreement_payload +): + result = await sync_agreement(agreement_id, api_context_factory()) - mpt_api_service.agreements.get_by_id.assert_awaited_once_with("AGR-1234-5678") - vendor_mpt_api_service.agreements.update.assert_awaited_once_with( - "AGR-1234-5678", {"externalIds": {"vendor": "ABC-2023-C07-dbeee0b302c0"}} - ) - mpt_api_service.agreements.update.assert_not_awaited() assert result.payload == agreement_payload -async def test_get_agreements_paginated(mocker, agreement_payload, mpt_api_service): - page = mocker.Mock(spec=PaginatedCollection, resources=[agreement_payload], total=1) - ctx = mocker.create_autospec(APIContext, instance=True) - ctx.request = mocker.create_autospec(AuthenticatedRequestContext, instance=True) - ctx.request.pagination = mocker.Mock(spec=Pagination, offset=0, limit=10) - ctx.mpt_api_service = mpt_api_service - mpt_api_service.agreements.get_all.return_value = page +async def test_sync_writes_back_as_the_vendor( + api_context_factory, agreement_id, agreement_in_mpt, vendor_external_id +): + ctx = api_context_factory() - result = await get_agreements(ctx) + await sync_agreement(agreement_id, ctx) # act - mpt_api_service.agreements.get_all.assert_awaited_once_with(offset=0, limit=10) - assert result.payload == [agreement_payload] - assert result.paginated_result.total == 1 - assert result.paginated_result.offset == 0 - assert result.paginated_result.limit == 10 + ctx.vendor_mpt_api_service.agreements.update.assert_awaited_once_with( + agreement_id, {"externalIds": {"vendor": vendor_external_id}} + ) + ctx.mpt_api_service.agreements.update.assert_not_awaited()