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
4 changes: 3 additions & 1 deletion e2e_config.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"accounts.seller.id": "SEL-7310-3075",
"catalog.product.parameter_group.id": "PGR-7255-3950-0001",
"catalog.product.parameter.id": "PAR-7255-3950-0016",
"accounts.account.id": "ACC-9042-0088"
"accounts.account.id": "ACC-9042-0088",
"accounts.buyer.account.id": "ACC-1086-6867",
"accounts.buyer.id": "BUY-1591-2112"
}
133 changes: 129 additions & 4 deletions mpt_api_client/resources/accounts/buyers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
from typing import override

from mpt_api_client.http import AsyncService, Service
from mpt_api_client.http.mixins import (
AsyncCollectionMixin,
AsyncManagedResourceMixin,
AsyncCreateWithIconMixin,
AsyncDeleteMixin,
AsyncGetMixin,
AsyncUpdateWithIconMixin,
CollectionMixin,
ManagedResourceMixin,
CreateWithIconMixin,
DeleteMixin,
GetMixin,
UpdateWithIconMixin,
)
from mpt_api_client.http.types import FileTypes
from mpt_api_client.models import Model
from mpt_api_client.models.model import ResourceData
from mpt_api_client.resources.accounts.mixins import (
Expand All @@ -30,16 +39,74 @@ class BuyersServiceConfig:


class BuyersService(
CreateWithIconMixin[Buyer],
UpdateWithIconMixin[Buyer],
GetMixin[Buyer],
DeleteMixin,
ActivatableMixin[Buyer],
EnablableMixin[Buyer],
ValidateMixin[Buyer],
ManagedResourceMixin[Buyer],
CollectionMixin[Buyer],
Service[Buyer],
BuyersServiceConfig,
):
"""Buyers Service."""

@override
def create(
self,
resource_data: ResourceData,
logo: FileTypes,
data_key: str = "buyer",
icon_key: str = "logo",
) -> Buyer:
"""Create a buyer.

Args:
resource_data (ResourceData): Buyer data.
logo: Logo image in jpg, png, GIF, etc.
data_key: The key for the buyer data.
icon_key: The key for the logo image.

Returns:
Buyer: Created buyer
"""
return super().create(
resource_data=resource_data,
icon=logo,
data_key=data_key,
icon_key=icon_key,
)

@override
def update(
self,
resource_id: str,
resource_data: ResourceData,
logo: FileTypes,
data_key: str = "buyer",
icon_key: str = "logo",
) -> Buyer:
"""Update a buyer.

Args:
resource_id: Resource ID
resource_data (ResourceData): Buyer data.
logo: Logo image in jpg, png, GIF, etc.
data_key: The key for the buyer data.
icon_key: The key for the logo image.

Returns:
Buyer: Updated buyer
"""
return super().update(
resource_id=resource_id,
resource_data=resource_data,
icon=logo,
data_key=data_key,
icon_key=icon_key,
)

def synchronize(self, resource_id: str, resource_data: ResourceData | None = None) -> Buyer:
"""Synchronize a buyer.

Expand All @@ -60,16 +127,74 @@ def transfer(self, resource_id: str, resource_data: ResourceData | None = None)


class AsyncBuyersService(
AsyncCreateWithIconMixin[Buyer],
AsyncUpdateWithIconMixin[Buyer],
AsyncGetMixin[Buyer],
AsyncDeleteMixin,
AsyncActivatableMixin[Buyer],
AsyncEnablableMixin[Buyer],
AsyncValidateMixin[Buyer],
AsyncManagedResourceMixin[Buyer],
AsyncCollectionMixin[Buyer],
AsyncService[Buyer],
BuyersServiceConfig,
):
"""Async Buyers Service."""

@override
async def create(
self,
resource_data: ResourceData,
logo: FileTypes,
data_key: str = "buyer",
icon_key: str = "logo",
) -> Buyer:
"""Create a buyer.

Args:
resource_data (ResourceData): Buyer data.
logo: Logo image in jpg, png, GIF, etc.
data_key: The key for the buyer data.
icon_key: The key for the logo image.

Returns:
Buyer: Created buyer
"""
return await super().create(
resource_data=resource_data,
icon=logo,
data_key=data_key,
icon_key=icon_key,
)

@override
async def update(
self,
resource_id: str,
resource_data: ResourceData,
logo: FileTypes,
data_key: str = "buyer",
icon_key: str = "logo",
) -> Buyer:
"""Update a buyer.

Args:
resource_id: Resource ID
resource_data (ResourceData): Buyer data.
logo: Logo image in jpg, png, GIF, etc.
data_key: The key for the buyer data.
icon_key: The key for the logo image.

Returns:
Buyer: Updated buyer
"""
return await super().update(
resource_id=resource_id,
resource_data=resource_data,
icon=logo,
data_key=data_key,
icon_key=icon_key,
)

async def synchronize(
self, resource_id: str, resource_data: ResourceData | None = None
) -> Buyer:
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ per-file-ignores =
mpt_api_client/http/mixins.py: WPS202 WPS204 WPS235
mpt_api_client/resources/*: WPS215
mpt_api_client/models/model.py: WPS215 WPS110
mpt_api_client/resources/accounts/*.py: WPS202 WPS215 WPS214
mpt_api_client/resources/accounts/*.py: WPS202 WPS215 WPS214 WPS235
mpt_api_client/resources/billing/*.py: WPS202 WPS204 WPS214 WPS215
mpt_api_client/resources/catalog/*.py: WPS110 WPS214 WPS215 WPS235
mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215 WPS235
Expand All @@ -45,8 +45,8 @@ per-file-ignores =
tests/unit/http/test_service.py: WPS204 WPS202
tests/unit/http/test_mixins.py: WPS204 WPS202 WPS210
tests/unit/resources/catalog/test_products.py: WPS202 WPS210
tests/unit/resources/accounts/*.py: WPS204 WPS202 WPS210
tests/unit/resources/*/test_mixins.py: WPS118 WPS202 WPS204 WPS235
tests/unit/resources/accounts/test_users.py: WPS204 WPS202 WPS210
tests/unit/test_mpt_client.py: WPS235
tests/e2e/accounts/*.py: WPS430 WPS202
tests/e2e/catalog/*.py: WPS421
Expand Down
115 changes: 115 additions & 0 deletions tests/e2e/accounts/buyers/test_async_buyers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import pytest

from mpt_api_client.exceptions import MPTAPIError
from mpt_api_client.rql.query_builder import RQLQuery

pytestmark = [pytest.mark.flaky]


@pytest.fixture
async def async_created_buyer(async_mpt_ops, buyer, buyer_account_id, account_icon):
new_buyer_request_data = buyer(
name="E2E Created Buyer",
account_id=buyer_account_id,
)

new_buyer = await async_mpt_ops.accounts.buyers.create(
new_buyer_request_data, logo=account_icon
)

yield new_buyer

try:
await async_mpt_ops.accounts.buyers.delete(new_buyer.id)
except MPTAPIError as error:
print(f"TEARDOWN - Unable to delete buyer: {error.title}") # noqa: WPS421


async def test_get_buyer_by_id(async_mpt_ops, buyer_id):
buyer = await async_mpt_ops.accounts.buyers.get(buyer_id)
assert buyer is not None


async def test_list_buyers(async_mpt_ops):
limit = 10
buyers = await async_mpt_ops.accounts.buyers.fetch_page(limit=limit)
assert len(buyers) > 0


async def test_get_buyer_by_id_not_found(async_mpt_ops, invalid_buyer_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.buyers.get(invalid_buyer_id)


async def test_filter_buyers(async_mpt_ops, buyer_id):
select_fields = ["-address"]

async_filtered_buyers = (
async_mpt_ops.accounts.buyers.filter(RQLQuery(id=buyer_id))
.filter(RQLQuery(name="E2E Seeded Buyer"))
.select(*select_fields)
)

buyers = [filtered_buyer async for filtered_buyer in async_filtered_buyers.iterate()]

assert len(buyers) == 1


def test_create_buyer(async_created_buyer):
assert async_created_buyer is not None


async def test_delete_buyer(async_mpt_ops, async_created_buyer):
await async_mpt_ops.accounts.buyers.delete(async_created_buyer.id)


async def test_delete_buyer_not_found(async_mpt_ops, invalid_buyer_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.buyers.delete(invalid_buyer_id)


async def test_update_buyer(
async_mpt_ops, buyer, buyer_account_id, account_icon, async_created_buyer
):
updated_buyer_data = buyer(name="E2E Updated Buyer", account_id=buyer_account_id)

updated_buyer = await async_mpt_ops.accounts.buyers.update(
async_created_buyer.id, updated_buyer_data, logo=account_icon
)

assert updated_buyer is not None


async def test_update_buyer_not_found(
async_mpt_ops, buyer, buyer_account_id, account_icon, invalid_buyer_id
):
updated_buyer_data = buyer(name="Nonexistent Buyer", account_id=buyer_account_id)

with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.buyers.update(
invalid_buyer_id, updated_buyer_data, logo=account_icon
)


async def test_buyer_disable(async_mpt_ops, async_created_buyer):
disabled_buyer = await async_mpt_ops.accounts.buyers.disable(async_created_buyer.id)

assert disabled_buyer is not None


async def test_buyer_disable_not_found(async_mpt_ops, invalid_buyer_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.buyers.disable(invalid_buyer_id)


async def test_buyer_enable(async_mpt_ops, async_created_buyer):
await async_mpt_ops.accounts.buyers.disable(async_created_buyer.id)

enabled_buyer = await async_mpt_ops.accounts.buyers.enable(async_created_buyer.id)

assert enabled_buyer is not None


async def test_buyer_enable_not_found(async_mpt_ops, invalid_buyer_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.buyers.enable(invalid_buyer_id)
Loading