Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions mpt_api_client/resources/commerce/commerce.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
from mpt_api_client.resources.commerce.agreements import AgreementsService, AsyncAgreementsService
from mpt_api_client.resources.commerce.orders import AsyncOrdersService, OrdersService
from mpt_api_client.resources.commerce.subscriptions import (
AsyncSubscriptionsService,
SubscriptionsService,
)


class Commerce:
Expand All @@ -19,6 +23,11 @@ def orders(self) -> OrdersService:
"""Order service."""
return OrdersService(http_client=self.http_client)

@property
def subscriptions(self) -> SubscriptionsService:
"""Subscription service."""
return SubscriptionsService(http_client=self.http_client)


class AsyncCommerce:
"""Commerce MPT API Module."""
Expand All @@ -35,3 +44,8 @@ def agreements(self) -> AsyncAgreementsService:
def orders(self) -> AsyncOrdersService:
"""Order service."""
return AsyncOrdersService(http_client=self.http_client)

@property
def subscriptions(self) -> AsyncSubscriptionsService:
"""Subscription service."""
return AsyncSubscriptionsService(http_client=self.http_client)
87 changes: 87 additions & 0 deletions mpt_api_client/resources/commerce/subscriptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from mpt_api_client.http import (
AsyncCreateMixin,
AsyncDeleteMixin,
AsyncService,
CreateMixin,
DeleteMixin,
Service,
)
from mpt_api_client.models import Model, ResourceData


class Subscription(Model):
"""Subscription resource."""


class SubscriptionsServiceConfig:
"""Subscription service config."""

_endpoint = "/public/v1/commerce/subscriptions"
_model_class = Subscription
_collection_key = "data"


class SubscriptionsService( # noqa: WPS215
CreateMixin[Subscription],
DeleteMixin,
Service[Subscription],
SubscriptionsServiceConfig,
):
"""Subscription service."""

def render(self, resource_id: str) -> str:
"""Render subscription template.

Args:
resource_id: Subscription resource ID

Returns:
Order template text in markdown format.
"""
response = self._resource_do_request(resource_id, "GET", "render")
return response.text

def terminate(self, resource_id: str, resource_data: ResourceData) -> Subscription:
"""Terminate subscription.

Args:
resource_id: Order resource ID
resource_data: Order resource data

Returns:
Subscription template text in markdown format.
"""
return self._resource_action(resource_id, "POST", "terminate", json=resource_data)


class AsyncSubscriptionsService( # noqa: WPS215
AsyncCreateMixin[Subscription],
AsyncDeleteMixin,
AsyncService[Subscription],
SubscriptionsServiceConfig,
):
"""Async Subscription service."""

async def render(self, resource_id: str) -> str:
"""Render subscription template.

Args:
resource_id: Subscription resource ID

Returns:
Order template text in markdown format.
"""
response = await self._resource_do_request(resource_id, "GET", "render")
return response.text

async def terminate(self, resource_id: str, resource_data: ResourceData) -> Subscription:
"""Terminate subscription.

Args:
resource_id: Order resource ID
resource_data: Order resource data

Returns:
Subscription template text in markdown format.
"""
return await self._resource_action(resource_id, "POST", "terminate", json=resource_data)
69 changes: 30 additions & 39 deletions tests/resources/commerce/test_commerce.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import pytest

from mpt_api_client.http import AsyncHTTPClient
from mpt_api_client.resources.commerce import AsyncCommerce, Commerce
from mpt_api_client.resources.commerce.agreements import AgreementsService, AsyncAgreementsService
from mpt_api_client.resources.commerce.orders import AsyncOrdersService, OrdersService
from mpt_api_client.resources.commerce.subscriptions import (
AsyncSubscriptionsService,
SubscriptionsService,
)


def test_commerce_init(http_client):
Expand All @@ -11,15 +17,6 @@ def test_commerce_init(http_client):
assert commerce.http_client is http_client


def test_commerce_orders_property(http_client):
commerce = Commerce(http_client=http_client)

orders_service = commerce.orders

assert isinstance(orders_service, OrdersService)
assert orders_service.http_client is http_client


def test_commerce_orders_multiple_calls(http_client):
commerce = Commerce(http_client=http_client)

Expand All @@ -38,39 +35,33 @@ def test_async_commerce_init(async_http_client: AsyncHTTPClient):
assert commerce.http_client is async_http_client


def test_async_commerce_orders_property(async_http_client: AsyncHTTPClient):
commerce = AsyncCommerce(http_client=async_http_client)

