Skip to content

MPT-18371 Helpdesk Chats core#227

Merged
jentyk merged 1 commit intomainfrom
feat/MPT-18369
Mar 13, 2026
Merged

MPT-18371 Helpdesk Chats core#227
jentyk merged 1 commit intomainfrom
feat/MPT-18369

Conversation

@jentyk
Copy link
Contributor

@jentyk jentyk commented Mar 13, 2026

Closes MPT-18371

Release Notes

  • Helpdesk API Resources: Added Helpdesk and AsyncHelpdesk entry-point classes and exported them from the resources package; integrated into MPTClient and AsyncMPTClient via new helpdesk properties.
  • Chats Service: Implemented ChatsService and AsyncChatsService providing create, get, update and list (collection) operations backed by the /public/v1/helpdesk/chats endpoint.
  • Chat Model: Introduced Chat model representing helpdesk chat entities.
  • Tests — End-to-End: Added async and sync e2e tests for chat retrieval, listing, updating, and not-found error handling.
  • Tests — Unit: Added unit tests validating Helpdesk/Chats services, public exports, and expected mixin methods for both sync and async variants.
  • Module Structure: Created helpdesk resource package with proper re-exports (mpt_api_client/resources/helpdesk and submodules).
  • E2E Test Config: Added e2e_config.test.json entry helpdesk.chat.id and pytest fixtures (chat_id, invalid_chat_id) for e2e tests.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 8581ddaf-46d0-483c-94f6-25b8764bfaca

📥 Commits

Reviewing files that changed from the base of the PR and between 1c2616e and bf74d41.

📒 Files selected for processing (15)
  • e2e_config.test.json
  • mpt_api_client/mpt_client.py
  • mpt_api_client/resources/__init__.py
  • mpt_api_client/resources/helpdesk/__init__.py
  • mpt_api_client/resources/helpdesk/chats.py
  • mpt_api_client/resources/helpdesk/helpdesk.py
  • tests/e2e/helpdesk/__init__.py
  • tests/e2e/helpdesk/chats/__init__.py
  • tests/e2e/helpdesk/chats/conftest.py
  • tests/e2e/helpdesk/chats/test_async_chats.py
  • tests/e2e/helpdesk/chats/test_sync_chats.py
  • tests/unit/resources/helpdesk/__init__.py
  • tests/unit/resources/helpdesk/test_chats.py
  • tests/unit/resources/helpdesk/test_helpdesk.py
  • tests/unit/test_mpt_client.py
✅ Files skipped from review due to trivial changes (1)
  • mpt_api_client/resources/helpdesk/chats.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/e2e/helpdesk/chats/conftest.py
  • tests/unit/resources/helpdesk/test_chats.py
  • tests/e2e/helpdesk/chats/test_sync_chats.py
  • e2e_config.test.json
  • mpt_api_client/resources/helpdesk/helpdesk.py

📝 Walkthrough

Walkthrough

Adds Helpdesk API surface: Chat model, synchronous and asynchronous Chats services, Helpdesk/AsyncHelpdesk wrappers, client properties exposing helpdesk, resource exports, e2e fixtures/tests, and unit tests.

Changes

Cohort / File(s) Summary
Configuration
e2e_config.test.json
Added helpdesk.chat.id configuration key.
Client integration
mpt_api_client/mpt_client.py
Added helpdesk properties to MPTClient and AsyncMPTClient returning Helpdesk / AsyncHelpdesk.
Resource exports
mpt_api_client/resources/__init__.py, mpt_api_client/resources/helpdesk/__init__.py
Re-exported AsyncHelpdesk and Helpdesk via package imports and updated __all__.
Helpdesk implementation
mpt_api_client/resources/helpdesk/chats.py, mpt_api_client/resources/helpdesk/helpdesk.py
Added Chat model, ChatsService/AsyncChatsService (Create/Update/Get/Collection mixins), and Helpdesk/AsyncHelpdesk wrappers exposing chats property.
E2E tests & fixtures
tests/e2e/helpdesk/chats/conftest.py, tests/e2e/helpdesk/chats/test_async_chats.py, tests/e2e/helpdesk/chats/test_sync_chats.py
Added fixtures for valid/invalid chat IDs and e2e tests exercising get, list, update, and not-found scenarios for sync and async flows.
Unit tests
tests/unit/resources/helpdesk/test_chats.py, tests/unit/resources/helpdesk/test_helpdesk.py, tests/unit/test_mpt_client.py
Added unit tests verifying presence of service mixin methods, Helpdesk/AsyncHelpdesk initialization and chats properties, and client resource registration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Jira Issue Key In Title ✅ Passed The PR title contains exactly one Jira issue key in the correct format at the beginning.
Test Coverage Required ✅ Passed PR modifies code in mpt_api_client/ directory and includes comprehensive test coverage with 6 test files covering unit and e2e tests for new helpdesk functionality.
Single Commit Required ✅ Passed The PR contains exactly one commit, maintaining a clean git history.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@jentyk jentyk force-pushed the feat/MPT-18369 branch 2 times, most recently from 196539a to 32f8572 Compare March 13, 2026 10:22
@jentyk jentyk marked this pull request as ready for review March 13, 2026 10:22
@jentyk jentyk requested a review from a team as a code owner March 13, 2026 10:22
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (5)
tests/unit/resources/helpdesk/test_helpdesk.py (1)

