From 7bb2207e2ff260786970f035964005a697eb9c44 Mon Sep 17 00:00:00 2001 From: Albert Sola Date: Wed, 10 Sep 2025 09:21:59 +0100 Subject: [PATCH] MPT-13320 Catalog items --- mpt_api_client/resources/catalog/catalog.py | 11 +++ mpt_api_client/resources/catalog/items.py | 47 +++++++++++++ setup.cfg | 1 + tests/resources/catalog/test_catalog.py | 77 ++++++++++++--------- tests/resources/catalog/test_items.py | 29 ++++++++ 5 files changed, 131 insertions(+), 34 deletions(-) create mode 100644 mpt_api_client/resources/catalog/items.py create mode 100644 tests/resources/catalog/test_items.py diff --git a/mpt_api_client/resources/catalog/catalog.py b/mpt_api_client/resources/catalog/catalog.py index 4c76c1d3..53b61766 100644 --- a/mpt_api_client/resources/catalog/catalog.py +++ b/mpt_api_client/resources/catalog/catalog.py @@ -1,4 +1,5 @@ from mpt_api_client.http import AsyncHTTPClient, HTTPClient +from mpt_api_client.resources.catalog.items import AsyncItemsService, ItemsService from mpt_api_client.resources.catalog.products import AsyncProductsService, ProductsService @@ -13,6 +14,11 @@ def products(self) -> ProductsService: """Products service.""" return ProductsService(http_client=self.http_client) + @property + def items(self) -> ItemsService: # noqa: WPS110 + """Items service.""" + return ItemsService(http_client=self.http_client) + class AsyncCatalog: """Catalog MPT API Module.""" @@ -24,3 +30,8 @@ def __init__(self, *, http_client: AsyncHTTPClient): def products(self) -> AsyncProductsService: """Products service.""" return AsyncProductsService(http_client=self.http_client) + + @property + def items(self) -> AsyncItemsService: # noqa: WPS110 + """Items service.""" + return AsyncItemsService(http_client=self.http_client) diff --git a/mpt_api_client/resources/catalog/items.py b/mpt_api_client/resources/catalog/items.py new file mode 100644 index 00000000..97a6e5f1 --- /dev/null +++ b/mpt_api_client/resources/catalog/items.py @@ -0,0 +1,47 @@ +from mpt_api_client.http import AsyncService, CreateMixin, Service +from mpt_api_client.http.mixins import ( + AsyncCreateMixin, + AsyncDeleteMixin, + AsyncUpdateMixin, + DeleteMixin, + UpdateMixin, +) +from mpt_api_client.models import Model +from mpt_api_client.resources.catalog.mixins import ( + AsyncPublishableMixin, + PublishableMixin, +) + + +class Item(Model): # noqa: WPS110 + """Item resource.""" + + +class ItemsServiceConfig: + """Items service configuration.""" + + _endpoint = "/public/v1/catalog/items" + _model_class = Item + _collection_key = "data" + + +class ItemsService( + CreateMixin[Item], + DeleteMixin, + UpdateMixin[Item], + PublishableMixin[Item], + Service[Item], + ItemsServiceConfig, +): + """Items service.""" + + +class AsyncItemsService( + AsyncCreateMixin[Item], + AsyncDeleteMixin, + AsyncUpdateMixin[Item], + AsyncPublishableMixin[Item], + AsyncService[Item], + ItemsServiceConfig, +): + """Items service.""" diff --git a/setup.cfg b/setup.cfg index a78bd925..827332d1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -34,6 +34,7 @@ extend-ignore = per-file-ignores = mpt_api_client/rql/query_builder.py: WPS110 WPS115 WPS210 WPS214 mpt_api_client/resources/catalog/products.py: WPS215 + mpt_api_client/resources/catalog/items.py: WPS215 mpt_api_client/resources/catalog/products_parameter_groups.py: WPS215 tests/http/test_async_service.py: WPS204 WPS202 tests/http/test_service.py: WPS204 WPS202 diff --git a/tests/resources/catalog/test_catalog.py b/tests/resources/catalog/test_catalog.py index 54255269..62d7e89b 100644 --- a/tests/resources/catalog/test_catalog.py +++ b/tests/resources/catalog/test_catalog.py @@ -1,58 +1,67 @@ +from typing import Any + import pytest -from mpt_api_client.http import AsyncHTTPClient -from mpt_api_client.resources.catalog import AsyncCatalog, Catalog +from mpt_api_client.resources.catalog.catalog import AsyncCatalog, Catalog +from mpt_api_client.resources.catalog.items import AsyncItemsService, ItemsService from mpt_api_client.resources.catalog.products import AsyncProductsService, ProductsService -def test_catalog_init(http_client): - catalog = Catalog(http_client=http_client) - - assert isinstance(catalog, Catalog) - assert catalog.http_client is http_client - - -def test_catalog_products_multiple_calls(http_client): - catalog = Catalog(http_client=http_client) - - products_service = catalog.products - products_service_additional = catalog.products - - assert products_service is not products_service_additional - assert isinstance(products_service, ProductsService) - assert isinstance(products_service_additional, ProductsService) - +@pytest.fixture +def catalog(http_client: Any) -> Catalog: + return Catalog(http_client=http_client) -def test_async_catalog_init(async_http_client: AsyncHTTPClient): - catalog = AsyncCatalog(http_client=async_http_client) - assert isinstance(catalog, AsyncCatalog) - assert catalog.http_client is async_http_client +@pytest.fixture +def async_catalog(async_http_client: Any) -> AsyncCatalog: + return AsyncCatalog(http_client=async_http_client) @pytest.mark.parametrize( - ("attr_name", "expected"), + ("property_name", "expected_service_class"), [ ("products", ProductsService), + ("items", ItemsService), ], ) -def test_catalog_properties(http_client, attr_name, expected): - catalog = Catalog(http_client=http_client) - - service = getattr(catalog, attr_name) +def test_catalog_properties( + catalog: Catalog, property_name: str, expected_service_class: type +) -> None: + """Test that Catalog properties return correct instances.""" + service = getattr(catalog, property_name) - assert isinstance(service, expected) + assert isinstance(service, expected_service_class) + assert service.http_client is catalog.http_client @pytest.mark.parametrize( - ("attr_name", "expected"), + ("property_name", "expected_service_class"), [ ("products", AsyncProductsService), + ("items", AsyncItemsService), ], ) -def test_async_catalog_properties(http_client, attr_name, expected): - catalog = AsyncCatalog(http_client=http_client) +def test_async_catalog_properties( + async_catalog: AsyncCatalog, property_name: str, expected_service_class: type +) -> None: + """Test that AsyncCatalog properties return correct instances.""" + service = getattr(async_catalog, property_name) + + assert isinstance(service, expected_service_class) + assert service.http_client is async_catalog.http_client + + +def test_catalog_initialization(http_client: Any) -> None: + """Test that Catalog can be properly initialized with http_client.""" + catalog = Catalog(http_client=http_client) + + assert catalog.http_client is http_client + assert isinstance(catalog, Catalog) + - service = getattr(catalog, attr_name) +def test_async_catalog_initialization(async_http_client: Any) -> None: + """Test that AsyncCatalog can be properly initialized with http_client.""" + async_catalog = AsyncCatalog(http_client=async_http_client) - assert isinstance(service, expected) + assert async_catalog.http_client is async_http_client + assert isinstance(async_catalog, AsyncCatalog) diff --git a/tests/resources/catalog/test_items.py b/tests/resources/catalog/test_items.py new file mode 100644 index 00000000..41119463 --- /dev/null +++ b/tests/resources/catalog/test_items.py @@ -0,0 +1,29 @@ +from typing import Any + +import pytest + +from mpt_api_client.resources.catalog.items import AsyncItemsService, ItemsService + + +@pytest.fixture +def items_service(http_client: Any) -> ItemsService: + return ItemsService(http_client=http_client) + + +@pytest.fixture +def async_items_service(async_http_client: Any) -> AsyncItemsService: + return AsyncItemsService(http_client=async_http_client) + + +@pytest.mark.parametrize( + "method", ["get", "create", "update", "delete", "review", "publish", "unpublish"] +) +def test_mixins_present(items_service: ItemsService, method: str) -> None: + assert hasattr(items_service, method) + + +@pytest.mark.parametrize( + "method", ["get", "create", "update", "delete", "review", "publish", "unpublish"] +) +def test_async_mixins_present(async_items_service: AsyncItemsService, method: str) -> None: + assert hasattr(async_items_service, method)