From fda99b8e82e7cf9541f43a46a588e0ae2cb2f313 Mon Sep 17 00:00:00 2001 From: Lukasz Lancucki Date: Thu, 16 Apr 2026 13:50:39 +0100 Subject: [PATCH 1/2] refactor(models): update resource type annotations and return type of `to_dict` method --- mpt_api_client/models/model.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mpt_api_client/models/model.py b/mpt_api_client/models/model.py index e8ad5a46..daf5f002 100644 --- a/mpt_api_client/models/model.py +++ b/mpt_api_client/models/model.py @@ -8,7 +8,8 @@ from mpt_api_client.models.meta import Meta from mpt_api_client.models.model_collection import ModelCollection -ResourceData = dict[str, Any] +Resource = dict[str, Any] +ResourceData = Resource | list[Resource] _SNAKE_CASE_BOUNDARY = re.compile(r"([a-z0-9])([A-Z])") @@ -158,7 +159,7 @@ def __setattr__(self, name: str, value: Any) -> None: processed_value = self._process_value(value, target_class=target_class) object.__setattr__(self, snake_name, processed_value) - def to_dict(self) -> dict[str, Any]: + def to_dict(self) -> Resource: """Returns the resource as a dictionary with original API keys.""" out_dict = {} @@ -219,7 +220,7 @@ class Model(BaseModel): id: str def __init__( - self, resource_data: ResourceData | None = None, meta: Meta | None = None, **kwargs: Any + self, resource_data: Resource | None = None, meta: Meta | None = None, **kwargs: Any ) -> None: object.__setattr__(self, "meta", meta) data = dict(resource_data or {}) From d8503a303f8c5e72e201bcd97da0fbb320b6182c Mon Sep 17 00:00:00 2001 From: Lukasz Lancucki Date: Thu, 16 Apr 2026 12:30:16 +0100 Subject: [PATCH 2/2] refactor(helpdesk): update fixtures and tests for chat participants, unskip tests --- e2e_config.test.json | 3 +- .../helpdesk/chats/participants/conftest.py | 27 ++++++---------- .../participants/test_async_participants.py | 32 +++++++++++-------- .../participants/test_sync_participants.py | 29 +++++++++++------ 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/e2e_config.test.json b/e2e_config.test.json index 00bac28b..c5a99ec2 100644 --- a/e2e_config.test.json +++ b/e2e_config.test.json @@ -69,5 +69,6 @@ "notifications.subscriber.id": "NTS-0829-7123-7123", "integration.extension.id": "EXT-6587-4477", "integration.term.id": "ETC-6587-4477-0062", - "program.program.id": "PRG-9643-3741" + "program.program.id": "PRG-9643-3741", + "notifications.contact.id": "CTT-0001-9158" } diff --git a/tests/e2e/helpdesk/chats/participants/conftest.py b/tests/e2e/helpdesk/chats/participants/conftest.py index 12986081..b25f9058 100644 --- a/tests/e2e/helpdesk/chats/participants/conftest.py +++ b/tests/e2e/helpdesk/chats/participants/conftest.py @@ -1,10 +1,5 @@ import pytest -from tests.e2e.helper import ( - async_create_fixture_resource_and_delete, - create_fixture_resource_and_delete, -) - @pytest.fixture def chat_participants_service(mpt_ops, created_chat): @@ -17,27 +12,23 @@ def async_chat_participants_service(async_mpt_ops, created_chat): @pytest.fixture -def chat_participant_data(account_id, user_id): - return { - "identity": {"id": user_id}, - "account": {"id": account_id}, - } +def contact_id(e2e_config): + return e2e_config["notifications.contact.id"] + + +@pytest.fixture +def chat_participant_data(contact_id): + return {"contact": {"id": contact_id}} @pytest.fixture def created_chat_participant(chat_participants_service, chat_participant_data): - with create_fixture_resource_and_delete( - chat_participants_service, chat_participant_data - ) as chat_participant: - yield chat_participant + return chat_participants_service.create([chat_participant_data]) @pytest.fixture async def async_created_chat_participant(async_chat_participants_service, chat_participant_data): - async with async_create_fixture_resource_and_delete( - async_chat_participants_service, chat_participant_data - ) as chat_participant: - yield chat_participant + return await async_chat_participants_service.create([chat_participant_data]) @pytest.fixture(scope="session") diff --git a/tests/e2e/helpdesk/chats/participants/test_async_participants.py b/tests/e2e/helpdesk/chats/participants/test_async_participants.py index 530fb868..322f5354 100644 --- a/tests/e2e/helpdesk/chats/participants/test_async_participants.py +++ b/tests/e2e/helpdesk/chats/participants/test_async_participants.py @@ -3,6 +3,7 @@ import pytest from mpt_api_client.exceptions import MPTAPIError +from mpt_api_client.models import ModelCollection from mpt_api_client.resources.helpdesk.chat_participants import ChatParticipant pytestmark = [pytest.mark.flaky] @@ -15,30 +16,35 @@ async def test_list_chat_participants(async_chat_participants_service): assert all(isinstance(participant, ChatParticipant) for participant in result) -@pytest.mark.skip(reason="Unskip after MPT-20015 completed") # noqa: AAA01 -def test_create_chat_participant(async_created_chat_participant): - assert isinstance(async_created_chat_participant, ChatParticipant) +def test_create_chat_participant(async_created_chat_participant, contact_id): # noqa: AAA01 + assert isinstance(async_created_chat_participant, ModelCollection) + assert all(isinstance(cp, ChatParticipant) for cp in async_created_chat_participant) + chat_participants_list = async_created_chat_participant.to_list() + assert any(cp["contact"]["id"] == contact_id for cp in chat_participants_list) -@pytest.mark.skip(reason="Unskip after MPT-20015 completed") async def test_update_chat_participant( async_chat_participants_service, async_created_chat_participant ): - result = await async_chat_participants_service.update( - async_created_chat_participant.id, - {"status": "Active"}, - ) + chat_participant = async_created_chat_participant[0].to_dict() + new_muted_status = not chat_participant["muted"] + chat_participant["muted"] = new_muted_status + + result = await async_chat_participants_service.update(chat_participant["id"], chat_participant) - assert isinstance(result, ChatParticipant) + assert result.to_dict().get("muted") == new_muted_status -@pytest.mark.skip(reason="Unskip after MPT-20015 completed") async def test_delete_chat_participant( - async_chat_participants_service, async_created_chat_participant + async_chat_participants_service, async_created_chat_participant, contact_id ): - result = async_created_chat_participant + result = next( + chat_participant + for chat_participant in async_created_chat_participant.to_list() + if chat_participant["contact"]["id"] == contact_id + ) - await async_chat_participants_service.delete(result.id) + await async_chat_participants_service.delete(result["id"]) async def test_update_chat_participant_not_found( diff --git a/tests/e2e/helpdesk/chats/participants/test_sync_participants.py b/tests/e2e/helpdesk/chats/participants/test_sync_participants.py index 9bb30143..5c766398 100644 --- a/tests/e2e/helpdesk/chats/participants/test_sync_participants.py +++ b/tests/e2e/helpdesk/chats/participants/test_sync_participants.py @@ -3,6 +3,7 @@ import pytest from mpt_api_client.exceptions import MPTAPIError +from mpt_api_client.models import ModelCollection from mpt_api_client.resources.helpdesk.chat_participants import ChatParticipant pytestmark = [pytest.mark.flaky] @@ -15,23 +16,31 @@ def test_list_chat_participants(chat_participants_service): assert all(isinstance(participant, ChatParticipant) for participant in result) -@pytest.mark.skip(reason="Unskip after MPT-20015 completed") # noqa: AAA01 -def test_create_chat_participant(created_chat_participant): - assert isinstance(created_chat_participant, ChatParticipant) +def test_create_chat_participant(created_chat_participant, contact_id): # noqa: AAA01 + assert isinstance(created_chat_participant, ModelCollection) + assert all(isinstance(cp, ChatParticipant) for cp in created_chat_participant) + chat_participants_list = created_chat_participant.to_list() + assert any(cp["contact"]["id"] == contact_id for cp in chat_participants_list) -@pytest.mark.skip(reason="Unskip after MPT-20015 completed") def test_update_chat_participant(chat_participants_service, created_chat_participant): - result = chat_participants_service.update(created_chat_participant.id, {"status": "Active"}) + chat_participant = created_chat_participant[0].to_dict() + new_muted_status = not chat_participant["muted"] + chat_participant["muted"] = new_muted_status - assert isinstance(result, ChatParticipant) + result = chat_participants_service.update(chat_participant["id"], chat_participant) + assert result.to_dict().get("muted") == new_muted_status -@pytest.mark.skip(reason="Unskip after MPT-20015 completed") -def test_delete_chat_participant(chat_participants_service, created_chat_participant): - result = created_chat_participant - chat_participants_service.delete(result.id) +def test_delete_chat_participant(chat_participants_service, created_chat_participant, contact_id): + result = next( + chat_participant + for chat_participant in created_chat_participant.to_list() + if chat_participant["contact"]["id"] == contact_id + ) + + chat_participants_service.delete(result["id"]) def test_update_chat_participant_not_found(chat_participants_service, invalid_chat_participant_id):