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
17 changes: 10 additions & 7 deletions e2e_config.test.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
{
"accounts.seller.id": "SEL-7310-3075",
"accounts.account.id": "ACC-9042-0088",
"accounts.api_token.id": "TKN-8857-1729",
"accounts.buyer.account.id": "ACC-1086-6867",
"accounts.buyer.id": "BUY-1591-2112",
"accounts.user_group.id": "UGR-6822-0561",
"accounts.licensee.account.id": "ACC-1086-6867",
"accounts.licensee.group.id": "UGR-2757-7226",
"accounts.licensee.id": "LCE-5758-4071-6507",
"accounts.module.id": "MOD-1756",
"accounts.module.name": "Access Management",
"accounts.seller.id": "SEL-7310-3075",
"accounts.user_group.id": "UGR-6822-0561",
"catalog.item.id": "ITM-7255-3950-0001",
"catalog.product.document.id": "PDC-7255-3950-0001",
"catalog.product.id": "PRD-7255-3950",
"catalog.product.parameter_group.id": "PGR-7255-3950-0001",
"catalog.product.item_group.id": "IGR-7255-3950-0001",
"catalog.product.parameter.id": "PAR-7255-3950-0016",
"catalog.product.document.id": "PDC-7255-3950-0001",
"catalog.item.id": "ITM-7255-3950-0001",
"catalog.unit.id": "UNT-1229",
"accounts.api_token.id": "TKN-8857-1729"
"catalog.product.parameter_group.id": "PGR-7255-3950-0001",
"catalog.unit.id": "UNT-1229"
}
134 changes: 130 additions & 4 deletions mpt_api_client/resources/accounts/licensees.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
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 AsyncEnablableMixin, EnablableMixin


Expand All @@ -22,20 +32,136 @@ class LicenseesServiceConfig:


class LicenseesService(
CreateWithIconMixin[Licensee],
UpdateWithIconMixin[Licensee],
GetMixin[Licensee],
DeleteMixin,
EnablableMixin[Licensee],
ManagedResourceMixin[Licensee],
CollectionMixin[Licensee],
Service[Licensee],
LicenseesServiceConfig,
):
"""Licensees Service."""

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

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

Returns:
Licensee: Created licensee
"""
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 = "licensee",
icon_key: str = "logo",
) -> Licensee:
"""Update a licensee.

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

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


class AsyncLicenseesService(
AsyncCreateWithIconMixin[Licensee],
AsyncUpdateWithIconMixin[Licensee],
AsyncGetMixin[Licensee],
AsyncDeleteMixin,
AsyncEnablableMixin[Licensee],
AsyncManagedResourceMixin[Licensee],
AsyncCollectionMixin[Licensee],
AsyncService[Licensee],
LicenseesServiceConfig,
):
"""Async Licensees Service."""

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

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

Returns:
Licensee: Created licensee
"""
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 = "licensee",
icon_key: str = "logo",
) -> Licensee:
"""Update a licensee.

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