orders_service = commerce.orders

assert isinstance(orders_service, AsyncOrdersService)
assert orders_service.http_client is async_http_client


def test_async_commerce_orders_multiple_calls(async_http_client: AsyncHTTPClient):
commerce = AsyncCommerce(http_client=async_http_client)

orders_service = commerce.orders
orders_service_additional = commerce.orders

assert orders_service is not orders_service_additional
assert isinstance(orders_service, AsyncOrdersService)
assert isinstance(orders_service_additional, AsyncOrdersService)


def test_async_agreements(async_http_client):
commerce = AsyncCommerce(http_client=async_http_client)
@pytest.mark.parametrize(
("attr_name", "expected"),
[
("agreements", AgreementsService),
("orders", OrdersService),
("subscriptions", SubscriptionsService),
],
)
def test_commerce_properties(http_client, attr_name, expected):
commerce = Commerce(http_client=http_client)

agreements = commerce.agreements
service = getattr(commerce, attr_name)

assert isinstance(agreements, AsyncAgreementsService)
assert agreements.http_client is async_http_client
assert isinstance(service, expected)


def test_agreements(http_client):
commerce = Commerce(http_client=http_client)
@pytest.mark.parametrize(
("attr_name", "expected"),
[
("agreements", AsyncAgreementsService),
("orders", AsyncOrdersService),
("subscriptions", AsyncSubscriptionsService),
],
)
def test_async_commerce_properties(http_client, attr_name, expected):
commerce = AsyncCommerce(http_client=http_client)

agreements = commerce.agreements
service = getattr(commerce, attr_name)

assert isinstance(agreements, AgreementsService)
assert agreements.http_client is http_client
assert isinstance(service, expected)
88 changes: 88 additions & 0 deletions tests/resources/commerce/test_subscriptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import httpx
import pytest
import respx

from mpt_api_client.resources.commerce.subscriptions import (
AsyncSubscriptionsService,
SubscriptionsService,
)


@pytest.fixture
def subscriptions_service(http_client):
return SubscriptionsService(http_client=http_client)


@pytest.fixture
def async_subscriptions_service(async_http_client):
return AsyncSubscriptionsService(http_client=async_http_client)


async def test_async_terminate(async_subscriptions_service):
subscription_expected = {"id": "SUB-123", "status": "Terminated", "name": "Terminated SUB-123"}
with respx.mock:
respx.post(
"https://api.example.com/public/v1/commerce/subscriptions/SUB-123/terminate"
).mock(
return_value=httpx.Response(
status_code=httpx.codes.OK,
json=subscription_expected,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the comma to avoid splitting the line unnecessarily

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruff seems to add it if the line does not fit inside a single line in this case

)
)

subscription_updated = await async_subscriptions_service.terminate(
"SUB-123", {"name": "Terminated SUB-123"}
)

assert subscription_updated.to_dict() == subscription_expected


async def test_async_render(async_subscriptions_service):
template_content = "# Subscription Template\n\nThis is a markdown template."
with respx.mock:
respx.get("https://api.example.com/public/v1/commerce/subscriptions/SUB-123/render").mock(
return_value=httpx.Response(
status_code=httpx.codes.OK,
headers={"content-type": "text/markdown"},
content=template_content,
)
)

template = await async_subscriptions_service.render("SUB-123")

assert template == template_content


def test_terminate(subscriptions_service):
subscription_expected = {"id": "SUB-123", "status": "Terminated", "name": "Terminated SUB-123"}
with respx.mock:
respx.post(
"https://api.example.com/public/v1/commerce/subscriptions/SUB-123/terminate"
).mock(
return_value=httpx.Response(
status_code=httpx.codes.OK,
json=subscription_expected,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about the comma here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruff seems to add it if the line does not fit inside a single line in this case

)
)

subscription_updated = subscriptions_service.terminate(
"SUB-123", {"name": "Terminated SUB-123"}
)

assert subscription_updated.to_dict() == subscription_expected


def test_render(subscriptions_service):
template_content = "# Subscription Template\n\nThis is a markdown template."
with respx.mock:
respx.get("https://api.example.com/public/v1/commerce/subscriptions/SUB-123/render").mock(
return_value=httpx.Response(
status_code=httpx.codes.OK,
headers={"content-type": "text/markdown"},
content=template_content,
)
)

template = subscriptions_service.render("SUB-123")

assert template == template_content