Skip to content

Conversation

@albertsola
Copy link
Contributor

@albertsola albertsola commented Dec 19, 2025

Summary by CodeRabbit

  • New Features

    • Accounts notifications now support iteration over contacts in both synchronous and asynchronous flows.
    • Notifications API endpoint for accounts updated to the notifications path.
  • Tests

    • Added end-to-end and unit tests validating sync and async iteration behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

📝 Walkthrough

Walkthrough

Renamed resource model to NotificationContact, added collection mixins to sync/async account services, and changed the service endpoint from the commerce namespace to the notifications namespace. Added unit and e2e tests for sync and async .iterate() behavior.

Changes

Cohort / File(s) Summary
Production service
mpt_api_client/resources/notifications/accounts.py
Renamed model ContactNotificationContact; imported CollectionMixin and AsyncCollectionMixin; updated class signatures to include CollectionMixin[NotificationContact] / AsyncCollectionMixin[NotificationContact]; changed AccountsServiceConfig._endpoint to "/public/v1/notifications/accounts/{account_id}/categories/{category_id}/contacts" and set _model_class to NotificationContact.
Unit tests
tests/unit/resources/notifications/test_accounts.py
Added tests asserting presence of iterate on AccountsService and AsyncAccountsService (via hasattr).
End-to-end tests
tests/e2e/notifications/accounts/test_sync_accounts.py, tests/e2e/notifications/accounts/test_async_accounts.py
Added sync and async e2e tests that materialize .iterate() into lists and assert the result is a list.

Sequence Diagram(s)

(omitted — changes are primarily API signature/model and tests, not multi-component control-flow additions)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I hopped through code with tiny paws,

Renamed a friend and fixed the cause.
From commerce roads to notification lanes,
Iterators hum like gentle trains.
Tests cheer softly — carrots for gains.

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main changes: adding end-to-end tests for the notifications accounts categories contacts functionality, which aligns with all the changes in the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch e2e/MPT-14863/Notification-categories-contacts-endpoint

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

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

✅ Found Jira issue key in the title: MPT-14937

Generated by 🚫 dangerJS against 649c11b

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.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
mpt_api_client/resources/notifications/accounts.py (1)

11-12: Fix incorrect docstring for Contact class.

The docstring says "Account resource." but this class represents a Contact, not an Account. This could confuse developers reading the code.

🔎 Proposed fix
 class Contact(Model):
-    """Account resource."""
+    """Contact resource."""
🧹 Nitpick comments (2)
tests/unit/resources/notifications/test_accounts.py (2)

19-23: Simplify test and fix misleading function name.

The @pytest.mark.parametrize decorator is unnecessary when testing only a single method. The function name test_sync_batches_service_methods references "batches" which is misleading—the test validates the iterate method presence, not batch-specific functionality.

🔎 Proposed refactor
-@pytest.mark.parametrize("method", ["iterate"])
-def test_sync_batches_service_methods(accounts_service, method):
-    result = hasattr(accounts_service, method)
-
-    assert result is True
+def test_sync_accounts_service_has_iterate(accounts_service):
+    assert hasattr(accounts_service, "iterate")

26-30: Simplify test and fix misleading function name.

Same issue as the sync variant: the parametrize decorator is unnecessary, and the function name references "batches" instead of accurately describing what's being tested.

🔎 Proposed refactor
-@pytest.mark.parametrize("method", ["iterate"])
-def test_async_batches_service_methods(async_accounts_service, method):
-    result = hasattr(async_accounts_service, method)
-
-    assert result is True
+def test_async_accounts_service_has_iterate(async_accounts_service):
+    assert hasattr(async_accounts_service, "iterate")
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 359d60e and 5a77946.

📒 Files selected for processing (4)
  • mpt_api_client/resources/notifications/accounts.py (2 hunks)
  • tests/e2e/notifications/accounts/test_async_accounts.py (1 hunks)
  • tests/e2e/notifications/accounts/test_sync_accounts.py (1 hunks)
  • tests/unit/resources/notifications/test_accounts.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-12T15:02:20.732Z