Returns:
Licensee: Updated licensee
"""
return await super().update(
resource_id=resource_id,
resource_data=resource_data,
icon=logo,
data_key=data_key,
icon_key=icon_key,
)
34 changes: 33 additions & 1 deletion tests/e2e/accounts/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ def _buyer(
def user_group_factory(account_id, module_id):
def _user_group(
name: str = "E2E Test Api Client User Group",
user_group_account_id: str = account_id,
):
return {
"name": name,
"account": {"id": account_id},
"account": {"id": user_group_account_id},
"buyers": None,
"logo": "",
"description": "User group for E2E tests",
Expand All @@ -122,3 +123,34 @@ def _api_token(
}

return _api_token


@pytest.fixture
def licensee_factory(seller_id, buyer_id, user_group_factory, licensee_account_id):
def _licensee(
name: str = "Test E2E Licensee",
licensee_type: str = "Client",
):
group = user_group_factory(user_group_account_id=licensee_account_id)

return {
"name": name,
"address": {
"addressLine1": "456 Licensee St",
"city": "Los Angeles",
"state": "CA",
"postCode": "67890",
"country": "US",
},
"useBuyerAddress": False,
"seller": {"id": seller_id},
"buyer": {"id": buyer_id},
"account": {"id": licensee_account_id},
"eligibility": {"client": True, "partner": False},
"groups": [group],
"type": licensee_type,
"status": "Enabled",
"defaultLanguage": "en-US",
}

return _licensee
114 changes: 114 additions & 0 deletions tests/e2e/accounts/licensees/test_async_licensees.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
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_licensee(async_mpt_client, licensee_factory, account_icon):
new_licensee_request_data = licensee_factory(name="E2E Created licensee")

new_licensee = await async_mpt_client.accounts.licensees.create(
new_licensee_request_data, logo=account_icon
)

yield new_licensee

try:
await async_mpt_client.accounts.licensees.delete(new_licensee.id)
except MPTAPIError as error:
print(f"TEARDOWN - Unable to delete licensee: {error.title}") # noqa: WPS421


async def test_get_licensee_by_id(async_mpt_client, licensee_id):
licensee = await async_mpt_client.accounts.licensees.get(licensee_id)
assert licensee is not None


async def test_list_licensees(async_mpt_client):
limit = 10
licensees = await async_mpt_client.accounts.licensees.fetch_page(limit=limit)
assert len(licensees) > 0


async def test_get_licensee_by_id_not_found(async_mpt_client, invalid_licensee_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_client.accounts.licensees.get(invalid_licensee_id)


async def test_filter_licensees(async_mpt_client, licensee_id):
select_fields = ["-address"]

async_filtered_licensees = (
async_mpt_client.accounts.licensees.filter(RQLQuery(id=licensee_id))
.filter(RQLQuery(name="E2E Seeded Licensee"))
.select(*select_fields)
)

licensees = [
filtered_licensee async for filtered_licensee in async_filtered_licensees.iterate()
]

assert len(licensees) == 1


def test_create_licensee(async_created_licensee):
assert async_created_licensee is not None


async def test_delete_licensee(async_mpt_client, async_created_licensee):
await async_mpt_client.accounts.licensees.delete(async_created_licensee.id)


async def test_delete_licensee_not_found(async_mpt_client, invalid_licensee_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_client.accounts.licensees.delete(invalid_licensee_id)


async def test_update_licensee(
async_mpt_client, licensee_factory, account_icon, async_created_licensee
):
updated_licensee_data = licensee_factory(name="E2E Updated Licensee")

updated_licensee = await async_mpt_client.accounts.licensees.update(
async_created_licensee.id, updated_licensee_data, logo=account_icon
)

assert updated_licensee is not None


async def test_update_licensee_not_found(
async_mpt_client, licensee_factory, account_icon, invalid_licensee_id
):
updated_licensee_data = licensee_factory(name="Nonexistent Licensee")

with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_client.accounts.licensees.update(
invalid_licensee_id, updated_licensee_data, logo=account_icon
)


async def test_licensee_disable(async_mpt_client, async_created_licensee):
disabled_licensee = await async_mpt_client.accounts.licensees.disable(async_created_licensee.id)

assert disabled_licensee is not None


async def test_licensee_disable_not_found(async_mpt_client, invalid_licensee_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_client.accounts.licensees.disable(invalid_licensee_id)


async def test_licensee_enable(async_mpt_client, async_created_licensee):
await async_mpt_client.accounts.licensees.disable(async_created_licensee.id)

enabled_licensee = await async_mpt_client.accounts.licensees.enable(async_created_licensee.id)

assert enabled_licensee is not None


async def test_licensee_enable_not_found(async_mpt_client, invalid_licensee_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_client.accounts.licensees.enable(invalid_licensee_id)
Loading