27-33: Strengthen property tests by asserting client wiring.

You already validate service type; also assert that the created service keeps the same client instance.

💡 Proposed improvement
 def test_helpdesk_properties(http_client, attr_name, expected):
     helpdesk = Helpdesk(http_client=http_client)

     result = getattr(helpdesk, attr_name)

     assert isinstance(result, expected)
+    assert result.http_client is http_client
@@
 def test_async_helpdesk_properties(async_http_client, attr_name, expected):
     helpdesk = AsyncHelpdesk(http_client=async_http_client)

     result = getattr(helpdesk, attr_name)

     assert isinstance(result, expected)
+    assert result.http_client is async_http_client

Also applies to: 41-46

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/resources/helpdesk/test_helpdesk.py` around lines 27 - 33, The
test_helpdesk_properties test creates a Helpdesk via Helpdesk(http_client=...),
but only asserts the service type; update the test to also assert the returned
service instance retains the same client instance (e.g., check the service's
client attribute or internal _client) by adding an assertion that result.client
(or result._client) is http_client; apply the same additional assertion to the
other similar test (the one at lines ~41-46) so both verify client wiring.
tests/e2e/helpdesk/chats/test_sync_chats.py (1)

32-36: Make not_found assertion stricter.

Assert expected status code so the test fails on unrelated MPTAPIError cases.

💡 Proposed assertion tightening
 def test_not_found(mpt_ops, invalid_chat_id):
     service = mpt_ops.helpdesk.chats

-    with pytest.raises(MPTAPIError):
+    with pytest.raises(MPTAPIError) as exc_info:
         service.get(invalid_chat_id)
+    assert exc_info.value.status_code == 404
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/e2e/helpdesk/chats/test_sync_chats.py` around lines 32 - 36, The
test_not_found in tests/e2e/helpdesk/chats/test_sync_chats.py currently only
asserts that service.get(invalid_chat_id) raises MPTAPIError; tighten it by
capturing the exception (using pytest.raises as excinfo) and then assert the
raised MPTAPIError's status_code equals the expected not-found code (e.g., 404)
to ensure you fail on unrelated MPTAPIError cases; locate the test_not_found
function and modify the pytest.raises usage around service.get to perform the
additional excinfo.value.status_code == 404 assertion.
tests/unit/resources/helpdesk/test_chats.py (1)

16-33: Prefer callable checks over hasattr for API method tests.

hasattr only checks attribute existence. For method-contract tests, callable(getattr(...)) is stricter.

💡 Proposed improvement
 def test_mixins_present(chats_service, method):
-    result = hasattr(chats_service, method)
-
-    assert result is True
+    result = getattr(chats_service, method, None)
+    assert callable(result)
@@
 def test_async_mixins_present(async_chats_service, method):
-    result = hasattr(async_chats_service, method)
-
-    assert result is True
+    result = getattr(async_chats_service, method, None)
+    assert callable(result)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/resources/helpdesk/test_chats.py` around lines 16 - 33, Replace
the fragile hasattr checks in tests test_mixins_present and
test_async_mixins_present with callable assertions: use
callable(getattr(chats_service, method, None)) and
callable(getattr(async_chats_service, method, None)) respectively so the tests
verify the attribute is an actual callable method (use getattr default None to
avoid AttributeError).
tests/e2e/helpdesk/chats/test_async_chats.py (2)

35-40: Assert the 404 contract, not only exception type.

pytest.raises(MPTAPIError) alone can pass on unrelated API failures; check status details too.

💡 Proposed assertion tightening
 async def test_not_found(async_mpt_ops, invalid_chat_id):
     service = async_mpt_ops.helpdesk.chats

-    with pytest.raises(MPTAPIError):
+    with pytest.raises(MPTAPIError) as exc_info:
         await service.get(invalid_chat_id)
+    assert exc_info.value.status_code == 404
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/e2e/helpdesk/chats/test_async_chats.py` around lines 35 - 40, The
test_not_found currently only checks that an MPTAPIError is raised; tighten it
to assert the 404 contract by using pytest.raises(MPTAPIError) as excinfo around
await async_mpt_ops.helpdesk.chats.get(invalid_chat_id) and then assert the
exception contains the HTTP 404 info (e.g., excinfo.value.status == 404 or
excinfo.value.status_code == 404 or excinfo.value.response.status_code == 404)
and optionally assert the error message contains "Not Found" to ensure the
failure is the expected 404 not some other API error.

6-36: Remove redundant @pytest.mark.asyncio decorators.