Learnt from: robcsegal
Repo: softwareone-platform/mpt-api-python-client PR: 160
File: tests/e2e/commerce/agreement/attachment/test_async_agreement_attachment.py:55-58
Timestamp: 2025-12-12T15:02:20.732Z
Learning: In pytest with pytest-asyncio, if a test function uses async fixtures but contains no await, declare the test function as def (synchronous) instead of async def. Pytest-asyncio will resolve the async fixtures automatically; this avoids linter complaints about unnecessary async functions. This pattern applies to any test file under the tests/ directory that uses such fixtures.

Applied to files:

  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/unit/resources/notifications/test_accounts.py
  • tests/e2e/notifications/accounts/test_sync_accounts.py
📚 Learning: 2025-11-27T00:05:54.701Z
Learnt from: robcsegal
Repo: softwareone-platform/mpt-api-python-client PR: 131
File: tests/e2e/accounts/accounts_users/test_async_accounts_users.py:0-0
Timestamp: 2025-11-27T00:05:54.701Z
Learning: In pytest-asyncio, async fixtures are automatically resolved before being passed to test functions (both sync and async). Test functions receive the yielded value from async fixtures, not coroutines, so fixture parameters should never be awaited. A sync test function can use async fixtures without any special handling.

Applied to files:

  • tests/unit/resources/notifications/test_accounts.py
🧬 Code graph analysis (3)
tests/e2e/notifications/accounts/test_async_accounts.py (2)
tests/e2e/conftest.py (2)
  • async_mpt_ops (36-39)
  • account_id (122-123)
tests/e2e/notifications/conftest.py (1)
  • category_id (5-6)
tests/e2e/notifications/accounts/test_sync_accounts.py (2)
tests/e2e/conftest.py (2)
  • mpt_ops (31-32)
  • account_id (122-123)
tests/e2e/notifications/conftest.py (1)
  • category_id (5-6)
mpt_api_client/resources/notifications/accounts.py (3)
mpt_api_client/http/mixins.py (2)
  • AsyncCollectionMixin (578-645)
  • CollectionMixin (509-575)
mpt_api_client/resources/notifications/contacts.py (1)
  • Contact (11-12)
mpt_api_client/resources/accounts/account.py (3)
  • AccountsService (43-61)
  • AccountsServiceConfig (33-40)
  • AsyncAccountsService (64-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: danger
🔇 Additional comments (6)
tests/e2e/notifications/accounts/test_sync_accounts.py (1)

1-8: LGTM! E2E test validates the integration successfully.

The test correctly verifies that the sync accounts iterator can be instantiated and consumed. While the assertion only checks the result type, this is acceptable for an e2e test focused on validating that the endpoint is reachable and returns valid data structure.

tests/e2e/notifications/accounts/test_async_accounts.py (1)

1-8: LGTM! Async e2e test validates the integration successfully.

The test correctly uses async iteration patterns with async comprehension to collect results from the async iterator. The minimal type assertion is appropriate for e2e validation.

mpt_api_client/resources/notifications/accounts.py (4)

3-3: LGTM! Mixin imports added correctly.

The CollectionMixin and AsyncCollectionMixin imports are necessary for the new inheritance structure and enable collection iteration functionality.


23-23: LGTM! CollectionMixin inheritance enables iteration functionality.

Adding CollectionMixin[Contact] properly enables iterate(), fetch_page(), and fetch_one() methods for the sync service. The multiple inheritance order is correct with the mixin appearing before Service[Contact].


27-29: LGTM! AsyncCollectionMixin inheritance enables async iteration functionality.

Adding AsyncCollectionMixin[Contact] correctly enables async iteration methods for the async service. The inheritance order follows best practices with the mixin before AsyncService[Contact].


18-18: This is a new endpoint in the notifications namespace, not a migration from commerce.

The endpoint at line 18 was newly created in the notifications namespace. Git history shows only one commit creating this file, with no prior existence in a commerce namespace. There is no breaking change for existing code, as no old commerce endpoint implementation exists in this codebase to migrate from.

Likely an incorrect or invalid review comment.

@albertsola albertsola changed the title MPT-14863 E2E for notifications accounts categories contacts MPT-14937 E2E for notifications accounts categories contacts Dec 19, 2025
@albertsola albertsola force-pushed the e2e/MPT-14863/Notification-categories-contacts-endpoint branch from 5a77946 to 597f15a Compare December 29, 2025 08:10
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.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
mpt_api_client/resources/notifications/accounts.py (1)

11-12: Fix docstring to match the class name.

The docstring says "Account resource" but the class is named Contact. This should be corrected for consistency.

🔎 Proposed fix
 class Contact(Model):
-    """Account resource."""
+    """Contact resource."""
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a77946 and 597f15a.

📒 Files selected for processing (4)
  • mpt_api_client/resources/notifications/accounts.py
  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/e2e/notifications/accounts/test_sync_accounts.py
  • tests/unit/resources/notifications/test_accounts.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unit/resources/notifications/test_accounts.py
  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/e2e/notifications/accounts/test_sync_accounts.py
🧰 Additional context used
🧬 Code graph analysis (1)
mpt_api_client/resources/notifications/accounts.py (4)
mpt_api_client/resources/notifications/contacts.py (1)
  • Contact (11-12)
mpt_api_client/resources/accounts/account.py (3)
  • AccountsService (43-61)
  • AccountsServiceConfig (33-40)
  • AsyncAccountsService (64-82)
mpt_api_client/http/service.py (1)
  • Service (12-80)
mpt_api_client/http/async_service.py (1)
  • AsyncService (12-80)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (3)
mpt_api_client/resources/notifications/accounts.py (3)

3-3: LGTM! Collection mixin imports added correctly.

The imports for CollectionMixin and AsyncCollectionMixin are necessary to support the iterate pattern on both sync and async service classes.


23-29: LGTM! Collection mixins added correctly.

Both AccountsService and AsyncAccountsService now properly inherit from their respective collection mixins (CollectionMixin and AsyncCollectionMixin). This follows the established pattern in the codebase and will expose the iterate method for collection iteration. The inheritance order is correct for proper method resolution.


18-18: The namespace change from /public/v1/commerce/accounts/... to /public/v1/notifications/accounts/... is verified as intentional and complete. The git history confirms this was a deliberate migration (commit 597f15a for MPT-14863), all dependent code has been updated, and no stale references to the old endpoint exist. The service is properly integrated into the notifications module with corresponding tests in place.

@albertsola albertsola force-pushed the e2e/MPT-14863/Notification-categories-contacts-endpoint branch from 597f15a to 9972063 Compare December 29, 2025 08:37
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.

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 597f15a and 9972063.

📒 Files selected for processing (4)
  • mpt_api_client/resources/notifications/accounts.py
  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/e2e/notifications/accounts/test_sync_accounts.py
  • tests/unit/resources/notifications/test_accounts.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unit/resources/notifications/test_accounts.py
  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/e2e/notifications/accounts/test_sync_accounts.py
🧰 Additional context used
🧬 Code graph analysis (1)
mpt_api_client/resources/notifications/accounts.py (3)
mpt_api_client/http/mixins.py (2)
  • AsyncCollectionMixin (578-645)
  • CollectionMixin (509-575)
mpt_api_client/resources/accounts/account.py (3)
  • AccountsServiceConfig (33-40)
  • AccountsService (43-61)
  • AsyncAccountsService (64-82)
mpt_api_client/resources/notifications/contacts.py (1)
  • Contact (11-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
mpt_api_client/resources/notifications/accounts.py (4)

3-3: LGTM!

The import correctly adds CollectionMixin and AsyncCollectionMixin to support the new collection iteration functionality for both sync and async service classes.


15-20: LGTM! Endpoint migrated to notifications namespace.

The endpoint path change from /public/v1/commerce/... to /public/v1/notifications/... aligns with the notifications service context. Ensure downstream consumers and documentation are updated accordingly.


23-24: LGTM!

The CollectionMixin[Contact] addition follows the established pattern (as seen in mpt_api_client/resources/accounts/account.py) and correctly positions mixins before the base service class in the MRO.


27-29: LGTM!

The async service correctly mirrors the sync version's inheritance pattern, adding AsyncCollectionMixin[Contact] to provide async collection iteration capabilities.

@albertsola albertsola force-pushed the e2e/MPT-14863/Notification-categories-contacts-endpoint branch from 9972063 to b6de8a7 Compare December 29, 2025 10:14
@albertsola albertsola force-pushed the e2e/MPT-14863/Notification-categories-contacts-endpoint branch from b6de8a7 to 649c11b Compare December 29, 2025 10:15
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.

Actionable comments posted: 0

🧹 Nitpick comments (1)
tests/e2e/notifications/accounts/test_sync_accounts.py (1)

6-8: Consider strengthening the test assertion.

The current assertion only verifies that result is a list, but doesn't validate the content or types of items returned by the iterator. Consider asserting that items are NotificationContact instances or checking for expected attributes.

🔎 Suggested enhancement
 result = list(iterator)

-assert isinstance(result, list)
+assert isinstance(result, list)
+if result:  # Only check if non-empty
+    from mpt_api_client.resources.notifications.accounts import NotificationContact
+    assert all(isinstance(item, NotificationContact) for item in result)
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9972063 and 649c11b.

📒 Files selected for processing (4)
  • mpt_api_client/resources/notifications/accounts.py
  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/e2e/notifications/accounts/test_sync_accounts.py
  • tests/unit/resources/notifications/test_accounts.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/e2e/notifications/accounts/test_async_accounts.py
  • tests/unit/resources/notifications/test_accounts.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-12T15:02:20.732Z
Learnt from: robcsegal
Repo: softwareone-platform/mpt-api-python-client PR: 160
File: tests/e2e/commerce/agreement/attachment/test_async_agreement_attachment.py:55-58
Timestamp: 2025-12-12T15:02:20.732Z
Learning: In pytest with pytest-asyncio, if a test function uses async fixtures but contains no await, declare the test function as def (synchronous) instead of async def. Pytest-asyncio will resolve the async fixtures automatically; this avoids linter complaints about unnecessary async functions. This pattern applies to any test file under the tests/ directory that uses such fixtures.

Applied to files:

  • tests/e2e/notifications/accounts/test_sync_accounts.py
🧬 Code graph analysis (2)
mpt_api_client/resources/notifications/accounts.py (5)
mpt_api_client/http/mixins.py (2)
  • AsyncCollectionMixin (578-645)
  • CollectionMixin (509-575)
mpt_api_client/models/model.py (1)
  • Model (65-125)
mpt_api_client/resources/accounts/account.py (3)
  • AccountsServiceConfig (33-40)
  • AccountsService (43-61)
  • AsyncAccountsService (64-82)
mpt_api_client/http/service.py (1)
  • Service (12-80)
mpt_api_client/http/async_service.py (1)
  • AsyncService (12-80)
tests/e2e/notifications/accounts/test_sync_accounts.py (2)
tests/e2e/conftest.py (2)
  • mpt_ops (31-32)
  • account_id (122-123)
tests/e2e/notifications/conftest.py (1)
  • category_id (5-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
mpt_api_client/resources/notifications/accounts.py (4)

3-3: LGTM: Collection mixin imports enable iteration functionality.

The import additions correctly support the CollectionMixin and AsyncCollectionMixin functionality added to the service classes below.


11-12: Good: Model rename addresses previous feedback.

Renaming Contact to NotificationContact successfully addresses the naming conflict raised in earlier reviews, making it clear this model represents contacts in the notifications context rather than general contacts.

Based on learnings, this change resolves the duplicate class concern.


23-33: LGTM: Collection mixins correctly enable iteration functionality.

The addition of CollectionMixin and AsyncCollectionMixin to both service classes properly enables collection operations (iterate(), fetch_page(), fetch_one()). The type parameters correctly use NotificationContact, and the structure follows established patterns from other services like AccountsService in accounts/account.py.


18-18: Endpoint migration from commerce to notifications is complete and verified.

The namespace change from /public/v1/commerce/accounts/... to /public/v1/notifications/accounts/... has been properly completed. No references to the old commerce endpoint remain in the codebase, the new notifications endpoint is integrated into the notifications module, and the AccountsService has corresponding unit and E2E tests validating its functionality.

@sonarqubecloud
Copy link

@d3rky d3rky merged commit f47c482 into main Dec 29, 2025
6 of 7 checks passed
@d3rky d3rky deleted the e2e/MPT-14863/Notification-categories-contacts-endpoint branch December 29, 2025 11:30
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.

4 participants