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
3 changes: 1 addition & 2 deletions mpt_api_client/resources/commerce/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from mpt_api_client.resources.commerce.commerce import AsyncCommerce, Commerce
from mpt_api_client.resources.commerce.orders import AsyncOrdersService, OrdersService

__all__ = ["AsyncCommerce", "AsyncOrdersService", "Commerce", "OrdersService"] # noqa: WPS410
__all__ = ["AsyncCommerce", "Commerce"] # noqa: WPS410
46 changes: 46 additions & 0 deletions mpt_api_client/resources/commerce/agreements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from mpt_api_client.http import AsyncService, Service
from mpt_api_client.models import Model


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


class AgreementsServiceConfig:
"""Orders service config."""

_endpoint = "/public/v1/commerce/agreements"
_model_class = Agreement
_collection_key = "data"


class AgreementsService(Service[Agreement], AgreementsServiceConfig):
"""Agreements service."""

def template(self, agreement_id: str) -> str:
"""Renders the template for the given Agreement id.

Args:
agreement_id: Agreement ID.

Returns:
Agreement template.
"""
response = self._resource_do_request(agreement_id, action="template")
return response.text


class AsyncAgreementsService(AsyncService[Agreement], AgreementsServiceConfig):
"""Agreements service."""

async def template(self, agreement_id: str) -> str:
"""Renders the template for the given Agreement id.

Args:
agreement_id: Agreement ID.

Returns:
Agreement template.
"""
response = await self._resource_do_request(agreement_id, action="template")
return response.text
11 changes: 11 additions & 0 deletions mpt_api_client/resources/commerce/commerce.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
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


Expand All @@ -8,6 +9,11 @@ class Commerce:
def __init__(self, http_client: HTTPClient):
self.http_client = http_client

@property
def agreements(self) -> AgreementsService:
"""Agreement service."""
return AgreementsService(http_client=self.http_client)

@property
def orders(self) -> OrdersService:
"""Order service."""
Expand All @@ -20,6 +26,11 @@ class AsyncCommerce:
def __init__(self, http_client: AsyncHTTPClient):
self.http_client = http_client

@property
def agreements(self) -> AsyncAgreementsService:
"""Agreement service."""
return AsyncAgreementsService(http_client=self.http_client)

@property
def orders(self) -> AsyncOrdersService:
"""Order service."""
Expand Down
33 changes: 0 additions & 33 deletions tests/http/test_async_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,6 @@
from tests.http.conftest import AsyncDummyService


async def test_async_create_mixin(async_dummy_service): # noqa: WPS210
resource_data = {"name": "Test Resource", "status": "active"}
new_resource_data = {"id": "new-resource-id", "name": "Test Resource", "status": "active"}
create_response = httpx.Response(httpx.codes.OK, json=new_resource_data)

with respx.mock:
mock_route = respx.post("https://api.example.com/api/v1/test").mock(
return_value=create_response
)

created_resource = await async_dummy_service.create(resource_data)

assert created_resource.to_dict() == new_resource_data
assert mock_route.call_count == 1
request = mock_route.calls[0].request
assert request.method == "POST"
assert request.url == "https://api.example.com/api/v1/test"
assert json.loads(request.content.decode()) == resource_data


async def test_async_delete_mixin(async_dummy_service): # noqa: WPS210
delete_response = httpx.Response(httpx.codes.NO_CONTENT, json=None)

with respx.mock:
mock_route = respx.delete("https://api.example.com/api/v1/test/RES-123").mock(
return_value=delete_response
)

await async_dummy_service.delete("RES-123")

assert mock_route.call_count == 1


async def test_async_fetch_one_success(async_dummy_service, single_result_response):
with respx.mock:
mock_route = respx.get("https://api.example.com/api/v1/test").mock(
Expand Down
69 changes: 69 additions & 0 deletions tests/http/test_mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import json

import httpx
import respx


async def test_async_create_mixin(async_dummy_service): # noqa: WPS210
resource_data = {"name": "Test Resource", "status": "active"}
new_resource_data = {"id": "new-resource-id", "name": "Test Resource", "status": "active"}
create_response = httpx.Response(httpx.codes.OK, json=new_resource_data)

with respx.mock:
mock_route = respx.post("https://api.example.com/api/v1/test").mock(
return_value=create_response
)

created_resource = await async_dummy_service.create(resource_data)

assert created_resource.to_dict() == new_resource_data
assert mock_route.call_count == 1
request = mock_route.calls[0].request
assert request.method == "POST"
assert request.url == "https://api.example.com/api/v1/test"
assert json.loads(request.content.decode()) == resource_data


async def test_async_delete_mixin(async_dummy_service): # noqa: WPS210
delete_response = httpx.Response(httpx.codes.NO_CONTENT, json=None)

with respx.mock:
mock_route = respx.delete("https://api.example.com/api/v1/test/RES-123").mock(
return_value=delete_response
)

await async_dummy_service.delete("RES-123")

assert mock_route.call_count == 1


def test_sync_create_mixin(dummy_service): # noqa: WPS210
resource_data = {"name": "Test Resource", "status": "active"}
new_resource_data = {"id": "new-resource-id", "name": "Test Resource", "status": "active"}
create_response = httpx.Response(httpx.codes.OK, json=new_resource_data)

with respx.mock:
mock_route = respx.post("https://api.example.com/api/v1/test").mock(
return_value=create_response
)

created_resource = dummy_service.create(resource_data)

assert created_resource.to_dict() == new_resource_data
assert mock_route.call_count == 1
request = mock_route.calls[0].request
assert request.method == "POST"
assert request.url == "https://api.example.com/api/v1/test"
assert json.loads(request.content.decode()) == resource_data


def test_sync_delete_mixin(dummy_service):
delete_response = httpx.Response(httpx.codes.NO_CONTENT, json=None)
with respx.mock:
mock_route = respx.delete("https://api.example.com/api/v1/test/RES-123").mock(
return_value=delete_response
)

dummy_service.delete("RES-123")

assert mock_route.call_count == 1
32 changes: 0 additions & 32 deletions tests/http/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,6 @@
from tests.http.conftest import DummyService


def test_sync_create_mixin(dummy_service): # noqa: WPS210
resource_data = {"name": "Test Resource", "status": "active"}
new_resource_data = {"id": "new-resource-id", "name": "Test Resource", "status": "active"}
create_response = httpx.Response(httpx.codes.OK, json=new_resource_data)

with respx.mock:
mock_route = respx.post("https://api.example.com/api/v1/test").mock(
return_value=create_response
)

created_resource = dummy_service.create(resource_data)

assert created_resource.to_dict() == new_resource_data
assert mock_route.call_count == 1
request = mock_route.calls[0].request
assert request.method == "POST"
assert request.url == "https://api.example.com/api/v1/test"
assert json.loads(request.content.decode()) == resource_data


def test_sync_delete_mixin(dummy_service):
delete_response = httpx.Response(httpx.codes.NO_CONTENT, json=None)
with respx.mock:
mock_route = respx.delete("https://api.example.com/api/v1/test/RES-123").mock(
return_value=delete_response
)

dummy_service.delete("RES-123")

assert mock_route.call_count == 1


def test_sync_fetch_one_success(dummy_service, single_result_response):
with respx.mock:
mock_route = respx.get("https://api.example.com/api/v1/test").mock(
Expand Down
41 changes: 41 additions & 0 deletions tests/resources/commerce/test_agreements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import httpx
import respx

from mpt_api_client.resources.commerce.agreements import AgreementsService, AsyncAgreementsService


async def test_async_template(async_http_client):
async_agreements_service = AsyncAgreementsService(http_client=async_http_client)
template_content = "# Order Template\n\nThis is a markdown template."
with respx.mock:
respx.get("https://api.example.com/public/v1/commerce/agreements/AGR-123/template").mock(
return_value=httpx.Response(
status_code=200,
headers={"content-type": "text/markdown"},
content=template_content,
)
)

template = await async_agreements_service.template("AGR-123")

assert template == template_content


def test_template(http_client):
agreements_service = AgreementsService(http_client=http_client)
with respx.mock:
mock_route = respx.get(
"https://api.example.com/public/v1/commerce/agreements/AGR-123/template"
).mock(
return_value=httpx.Response(
status_code=200,
headers={"content-type": "text/markdown"},
content="# Order Template\n\nThis is a markdown template.",
)
)

markdown_template = agreements_service.template("AGR-123")

assert mock_route.called
assert mock_route.call_count == 1
assert markdown_template == "# Order Template\n\nThis is a markdown template."
19 changes: 19 additions & 0 deletions tests/resources/commerce/test_commerce.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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


Expand Down Expand Up @@ -55,3 +56,21 @@ def test_async_commerce_orders_multiple_calls(async_http_client: AsyncHTTPClient
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)

agreements = commerce.agreements

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


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

agreements = commerce.agreements

assert isinstance(agreements, AgreementsService)
assert agreements.http_client is http_client