The project uses asyncio_mode = "auto" in pyproject.toml, which automatically detects and runs async test functions without requiring explicit markers.

Proposed cleanup
-@pytest.mark.asyncio
 async def test_get_chat(async_mpt_ops, chat_id):

-@pytest.mark.asyncio
 async def test_list_chats(async_mpt_ops):

-@pytest.mark.asyncio
 async def test_update_chat(async_mpt_ops, chat_id, short_uuid):

-@pytest.mark.asyncio
 async def test_not_found(async_mpt_ops, invalid_chat_id):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/e2e/helpdesk/chats/test_async_chats.py` around lines 6 - 36, Tests in
tests/e2e/helpdesk/chats/test_async_chats.py are redundantly decorated with
`@pytest.mark.asyncio`; remove the decorator lines from the async test functions
test_get_chat, test_list_chats, test_update_chat, and test_not_found so they
rely on pytest's asyncio_mode="auto" detection; keep the async function
signatures and awaits unchanged (locate the decorator above each function name
to delete).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/e2e/helpdesk/chats/test_async_chats.py`:
- Around line 35-40: The test_not_found currently only checks that an
MPTAPIError is raised; tighten it to assert the 404 contract by using
pytest.raises(MPTAPIError) as excinfo around await
async_mpt_ops.helpdesk.chats.get(invalid_chat_id) and then assert the exception
contains the HTTP 404 info (e.g., excinfo.value.status == 404 or
excinfo.value.status_code == 404 or excinfo.value.response.status_code == 404)
and optionally assert the error message contains "Not Found" to ensure the
failure is the expected 404 not some other API error.
- Around line 6-36: Tests in tests/e2e/helpdesk/chats/test_async_chats.py are
redundantly decorated with `@pytest.mark.asyncio`; remove the decorator lines from
the async test functions test_get_chat, test_list_chats, test_update_chat, and
test_not_found so they rely on pytest's asyncio_mode="auto" detection; keep the
async function signatures and awaits unchanged (locate the decorator above each
function name to delete).

In `@tests/e2e/helpdesk/chats/test_sync_chats.py`:
- Around line 32-36: The test_not_found in
tests/e2e/helpdesk/chats/test_sync_chats.py currently only asserts that
service.get(invalid_chat_id) raises MPTAPIError; tighten it by capturing the
exception (using pytest.raises as excinfo) and then assert the raised
MPTAPIError's status_code equals the expected not-found code (e.g., 404) to
ensure you fail on unrelated MPTAPIError cases; locate the test_not_found
function and modify the pytest.raises usage around service.get to perform the
additional excinfo.value.status_code == 404 assertion.

In `@tests/unit/resources/helpdesk/test_chats.py`:
- Around line 16-33: Replace the fragile hasattr checks in tests
test_mixins_present and test_async_mixins_present with callable assertions: use
callable(getattr(chats_service, method, None)) and
callable(getattr(async_chats_service, method, None)) respectively so the tests
verify the attribute is an actual callable method (use getattr default None to
avoid AttributeError).

In `@tests/unit/resources/helpdesk/test_helpdesk.py`:
- Around line 27-33: The test_helpdesk_properties test creates a Helpdesk via
Helpdesk(http_client=...), but only asserts the service type; update the test to
also assert the returned service instance retains the same client instance
(e.g., check the service's client attribute or internal _client) by adding an
assertion that result.client (or result._client) is http_client; apply the same
additional assertion to the other similar test (the one at lines ~41-46) so both
verify client wiring.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: bd2d0f2c-aa7d-43f0-b9fa-fb0503ae79a4

📥 Commits

Reviewing files that changed from the base of the PR and between ed1c921 and 32f8572.

📒 Files selected for processing (15)
  • e2e_config.test.json
  • mpt_api_client/mpt_client.py
  • mpt_api_client/resources/__init__.py
  • mpt_api_client/resources/helpdesk/__init__.py
  • mpt_api_client/resources/helpdesk/chats.py
  • mpt_api_client/resources/helpdesk/helpdesk.py
  • tests/e2e/helpdesk/__init__.py
  • tests/e2e/helpdesk/chats/__init__.py
  • tests/e2e/helpdesk/chats/conftest.py
  • tests/e2e/helpdesk/chats/test_async_chats.py
  • tests/e2e/helpdesk/chats/test_sync_chats.py
  • tests/unit/resources/helpdesk/__init__.py
  • tests/unit/resources/helpdesk/test_chats.py
  • tests/unit/resources/helpdesk/test_helpdesk.py
  • tests/unit/test_mpt_client.py

from mpt_api_client.exceptions import MPTAPIError


@pytest.mark.asyncio
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't mark those as asyncio

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

@jentyk jentyk requested a review from albertsola March 13, 2026 15:08
@sonarqubecloud
Copy link

@jentyk jentyk merged commit f0bf751 into main Mar 13, 2026
4 checks passed
@jentyk jentyk deleted the feat/MPT-18369 branch March 13, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants