diff --git a/mpt_api_client/mpt_client.py b/mpt_api_client/mpt_client.py index 7e7af76..802da1a 100644 --- a/mpt_api_client/mpt_client.py +++ b/mpt_api_client/mpt_client.py @@ -2,6 +2,8 @@ from mpt_api_client.http import AsyncHTTPClient, HTTPClient from mpt_api_client.resources import ( + Accounts, + AsyncAccounts, AsyncAudit, AsyncBilling, AsyncCatalog, @@ -56,6 +58,11 @@ def billing(self) -> AsyncBilling: """Billing MPT API Client.""" return AsyncBilling(http_client=self.http_client) + @property + def accounts(self) -> AsyncAccounts: + """Accounts MPT API Client.""" + return AsyncAccounts(http_client=self.http_client) + class MPTClient: """MPT API Client.""" @@ -104,3 +111,8 @@ def audit(self) -> Audit: def billing(self) -> Billing: """Billing MPT API Client.""" return Billing(http_client=self.http_client) + + @property + def accounts(self) -> Accounts: + """Accounts MPT API Client.""" + return Accounts(http_client=self.http_client) diff --git a/mpt_api_client/resources/__init__.py b/mpt_api_client/resources/__init__.py index 6d0b930..74dd4ff 100644 --- a/mpt_api_client/resources/__init__.py +++ b/mpt_api_client/resources/__init__.py @@ -1,9 +1,12 @@ +from mpt_api_client.resources.accounts import Accounts, AsyncAccounts from mpt_api_client.resources.audit import AsyncAudit, Audit from mpt_api_client.resources.billing import AsyncBilling, Billing from mpt_api_client.resources.catalog import AsyncCatalog, Catalog from mpt_api_client.resources.commerce import AsyncCommerce, Commerce __all__ = [ # noqa: WPS410 + "Accounts", + "AsyncAccounts", "AsyncAudit", "AsyncBilling", "AsyncCatalog", diff --git a/mpt_api_client/resources/accounts/__init__.py b/mpt_api_client/resources/accounts/__init__.py new file mode 100644 index 0000000..0529713 --- /dev/null +++ b/mpt_api_client/resources/accounts/__init__.py @@ -0,0 +1,3 @@ +from mpt_api_client.resources.accounts.accounts import Accounts, AsyncAccounts + +__all__ = ["Accounts", "AsyncAccounts"] # noqa: WPS410 diff --git a/mpt_api_client/resources/accounts/account.py b/mpt_api_client/resources/accounts/account.py new file mode 100644 index 0000000..af3f195 --- /dev/null +++ b/mpt_api_client/resources/accounts/account.py @@ -0,0 +1,38 @@ +from mpt_api_client.http import AsyncService, Service +from mpt_api_client.http.mixins import ( + AsyncCreateMixin, + AsyncUpdateMixin, + CreateMixin, + UpdateMixin, +) +from mpt_api_client.models import Model + + +class Account(Model): + """Account resource.""" + + +class AccountsServiceConfig: + """Accounts service configuration.""" + + _endpoint = "/public/v1/accounts" + _model_class = Account + _collection_key = "data" + + +class AccountsService( + CreateMixin[Account], + UpdateMixin[Account], + Service[Account], + AccountsServiceConfig, +): + """Accounts service.""" + + +class AsyncAccountsService( + AsyncCreateMixin[Account], + AsyncUpdateMixin[Account], + AsyncService[Account], + AccountsServiceConfig, +): + """Async Accounts service.""" diff --git a/mpt_api_client/resources/accounts/accounts.py b/mpt_api_client/resources/accounts/accounts.py new file mode 100644 index 0000000..faf1440 --- /dev/null +++ b/mpt_api_client/resources/accounts/accounts.py @@ -0,0 +1,26 @@ +from mpt_api_client.http import AsyncHTTPClient, HTTPClient +from mpt_api_client.resources.accounts.account import AccountsService, AsyncAccountsService + + +class Accounts: + """Accounts MPT API Module.""" + + def __init__(self, *, http_client: HTTPClient): + self.http_client = http_client + + @property + def accounts(self) -> AccountsService: + """Accounts service.""" + return AccountsService(http_client=self.http_client) + + +class AsyncAccounts: + """Async Accounts MPT API Module.""" + + def __init__(self, *, http_client: AsyncHTTPClient): + self.http_client = http_client + + @property + def accounts(self) -> AsyncAccountsService: + """Accounts service.""" + return AsyncAccountsService(http_client=self.http_client) diff --git a/setup.cfg b/setup.cfg index d273742..ad8d96b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,6 +32,7 @@ extend-ignore = per-file-ignores = + mpt_api_client/resources/accounts/*.py: WPS215 mpt_api_client/resources/audit/*.py: WPS215 mpt_api_client/resources/billing/*.py: WPS215 WPS202 WPS214 WPS204 mpt_api_client/resources/catalog/*.py: WPS110 WPS215 WPS214 @@ -39,11 +40,13 @@ per-file-ignores = mpt_api_client/rql/query_builder.py: WPS110 WPS115 WPS210 WPS214 mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215 mpt_api_client/http/mixins.py: WPS202 + mpt_api_client/mpt_client.py: WPS235 tests/http/test_async_service.py: WPS204 WPS202 tests/http/test_service.py: WPS204 WPS202 tests/http/test_mixins.py: WPS204 WPS202 tests/resources/catalog/test_products.py: WPS202 WPS210 tests/resources/*/test_mixins.py: WPS118 WPS202 WPS204 + tests/test_mpt.py: WPS210 WPS218 WPS235 tests/*: # Allow magic strings. diff --git a/tests/resources/accounts/test_account.py b/tests/resources/accounts/test_account.py new file mode 100644 index 0000000..678c4a3 --- /dev/null +++ b/tests/resources/accounts/test_account.py @@ -0,0 +1,23 @@ +import pytest + +from mpt_api_client.resources.accounts.account import AccountsService, AsyncAccountsService + + +@pytest.fixture +def account_service(http_client): + return AccountsService(http_client=http_client) + + +@pytest.fixture +def async_account_service(async_http_client): + return AsyncAccountsService(http_client=async_http_client) + + +@pytest.mark.parametrize("method", ["get", "create", "update"]) +def test_mixins_present(account_service, method): + assert hasattr(account_service, method) + + +@pytest.mark.parametrize("method", ["get", "create", "update"]) +def test_async_mixins_present(async_account_service, method): + assert hasattr(async_account_service, method) diff --git a/tests/resources/accounts/test_accounts.py b/tests/resources/accounts/test_accounts.py new file mode 100644 index 0000000..00121d5 --- /dev/null +++ b/tests/resources/accounts/test_accounts.py @@ -0,0 +1,50 @@ +import pytest + +from mpt_api_client.resources.accounts.account import AccountsService, AsyncAccountsService +from mpt_api_client.resources.accounts.accounts import Accounts, AsyncAccounts + + +@pytest.fixture +def accounts(http_client): + return Accounts(http_client=http_client) + + +@pytest.fixture +def async_accounts(async_http_client): + return AsyncAccounts(http_client=async_http_client) + + +@pytest.mark.parametrize( + ("property_name", "expected_service_class"), [("accounts", AccountsService)] +) +def test_accounts_properties(accounts, property_name, expected_service_class): + """Test that Accounts properties return correct instances.""" + service = getattr(accounts, property_name) + + assert isinstance(service, expected_service_class) + assert service.http_client is accounts.http_client + + +@pytest.mark.parametrize( + ("property_name", "expected_service_class"), [("accounts", AsyncAccountsService)] +) +def test_async_accounts_properties(async_accounts, property_name, expected_service_class): + """Test that AsyncAccounts properties return correct instances.""" + service = getattr(async_accounts, property_name) + + assert isinstance(service, expected_service_class) + assert service.http_client is async_accounts.http_client + + +def test_accounts_initialization(http_client): + accounts = Accounts(http_client=http_client) + + assert accounts.http_client is http_client + assert isinstance(accounts, Accounts) + + +def test_async_accounts_initialization(async_http_client): + accounts = AsyncAccounts(http_client=async_http_client) + + assert accounts.http_client is async_http_client + assert isinstance(accounts, AsyncAccounts) diff --git a/tests/test_mpt.py b/tests/test_mpt.py index bf39c59..7f680df 100644 --- a/tests/test_mpt.py +++ b/tests/test_mpt.py @@ -3,6 +3,8 @@ from mpt_api_client.http import AsyncHTTPClient, HTTPClient from mpt_api_client.mpt_client import AsyncMPTClient, MPTClient from mpt_api_client.resources import ( + Accounts, + AsyncAccounts, AsyncAudit, AsyncBilling, AsyncCatalog, @@ -15,18 +17,27 @@ from tests.conftest import API_TOKEN, API_URL -def test_mpt_client() -> None: - mpt = MPTClient.from_config(base_url=API_URL, api_token=API_TOKEN) - commerce = mpt.commerce - catalog = mpt.catalog - audit = mpt.audit - billing = mpt.billing +def get_mpt_client(): + return MPTClient.from_config(base_url=API_URL, api_token=API_TOKEN) - assert isinstance(mpt, MPTClient) - assert isinstance(commerce, Commerce) - assert isinstance(catalog, Catalog) - assert isinstance(audit, Audit) - assert isinstance(billing, Billing) + +def get_async_mpt_client(): + return AsyncMPTClient.from_config(base_url=API_URL, api_token=API_TOKEN) + + +@pytest.mark.parametrize( + ("domain_module", "domain_type"), + [ + (get_mpt_client(), MPTClient), + (get_mpt_client().commerce, Commerce), + (get_mpt_client().catalog, Catalog), + (get_mpt_client().audit, Audit), + (get_mpt_client().billing, Billing), + (get_mpt_client().accounts, Accounts), + ], +) +def test_mpt_client(domain_module, domain_type) -> None: + assert isinstance(domain_module, domain_type) def test_mpt_client_env(monkeypatch: pytest.MonkeyPatch) -> None: @@ -39,18 +50,19 @@ def test_mpt_client_env(monkeypatch: pytest.MonkeyPatch) -> None: assert isinstance(mpt.http_client, HTTPClient) -def test_async_mpt_client() -> None: - mpt = AsyncMPTClient.from_config(base_url=API_URL, api_token=API_TOKEN) - commerce = mpt.commerce - catalog = mpt.catalog - audit = mpt.audit - billing = mpt.billing - - assert isinstance(mpt, AsyncMPTClient) - assert isinstance(commerce, AsyncCommerce) - assert isinstance(catalog, AsyncCatalog) - assert isinstance(audit, AsyncAudit) - assert isinstance(billing, AsyncBilling) +@pytest.mark.parametrize( + ("domain_module", "domain_type"), + [ + (get_async_mpt_client(), AsyncMPTClient), + (get_async_mpt_client().commerce, AsyncCommerce), + (get_async_mpt_client().catalog, AsyncCatalog), + (get_async_mpt_client().audit, AsyncAudit), + (get_async_mpt_client().billing, AsyncBilling), + (get_async_mpt_client().accounts, AsyncAccounts), + ], +) +def test_async_mpt_client(domain_module, domain_type) -> None: + assert isinstance(domain_module, domain_type) def test_async_mpt_client_env(monkeypatch: pytest.MonkeyPatch) -> None: