From a47325a40e51f387b9b97dfc04ce4021e6f905ee Mon Sep 17 00:00:00 2001 From: Robert Segal Date: Mon, 15 Dec 2025 12:01:14 -0700 Subject: [PATCH] Added e2e tests for commerce order subscription --- e2e_config.test.json | 1 + tests/e2e/commerce/conftest.py | 15 +++ .../commerce/order/subscription/conftest.py | 23 ++++ .../subscription/test_async_subscription.py | 103 ++++++++++++++++++ .../subscription/test_sync_subscription.py | 102 +++++++++++++++++ 5 files changed, 244 insertions(+) create mode 100644 tests/e2e/commerce/order/subscription/conftest.py create mode 100644 tests/e2e/commerce/order/subscription/test_async_subscription.py create mode 100644 tests/e2e/commerce/order/subscription/test_sync_subscription.py diff --git a/e2e_config.test.json b/e2e_config.test.json index 8ac6fdd..90b1fe9 100644 --- a/e2e_config.test.json +++ b/e2e_config.test.json @@ -26,6 +26,7 @@ "catalog.unit.id": "UNT-1229", "commerce.agreement.attachment.id": "ATT-9850-2169-6098-0001", "commerce.agreement.id": "AGR-9850-2169-6098", + "commerce.agreement.subscription.line.id": "ALI-9850-2169-6098-0001", "commerce.assets.agreement.id": "AGR-2473-3299-1721", "commerce.assets.id": "AST-0625-6526-6154", "commerce.assets.order.id": "ORD-7707-7765-8445", diff --git a/tests/e2e/commerce/conftest.py b/tests/e2e/commerce/conftest.py index 9555506..52c95e1 100644 --- a/tests/e2e/commerce/conftest.py +++ b/tests/e2e/commerce/conftest.py @@ -49,3 +49,18 @@ def asset_item_id(e2e_config): @pytest.fixture def asset_agreement_id(e2e_config): return e2e_config["commerce.assets.agreement.id"] + + +@pytest.fixture +def subscription_id(e2e_config): + return e2e_config["commerce.subscription.id"] + + +@pytest.fixture +def agreement_subscription_line_id(e2e_config): + return e2e_config["commerce.agreement.subscription.line.id"] + + +@pytest.fixture +def invalid_subscription_id(): + return "SUB-0000-0000-0000" diff --git a/tests/e2e/commerce/order/subscription/conftest.py b/tests/e2e/commerce/order/subscription/conftest.py new file mode 100644 index 0000000..522e2a9 --- /dev/null +++ b/tests/e2e/commerce/order/subscription/conftest.py @@ -0,0 +1,23 @@ +import pytest +from freezegun import freeze_time + + +@pytest.fixture +def order_subscription_factory(agreement_subscription_line_id): + @freeze_time("2025-11-14T09:00:00.000Z") + def factory( + name: str = "E2E Created Order Subscription", + external_vendor_id: str = "ext-vendor-id", + ): + return { + "name": name, + "startDate": "2025-11-03T09:00:00.000Z", + "commitmentDate": "2026-11-02T09:00:00.000Z", + "autoRenew": True, + "externalIds": {"vendor": external_vendor_id}, + "template": None, + "lines": [{"id": agreement_subscription_line_id}], + "parameters": {"fulfillment": []}, + } + + return factory diff --git a/tests/e2e/commerce/order/subscription/test_async_subscription.py b/tests/e2e/commerce/order/subscription/test_async_subscription.py new file mode 100644 index 0000000..6a352a7 --- /dev/null +++ b/tests/e2e/commerce/order/subscription/test_async_subscription.py @@ -0,0 +1,103 @@ +from contextlib import asynccontextmanager + +import pytest + +from mpt_api_client.exceptions import MPTAPIError +from mpt_api_client.rql.query_builder import RQLQuery + +pytestmark = [pytest.mark.flaky] + + +@asynccontextmanager +async def async_create_fixture_resource_and_delete(resource_manager, resource_data): + resource = await resource_manager.create(resource_data) + + yield resource + + try: + await resource_manager.delete(resource.id) + except MPTAPIError as error: + print(f"TEARDOWN - Unable to delete subscription: {getattr(error, 'title', str(error))}") # noqa: WPS421 + + +@pytest.fixture +async def created_order_subscription(async_mpt_vendor, order_subscription_factory, order_id): + # Must use this fixture for all tests to prevent api failures + subscription_data = order_subscription_factory() + orders = async_mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + async with async_create_fixture_resource_and_delete( + subscriptions, subscription_data + ) as subscription: + yield subscription + + +async def test_get_order_subscription_by_id(async_mpt_vendor, created_order_subscription, order_id): + subscription_id = created_order_subscription.id + subscriptions = async_mpt_vendor.commerce.orders.subscriptions(order_id) + + result = await subscriptions.get(subscription_id) + + assert result is not None + + +async def test_list_order_subscriptions(async_mpt_vendor, created_order_subscription, order_id): + limit = 10 + orders = async_mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + + result = await subscriptions.fetch_page(limit=limit) + + assert result is not None + + +async def test_get_order_subscription_by_id_not_found( + async_mpt_vendor, created_order_subscription, order_id, invalid_subscription_id +): + orders = async_mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + + with pytest.raises(MPTAPIError, match="404 Not Found"): + await subscriptions.get(invalid_subscription_id) + + +async def test_filter_order_subscriptions(async_mpt_vendor, created_order_subscription, order_id): + select_fields = ["-externalIds"] + subscription_id = created_order_subscription.id + subscriptions = async_mpt_vendor.commerce.orders.subscriptions(order_id) + filtered_subscriptions = ( + subscriptions.filter(RQLQuery(id=subscription_id)) + .filter(RQLQuery(name="E2E Created Order Subscription")) + .select(*select_fields) + ) + + result = [subscription async for subscription in filtered_subscriptions.iterate()] + + assert len(result) == 1 + + +def test_create_order_subscription(created_order_subscription): + result = created_order_subscription + + assert result is not None + + +async def test_update_order_subscription(async_mpt_vendor, created_order_subscription, order_id): + subscription_id = created_order_subscription.id + updated_subscription_data = { + "name": "E2E Updated Order Subscription", + } + orders = async_mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + + result = await subscriptions.update(subscription_id, updated_subscription_data) + + assert result is not None + + +async def test_delete_order_subscription(async_mpt_vendor, created_order_subscription, order_id): + subscription_id = created_order_subscription.id + orders = async_mpt_vendor.commerce.orders + + subscriptions = orders.subscriptions(order_id) + await subscriptions.delete(subscription_id) diff --git a/tests/e2e/commerce/order/subscription/test_sync_subscription.py b/tests/e2e/commerce/order/subscription/test_sync_subscription.py new file mode 100644 index 0000000..0afabb8 --- /dev/null +++ b/tests/e2e/commerce/order/subscription/test_sync_subscription.py @@ -0,0 +1,102 @@ +from contextlib import contextmanager + +import pytest + +from mpt_api_client.exceptions import MPTAPIError +from mpt_api_client.rql.query_builder import RQLQuery + +pytestmark = [pytest.mark.flaky] + + +@contextmanager +def create_fixture_resource_and_delete(resource_manager, resource_data): + resource = resource_manager.create(resource_data) + + yield resource + + try: + resource_manager.delete(resource.id) + except MPTAPIError as error: + print(f"TEARDOWN - Unable to delete subscription: {getattr(error, 'title', str(error))}") # noqa: WPS421 + + +@pytest.fixture +def created_order_subscription(mpt_vendor, order_subscription_factory, order_id): + # Must use this fixture for all tests to prevent api failures + subscription_data = order_subscription_factory() + orders = mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + with create_fixture_resource_and_delete(subscriptions, subscription_data) as subscription: + yield subscription + + +def test_get_order_subscription_by_id(mpt_vendor, created_order_subscription, order_id): + subscription_id = created_order_subscription.id + subscriptions = mpt_vendor.commerce.orders.subscriptions(order_id) + + result = subscriptions.get(subscription_id) + + assert result is not None + + +def test_list_order_subscriptions(mpt_vendor, created_order_subscription, order_id): + limit = 10 + orders = mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + + result = subscriptions.fetch_page(limit=limit) + + assert result is not None + + +def test_get_order_subscription_by_id_not_found( + mpt_vendor, created_order_subscription, order_id, invalid_subscription_id +): + orders = mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + + with pytest.raises(MPTAPIError, match="404 Not Found"): + subscriptions.get(invalid_subscription_id) + + +def test_filter_order_subscriptions(mpt_vendor, created_order_subscription, order_id): + select_fields = ["-externalIds"] + subscription_id = created_order_subscription.id + subscriptions = mpt_vendor.commerce.orders.subscriptions(order_id) + filtered_subscriptions = ( + subscriptions.filter(RQLQuery(id=subscription_id)) + .filter(RQLQuery(name="E2E Created Order Subscription")) + .select(*select_fields) + ) + + result = list(filtered_subscriptions.iterate()) + + assert len(result) == 1 + + +def test_create_order_subscription(created_order_subscription): + result = created_order_subscription + + assert result is not None + + +def test_update_order_subscription(mpt_vendor, created_order_subscription, order_id): + subscription_id = created_order_subscription.id + updated_subscription_data = { + "name": "E2E Updated Order Subscription", + } + orders = mpt_vendor.commerce.orders + subscriptions = orders.subscriptions(order_id) + + result = subscriptions.update(subscription_id, updated_subscription_data) + + assert result is not None + + +def test_delete_order_subscription(mpt_vendor, created_order_subscription, order_id): + subscription_id = created_order_subscription.id + orders = mpt_vendor.commerce.orders + + result = orders.subscriptions(order_id) + + result.delete(subscription_id)