diff --git a/mpt_api_client/resources/catalog/mixins.py b/mpt_api_client/resources/catalog/mixins.py index 05ce4ae..644b6cc 100644 --- a/mpt_api_client/resources/catalog/mixins.py +++ b/mpt_api_client/resources/catalog/mixins.py @@ -73,3 +73,57 @@ async def unpublish(self, resource_id: str, resource_data: ResourceData | None = return await self._resource_action( # type: ignore[attr-defined, no-any-return] resource_id, "POST", "unpublish", json=resource_data ) + + +class ActivatableMixin[Model]: + """Activatable mixin adds the ability to activate and deactivate.""" + + def activate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model: + """Update state to Active. + + Args: + resource_id: Resource ID + resource_data: Resource data will be updated + """ + return self._resource_action( # type: ignore[attr-defined, no-any-return] + resource_id, "POST", "activate", json=resource_data + ) + + def deactivate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model: + """Update state to Inactive. + + Args: + resource_id: Resource ID + resource_data: Resource data will be updated + """ + return self._resource_action( # type: ignore[attr-defined, no-any-return] + resource_id, "POST", "deactivate", json=resource_data + ) + + +class AsyncActivatableMixin[Model]: + """Activatable mixin adds the ability to activate and deactivate.""" + + async def activate(self, resource_id: str, resource_data: ResourceData | None = None) -> Model: + """Update state to Active. + + Args: + resource_id: Resource ID + resource_data: Resource data will be updated + """ + return await self._resource_action( # type: ignore[attr-defined, no-any-return] + resource_id, "POST", "activate", json=resource_data + ) + + async def deactivate( + self, resource_id: str, resource_data: ResourceData | None = None + ) -> Model: + """Update state to Inactive. + + Args: + resource_id: Resource ID + resource_data: Resource data will be updated + """ + return await self._resource_action( # type: ignore[attr-defined, no-any-return] + resource_id, "POST", "deactivate", json=resource_data + ) diff --git a/mpt_api_client/resources/catalog/pricing_policies.py b/mpt_api_client/resources/catalog/pricing_policies.py index e541846..833dba0 100644 --- a/mpt_api_client/resources/catalog/pricing_policies.py +++ b/mpt_api_client/resources/catalog/pricing_policies.py @@ -7,6 +7,10 @@ Service, ) from mpt_api_client.models import Model, ResourceData +from mpt_api_client.resources.catalog.pricing_policy_attachments import ( + AsyncPricingPolicyAttachmentsService, + PricingPolicyAttachmentsService, +) class PricingPolicy(Model): @@ -29,6 +33,13 @@ class PricingPoliciesService( # noqa: WPS215 ): """Pricing policies service.""" + def attachments(self, pricing_policy_id: str) -> PricingPolicyAttachmentsService: + """Return pricing policy attachments service.""" + return PricingPolicyAttachmentsService( + http_client=self.http_client, + endpoint_params={"pricing_policy_id": pricing_policy_id}, + ) + def activate(self, resource_id: str, resource_data: ResourceData) -> PricingPolicy: """Activate pricing policy. @@ -62,6 +73,13 @@ class AsyncPricingPoliciesService( ): """Async pricing policies service.""" + def attachments(self, pricing_policy_id: str) -> AsyncPricingPolicyAttachmentsService: + """Return pricing policy attachments service.""" + return AsyncPricingPolicyAttachmentsService( + http_client=self.http_client, + endpoint_params={"pricing_policy_id": pricing_policy_id}, + ) + async def activate(self, resource_id: str, resource_data: ResourceData) -> PricingPolicy: """Activate pricing policy. diff --git a/mpt_api_client/resources/catalog/pricing_policy_attachments.py b/mpt_api_client/resources/catalog/pricing_policy_attachments.py new file mode 100644 index 0000000..eb3a397 --- /dev/null +++ b/mpt_api_client/resources/catalog/pricing_policy_attachments.py @@ -0,0 +1,44 @@ +from mpt_api_client.http import AsyncService, DeleteMixin, Service +from mpt_api_client.http.mixins import ( + AsyncDeleteMixin, + AsyncFileOperationsMixin, + AsyncUpdateMixin, + FileOperationsMixin, + UpdateMixin, +) +from mpt_api_client.models import Model +from mpt_api_client.resources.catalog.mixins import ActivatableMixin, AsyncActivatableMixin + + +class PricingPolicyAttachment(Model): + """Pricing Policy Attachment resource.""" + + +class PricingPolicyAttachmentsServiceConfig: + """Pricing Policy Attachments service configuration.""" + + _endpoint = "/public/v1/catalog/pricing-policies/{pricing_policy_id}/attachments" + _model_class = PricingPolicyAttachment + _collection_key = "data" + + +class PricingPolicyAttachmentsService( + FileOperationsMixin[PricingPolicyAttachment], + DeleteMixin, + UpdateMixin[PricingPolicyAttachment], + ActivatableMixin[PricingPolicyAttachment], + Service[PricingPolicyAttachment], + PricingPolicyAttachmentsServiceConfig, +): + """Pricing Policy Attachments service.""" + + +class AsyncPricingPolicyAttachmentsService( + AsyncFileOperationsMixin[PricingPolicyAttachment], + AsyncDeleteMixin, + AsyncUpdateMixin[PricingPolicyAttachment], + AsyncActivatableMixin[PricingPolicyAttachment], + AsyncService[PricingPolicyAttachment], + PricingPolicyAttachmentsServiceConfig, +): + """Pricing Policy Attachments service.""" diff --git a/tests/resources/catalog/test_pricing_policies.py b/tests/resources/catalog/test_pricing_policies.py index e69779d..c241f75 100644 --- a/tests/resources/catalog/test_pricing_policies.py +++ b/tests/resources/catalog/test_pricing_policies.py @@ -6,6 +6,10 @@ AsyncPricingPoliciesService, PricingPoliciesService, ) +from mpt_api_client.resources.catalog.pricing_policy_attachments import ( + AsyncPricingPolicyAttachmentsService, + PricingPolicyAttachmentsService, +) @pytest.fixture @@ -108,3 +112,31 @@ async def test_async_disable(async_pricing_policies_service): ) assert pricing_policy_disabled.to_dict() == pricing_policy_expected + + +@pytest.mark.parametrize( + ("service_method", "expected_service_class"), + [ + ("attachments", PricingPolicyAttachmentsService), + ], +) +def test_property_services(pricing_policies_service, service_method, expected_service_class): + property_service = getattr(pricing_policies_service, service_method)("PRP-0000-0001") + + assert isinstance(property_service, expected_service_class) + assert property_service.endpoint_params == {"pricing_policy_id": "PRP-0000-0001"} + + +@pytest.mark.parametrize( + ("service_method", "expected_service_class"), + [ + ("attachments", AsyncPricingPolicyAttachmentsService), + ], +) +def test_async_property_services( + async_pricing_policies_service, service_method, expected_service_class +): + property_service = getattr(async_pricing_policies_service, service_method)("PRP-0000-0001") + + assert isinstance(property_service, expected_service_class) + assert property_service.endpoint_params == {"pricing_policy_id": "PRP-0000-0001"} diff --git a/tests/resources/catalog/test_pricing_policy_attachments.py b/tests/resources/catalog/test_pricing_policy_attachments.py new file mode 100644 index 0000000..a1d8855 --- /dev/null +++ b/tests/resources/catalog/test_pricing_policy_attachments.py @@ -0,0 +1,50 @@ +import pytest + +from mpt_api_client.resources.catalog.pricing_policy_attachments import ( + AsyncPricingPolicyAttachmentsService, + PricingPolicyAttachmentsService, +) + + +@pytest.fixture +def pricing_policy_attachments_service(http_client) -> PricingPolicyAttachmentsService: + return PricingPolicyAttachmentsService( + http_client=http_client, endpoint_params={"pricing_policy_id": "PRP-0000-0001"} + ) + + +@pytest.fixture +def async_pricing_policy_attachments_service( + async_http_client, +) -> AsyncPricingPolicyAttachmentsService: + return AsyncPricingPolicyAttachmentsService( + http_client=async_http_client, endpoint_params={"pricing_policy_id": "PRP-0000-0001"} + ) + + +def test_endpoint(pricing_policy_attachments_service) -> None: + assert ( + pricing_policy_attachments_service.endpoint + == "/public/v1/catalog/pricing-policies/PRP-0000-0001/attachments" + ) + + +def test_async_endpoint(async_pricing_policy_attachments_service) -> None: + assert ( + async_pricing_policy_attachments_service.endpoint + == "/public/v1/catalog/pricing-policies/PRP-0000-0001/attachments" + ) + + +@pytest.mark.parametrize( + "method", ["get", "create", "delete", "update", "download", "activate", "deactivate"] +) +def test_methods_present(pricing_policy_attachments_service, method: str) -> None: + assert hasattr(pricing_policy_attachments_service, method) + + +@pytest.mark.parametrize( + "method", ["get", "create", "delete", "update", "download", "activate", "deactivate"] +) +def test_async_methods_present(async_pricing_policy_attachments_service, method: str) -> None: + assert hasattr(async_pricing_policy_attachments_service, method)