Skip to content

Conversation

@robcsegal
Copy link
Contributor

@robcsegal robcsegal commented Dec 9, 2025

Updated account seeding and tests
https://softwareone.atlassian.net/browse/MPT-16315

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for operations account seeding alongside existing vendor and client accounts.
  • Refactor

    • Simplified account creation flows with generalized environment variable initialization.
    • Updated account reference naming for consistency across configuration and tests.
    • Restructured API token, buyer, licensee, module, seller, and user group creation to use direct initialization patterns.
  • Tests

    • Updated test fixtures and configurations to reflect new account initialization approach.

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

@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Walkthrough

This PR refactors account seeding by introducing a unified env-var-based account initializer, replacing specific get/init patterns with direct creation functions across modules, renaming test fixtures from buyer_account_id to client_account_id, and updating init_resource to handle both string and object return types.

Changes

Cohort / File(s) Summary
Account seeding initialization
seed/accounts/account.py, seed/accounts/accounts.py
Introduces generic init_account_id(env_var, context) to read VENDOR_ACCOUNT_ID, CLIENT_ACCOUNT_ID, and OPERATIONS_ACCOUNT_ID; replaces specific init_vendor_account_id and init_client_account_id; seed_accounts now explicitly seeds all three accounts via seed_account_ids()
Resource creation functions
seed/accounts/api_tokens.py, seed/accounts/buyer.py, seed/accounts/licensee.py, seed/accounts/module.py, seed/accounts/seller.py, seed/accounts/user_group.py
Removes get_* functions; renames init_* to create_* with simplified direct-creation logic; updates all to use require_context_id for ID retrieval and init_resource for seeding instead of in-place logic; api_tokens.py also removes custom API service classes
Helper utilities
seed/helper.py
Updates init_resource to handle both string and object return types from resource factory; if factory returns string, uses it directly; otherwise extracts id attribute
Configuration and test fixtures
e2e_config.test.json, tests/e2e/conftest.py
Renames fixture from buyer_account_id to client_account_id; updates config key from accounts.buyer.account.id to accounts.client_account.id
E2E test fixture updates
tests/e2e/accounts/buyers/conftest.py, tests/e2e/accounts/buyers/test_*.py, tests/e2e/accounts/licensees/conftest.py, tests/e2e/catalog/pricing_policies/conftest.py
Propagates fixture name change from buyer_account_id to client_account_id across all test signatures and internal usage
Seed unit tests
tests/seed/accounts/test_account.py, tests/seed/accounts/test_accounts.py, tests/seed/accounts/test_api_token.py, tests/seed/accounts/test_buyer.py, tests/seed/accounts/test_licensee.py, tests/seed/accounts/test_module.py, tests/seed/accounts/test_seller.py, tests/seed/accounts/test_user_group.py
Updates tests to validate new create_* functions; introduces context_with_data fixtures; removes get_* and old init_* tests; mocks init_resource instead of individual creation functions; verifies new payload structures and account ID sourcing via context helpers

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25–35 minutes

  • Attention areas:
    • Verify init_resource behavior change in seed/helper.py correctly handles both string and object returns across all call sites
    • Ensure require_context_id error handling is consistent when account/module IDs are missing from context
    • Validate that the seed order in seed_accounts (account IDs → seller → buyer → module → api_token → user_group → licensee) does not introduce dependency issues
    • Check that all create_* functions properly extract IDs via require_context_id before API calls
    • Confirm test fixture changes (client_account_id) are correctly wired through all dependent tests and do not break other test modules

Possibly related PRs

Suggested reviewers

  • albertsola
  • jentyk
  • d3rky
  • svazquezco
  • ruben-sebrango

Poem

🐰 Account IDs sprouted from env vars so bright,
Creation functions dance in the seeding light,
No more get-or-create, just direct and clean,
Context helpers whisper IDs between,
A tidy refactor hops into the night! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.58% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 accurately describes the primary change: refactoring account seeding logic and updating related tests to use a new resource-based initialization pattern.
✨ 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 MPT-16315-update-account-seeding-to-latest-convention

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

Warnings
⚠️

This PR changes 999 lines across 24 files (threshold: 600). Please consider splitting it into smaller PRs for easier review.

⚠️

Some newly added source files do not have corresponding tests in the tests/ folder with matching structure and the test_ prefix.

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

Tests mirroring check (created files only)

Added source file Expected test (added in this PR)
seed/accounts/account.py tests/accounts/test_account.py

Generated by 🚫 dangerJS against 6b782e6

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

Caution

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

⚠️ Outside diff range comments (1)
tests/seed/accounts/test_buyer.py (1)

15-38: Test will fail due to key casing mismatch.

The expected data uses "lastName" (camelCase), but according to the implementation in seed/accounts/buyer.py (lines 22-24), the actual key is "LastName" (PascalCase with capital L):

"contact": {
    "firstName": "first",
    "LastName": "last",  # Note: capital L
    ...
}

This test will fail with an assertion error.

Apply this diff to fix the expected key:

     "contact": {
         "firstName": "first",
-        "lastName": "last",
+        "LastName": "last",
         "email": "created.buyer@example.com",
     },

Alternatively, if lastName is the intended API contract, the fix should be applied to seed/accounts/buyer.py instead.

🧹 Nitpick comments (6)
seed/accounts/account.py (3)

15-21: Remove unused noqa directive and refactor error message.

Two minor issues flagged by static analysis:

  1. The noqa: RUF029 directive on line 15 is unused and should be removed
  2. The error message on line 19 should be extracted to follow TRY003 guidelines

Apply this diff:

 @inject
-async def init_vendor_account_id(context: Context = Provide[Container.context]) -> Account:  # noqa: RUF029
+async def init_vendor_account_id(context: Context = Provide[Container.context]) -> Account:
     """Initialize account ID in context."""
     account_id = os.getenv("VENDOR_ACCOUNT_ID")
     if not account_id:
-        raise ValueError("VENDOR_ACCOUNT_ID environment variable is required")
+        msg = "VENDOR_ACCOUNT_ID environment variable is required"
+        raise ValueError(msg)
     context["accounts.account.id"] = account_id
     return Account({"id": account_id})

25-31: Remove unused noqa directive and refactor error message.

Same issues as init_vendor_account_id:

  1. The noqa: RUF029 directive on line 25 is unused and should be removed
  2. The error message on line 29 should be extracted to follow TRY003 guidelines

Apply this diff:

 @inject
-async def init_client_account_id(context: Context = Provide[Container.context]) -> Account:  # noqa: RUF029
+async def init_client_account_id(context: Context = Provide[Container.context]) -> Account:
     """Initialize client account ID in context."""
     account_id = os.getenv("CLIENT_ACCOUNT_ID")
     if not account_id:
-        raise ValueError("CLIENT_ACCOUNT_ID environment variable is required")
+        msg = "CLIENT_ACCOUNT_ID environment variable is required"
+        raise ValueError(msg)
     context["accounts.client_account.id"] = account_id
     return Account({"id": account_id})

34-39: Clarify the docstring.

The docstring says "Seed account" but the function seeds both vendor and client account IDs. Consider updating for clarity.

Apply this diff:

 async def seed_account_ids() -> None:
-    """Seed account."""
+    """Seed account IDs."""
     logger.debug("Seeding vendor account ...")
     await init_resource("accounts.account.id", init_vendor_account_id)
     await init_resource("accounts.client_account.id", init_client_account_id)
     logger.debug("Seeding account completed.")
seed/accounts/licensee.py (1)

16-45: Remove unused noqa directive; refactoring looks good.

Static analysis flags the noqa: WPS238 directive on line 16 as unused (unknown rule). The refactored function correctly uses require_context_id for context-based ID retrieval, which is a clean improvement.

Apply this diff to remove the unused directive:

 @inject
-def build_licensee_data(  # noqa: WPS238
+def build_licensee_data(
     context: Context = Provide[Container.context],
 ) -> dict[str, object]:
tests/seed/accounts/test_seller.py (1)

7-9: Unused fixture context_without_data.

This fixture is defined but not used in any test within this file. Consider removing it unless it's intended for future use.

-@pytest.fixture
-def context_without_data() -> Context:
-    return Context()
-
-
tests/seed/accounts/test_licensee.py (1)

62-69: Tighten assertion on init_resource call in test_seed_licensee

Right now the test only checks that init_resource was awaited once. Asserting the exact namespace and factory would better lock in the new seeding contract:

-    mock_init_resource.assert_awaited_once()
+    mock_init_resource.assert_awaited_once_with("accounts.licensee.id", create_licensee)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d927ac4 and 22c94cf.

📒 Files selected for processing (26)
  • e2e_config.test.json (1 hunks)
  • mpt_api_client/resources/accounts/account.py (2 hunks)
  • mpt_api_client/resources/accounts/buyers.py (2 hunks)
  • mpt_api_client/resources/accounts/licensees.py (2 hunks)
  • seed/accounts/account.py (1 hunks)
  • seed/accounts/accounts.py (2 hunks)
  • seed/accounts/api_tokens.py (2 hunks)
  • seed/accounts/buyer.py (2 hunks)
  • seed/accounts/licensee.py (2 hunks)
  • seed/accounts/module.py (1 hunks)
  • seed/accounts/seller.py (2 hunks)
  • seed/accounts/user_group.py (2 hunks)
  • tests/e2e/accounts/buyers/conftest.py (1 hunks)
  • tests/e2e/accounts/buyers/test_async_buyers.py (3 hunks)
  • tests/e2e/accounts/buyers/test_sync_buyers.py (2 hunks)
  • tests/e2e/accounts/licensees/conftest.py (2 hunks)
  • tests/e2e/catalog/pricing_policies/conftest.py (1 hunks)
  • tests/e2e/conftest.py (1 hunks)
  • tests/seed/accounts/test_account.py (1 hunks)
  • tests/seed/accounts/test_accounts.py (2 hunks)
  • tests/seed/accounts/test_api_token.py (1 hunks)
  • tests/seed/accounts/test_buyer.py (2 hunks)
  • tests/seed/accounts/test_licensee.py (2 hunks)
  • tests/seed/accounts/test_module.py (3 hunks)
  • tests/seed/accounts/test_seller.py (2 hunks)
  • tests/seed/accounts/test_user_group.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 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/e2e/accounts/buyers/test_async_buyers.py
🧬 Code graph analysis (20)
mpt_api_client/resources/accounts/account.py (1)
mpt_api_client/resources/accounts/mixins.py (6)
  • ActivatableMixin (4-27)
  • EnablableMixin (30-53)
  • ValidateMixin (56-68)
  • AsyncActivatableMixin (134-159)
  • AsyncEnablableMixin (162-185)
  • AsyncValidateMixin (188-200)
seed/accounts/api_tokens.py (4)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/resources/accounts/api_tokens.py (1)
  • ApiToken (12-13)
tests/seed/accounts/test_account.py (4)
seed/accounts/account.py (3)
  • init_client_account_id (25-31)
  • init_vendor_account_id (15-21)
  • seed_account_ids (34-39)
tests/seed/conftest.py (1)
  • context (14-15)
seed/context.py (1)
  • Context (12-33)
seed/helper.py (1)
  • init_resource (44-84)
tests/e2e/accounts/licensees/conftest.py (2)
tests/e2e/conftest.py (1)
  • client_account_id (127-128)
tests/e2e/accounts/conftest.py (1)
  • user_group_factory (45-60)
seed/accounts/module.py (4)
seed/helper.py (1)
  • init_resource (44-84)
seed/context.py (1)
  • Context (12-33)
mpt_api_client/resources/accounts/modules.py (1)
  • Module (11-12)
mpt_api_client/models/model.py (1)
  • id (119-121)
mpt_api_client/resources/accounts/buyers.py (3)
mpt_api_client/http/mixins.py (4)
  • CreateFileMixin (115-144)
  • UpdateFileMixin (147-184)
  • AsyncCreateFileMixin (187-216)
  • AsyncUpdateFileMixin (219-256)
mpt_api_client/resources/accounts/mixins.py (6)
  • ActivatableMixin (4-27)
  • EnablableMixin (30-53)
  • ValidateMixin (56-68)
  • AsyncActivatableMixin (134-159)
  • AsyncEnablableMixin (162-185)
  • AsyncValidateMixin (188-200)
mpt_api_client/resources/catalog/mixins.py (2)
  • ActivatableMixin (109-132)
  • AsyncActivatableMixin (135-160)
mpt_api_client/resources/accounts/licensees.py (2)
mpt_api_client/http/mixins.py (4)
  • CreateFileMixin (115-144)
  • UpdateFileMixin (147-184)
  • AsyncCreateFileMixin (187-216)
  • AsyncUpdateFileMixin (219-256)
mpt_api_client/resources/accounts/mixins.py (2)
  • EnablableMixin (30-53)
  • AsyncEnablableMixin (162-185)
seed/accounts/user_group.py (2)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_licensee.py (4)
seed/accounts/licensee.py (3)
  • build_licensee_data (16-45)
  • create_licensee (49-57)
  • seed_licensee (60-64)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_module.py (1)
  • context_with_data (23-26)
tests/seed/accounts/test_user_group.py (1)
  • context_with_data (12-16)
seed/accounts/licensee.py (5)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/mpt_client.py (1)
  • AsyncMPTClient (20-71)
mpt_api_client/resources/accounts/licensees.py (1)
  • Licensee (21-22)
tests/e2e/accounts/buyers/conftest.py (1)
tests/e2e/conftest.py (2)
  • client_account_id (127-128)
  • account_id (122-123)
tests/e2e/catalog/pricing_policies/conftest.py (1)
tests/e2e/conftest.py (2)
  • client_account_id (127-128)
  • product_id (96-97)
seed/accounts/accounts.py (2)
seed/accounts/account.py (1)
  • seed_account_ids (34-39)
tests/e2e/conftest.py (1)
  • logger (63-64)
tests/seed/accounts/test_api_token.py (4)
seed/accounts/api_tokens.py (3)
  • create_api_token (31-38)
  • seed_api_token (41-45)
  • build_api_token_data (15-27)
tests/seed/conftest.py (2)
  • context (14-15)
  • operations_client (24-25)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_module.py (1)
  • context_with_data (23-26)
tests/seed/accounts/test_seller.py (3)
seed/accounts/seller.py (3)
  • build_seller_data (14-29)
  • create_seller (33-38)
  • seed_seller (41-45)
tests/seed/conftest.py (2)
  • context (14-15)
  • operations_client (24-25)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_buyer.py (2)
seed/accounts/buyer.py (3)
  • build_buyer_data (16-37)
  • create_buyer (41-49)
  • seed_buyer (52-56)
seed/context.py (1)
  • Context (12-33)
tests/e2e/accounts/buyers/test_sync_buyers.py (3)
tests/e2e/conftest.py (3)
  • mpt_ops (31-32)
  • client_account_id (127-128)
  • account_id (122-123)
tests/e2e/accounts/buyers/conftest.py (2)
  • buyer_factory (10-34)
  • invalid_buyer_id (5-6)
tests/e2e/accounts/conftest.py (1)
  • account_icon (20-21)
tests/seed/accounts/test_user_group.py (2)
seed/accounts/user_group.py (3)
  • create_user_group (33-39)
  • seed_user_group (42-46)
  • build_user_group_data (15-29)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_module.py (4)
seed/accounts/module.py (2)
  • refresh_module (16-31)
  • seed_module (34-38)
tests/seed/accounts/test_user_group.py (1)
  • context_with_data (12-16)
seed/context.py (1)
  • Context (12-33)
mpt_api_client/resources/accounts/modules.py (1)
  • Module (11-12)
seed/accounts/buyer.py (3)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
🪛 Ruff (0.14.8)
seed/accounts/account.py

15-15: Unused noqa directive (non-enabled: RUF029)

Remove unused noqa directive

(RUF100)


19-19: Avoid specifying long messages outside the exception class

(TRY003)


25-25: Unused noqa directive (non-enabled: RUF029)

Remove unused noqa directive

(RUF100)


29-29: Avoid specifying long messages outside the exception class

(TRY003)

tests/seed/accounts/test_licensee.py

43-43: Unused noqa directive (unknown: WPS218)

Remove unused noqa directive

(RUF100)

seed/accounts/licensee.py

16-16: Unused noqa directive (unknown: WPS238)

Remove unused noqa directive

(RUF100)

seed/accounts/accounts.py

14-14: Unused noqa directive (unknown: WPS217, WPS213)

Remove unused noqa directive

(RUF100)

⏰ 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 (53)
e2e_config.test.json (1)

4-4: LGTM! Configuration key updated consistently.

The account identifier has been successfully renamed to accounts.client_account.id, aligning with the broader refactoring effort across the codebase.

seed/accounts/module.py (2)

10-10: LGTM! Import added for new seeding pattern.

The init_resource import supports the refactored seeding approach and is consistent with changes across other seed modules.


16-31: LGTM! Simplified module fetching logic.

The refactored refresh_module function correctly:

  • Fetches the "Access Management" module directly
  • Validates the module type
  • Stores the module ID in context
  • Handles edge cases with appropriate warnings
mpt_api_client/resources/accounts/account.py (1)

42-46: LGTM! Type parameters tightened for improved type safety.

The mixin type parameters have been correctly updated from Model to Account for both synchronous and asynchronous service classes. This change improves type safety without affecting runtime behavior and is consistent with similar updates across other account service modules.

Also applies to: 62-66

seed/accounts/licensee.py (3)

9-9: LGTM! Imports added for context-based ID handling.

The new imports support the refactored seeding pattern that uses require_context_id for ID validation and init_resource for resource initialization.


49-57: LGTM! Clean licensee creation implementation.

The create_licensee function follows the consistent pattern established across other seed modules, building the licensee data from context and creating it via the API.


60-64: LGTM! Seeding flow updated to use init_resource pattern.

The refactored seed_licensee function correctly uses the standardized init_resource helper with the create_licensee factory.

seed/accounts/seller.py (1)

9-9: LGTM! Seller seeding refactored consistently.

The changes successfully refactor the seller seeding to follow the standardized pattern:

  • Added init_resource import
  • Renamed init_seller to create_seller with simplified implementation
  • Updated seed_seller to use init_resource with the create_seller factory

These changes are consistent with the refactoring across other seed modules.

Also applies to: 33-38, 41-45

mpt_api_client/resources/accounts/licensees.py (1)

36-38: LGTM! Type parameters tightened for improved type safety.

The mixin type parameters have been correctly updated from Model to Licensee for both synchronous and asynchronous service classes. This enhances type safety and is consistent with the refactoring pattern applied across other account service modules.

Also applies to: 49-51

mpt_api_client/resources/accounts/buyers.py (1)

41-45: LGTM! Type parameters tightened for improved type safety.

The mixin type parameters have been correctly updated from Model to Buyer for both synchronous and asynchronous service classes. This enhances type safety and completes the consistent refactoring pattern applied across all account service modules.

Also applies to: 74-78

tests/seed/accounts/test_accounts.py (1)

5-7: LGTM!

The test correctly mocks seed_account_ids as an AsyncMock and includes it in the assertion list to verify it's called exactly once during the seeding process. This aligns with the implementation in seed/accounts/accounts.py.

Also applies to: 27-35

tests/e2e/conftest.py (1)

126-129: LGTM!

The new client_account_id fixture follows the established pattern for ID fixtures in this file and aligns with the broader refactor to standardize on client_account terminology.

tests/e2e/catalog/pricing_policies/conftest.py (1)

7-11: LGTM!

The parameter rename from buyer_account_id to client_account_id is consistent with the fixture changes in tests/e2e/conftest.py. The "client" field in the payload semantically aligns with the new naming convention.

tests/e2e/accounts/buyers/conftest.py (1)

10-14: LGTM!

The buyer_factory fixture correctly uses client_account_id as both the fixture dependency and the default value for the account_id parameter, maintaining consistency with the naming convention changes across the test suite.

seed/accounts/accounts.py (2)

3-3: LGTM!

The addition of seed_account_ids() as the first step in the seeding sequence is correct—account IDs must be initialized before dependent resources (seller, buyer, etc.) are seeded.

Also applies to: 17-18


14-14: Remove this suggestion—the noqa directives are necessary.

The project uses wemake-python-styleguide, which defines WPS217 and WPS213. These noqa directives are valid and should be retained.

tests/seed/accounts/test_account.py (3)

7-12: LGTM!

The context_with_data fixture provides a pre-populated context for testing the init functions, allowing verification that the environment values correctly overwrite existing context entries.


15-21: LGTM!

Both tests correctly verify:

  1. The returned Account object has the expected ID from the environment variable
  2. The context is mutated with the new ID value

This provides good coverage for the init functions' dual responsibilities.

Also applies to: 24-30


33-42: LGTM!

The test correctly mocks init_resource and verifies it's called with the expected namespace keys and init functions for both vendor and client accounts.

tests/e2e/accounts/buyers/test_sync_buyers.py (1)

10-10: LGTM!

All references to buyer_account_id have been consistently replaced with client_account_id across fixtures and test functions, aligning with the broader refactor.

Also applies to: 14-14, 78-78, 80-80, 88-88, 91-91

tests/e2e/accounts/licensees/conftest.py (1)

15-15: LGTM!

The licensee_factory correctly uses client_account_id for both the user group creation and the licensee's account reference, maintaining consistency with the broader test suite refactor.

Also applies to: 20-20, 34-34

seed/accounts/api_tokens.py (4)

9-9: LGTM!

The new imports for init_resource and require_context_id from seed.helper align with the refactored seeding pattern used across other account modules.


14-27: LGTM!

The refactor to use require_context_id for fetching account_id and module_id provides better error handling with clear context about which resource is missing and for what action. This is consistent with the pattern used in build_buyer_data and build_user_group_data.


30-38: LGTM!

The rename from init_api_token to create_api_token with create-only semantics is a good simplification. The function now has a single responsibility and delegates the "get-or-create" logic to init_resource.


41-45: LGTM!

The seed_api_token function now uses the init_resource pattern, which handles caching the resource ID in the context and only calls create_api_token when needed. This is consistent with other seed functions in the codebase.

tests/seed/accounts/test_seller.py (2)

32-43: LGTM!

The test correctly validates the create_seller flow by mocking the API call, invoking the function, and asserting both the return value and the payload structure.


46-53: LGTM!

The test correctly patches init_resource and verifies it's awaited once when seed_seller is called, aligning with the new seeding pattern.

tests/e2e/accounts/buyers/test_async_buyers.py (3)

9-14: LGTM!

The rename from buyer_account_id to client_account_id in the async_created_buyer fixture is consistent with the broader PR refactoring and is properly propagated to the buyer_factory call.


80-84: LGTM!

The parameter rename is correctly applied to test_update_buyer.


93-97: LGTM!

The parameter rename is correctly applied to test_update_buyer_not_found.

tests/seed/accounts/test_module.py (4)

4-4: LGTM!

The import is updated to reflect the removal of get_module and the new seeding flow that uses refresh_module and seed_module.


22-26: LGTM!

The context_with_data fixture provides the pre-populated accounts.module.id needed for testing the module refresh flow.


43-55: LGTM!

The test correctly uses the new context_with_data fixture and validates that refresh_module returns the expected module when the API call is mocked.


58-65: LGTM!

The test correctly patches init_resource and verifies it's awaited once when seed_module is called.

tests/seed/accounts/test_buyer.py (2)

41-55: LGTM!

The test correctly validates the create_buyer flow by mocking the API call and verifying both the return value and critical payload fields.


58-65: LGTM!

The test correctly patches init_resource and verifies it's awaited once when seed_buyer is called.

tests/seed/accounts/test_user_group.py (5)

5-5: LGTM!

The import is updated to use create_user_group instead of the removed init_user_group, aligning with the new create-focused seeding flow.


11-16: LGTM!

The context_with_data fixture provides the required accounts.client_account.id and accounts.module.id values for testing build_user_group_data and create_user_group.


19-31: LGTM!

The test correctly validates that build_user_group_data produces the expected payload using IDs from the context fixture.


34-48: LGTM!

The test validates the create_user_group flow by mocking the API call and verifying both the return value and the payload structure.


51-58: LGTM!

The test correctly patches init_resource and verifies it's awaited once when seed_user_group is called.

seed/accounts/user_group.py (4)

9-9: LGTM!

The new imports for init_resource and require_context_id from seed.helper align with the standardized seeding pattern used across other account modules.


14-29: LGTM!

The refactor to use require_context_id for fetching account_id and module_id provides consistent error handling with clear context about which resource is missing. This matches the pattern in build_api_token_data and build_buyer_data.


32-39: LGTM!

The rename from init_user_group to create_user_group with a simplified return type (UserGroup instead of UserGroup | None) provides clearer semantics. The "get-or-create" logic is now handled by init_resource.


42-46: LGTM!

The seed_user_group function now uses the init_resource pattern, consistent with other seed functions like seed_api_token, seed_buyer, and seed_seller.

tests/seed/accounts/test_licensee.py (2)

8-14: Fixture and data-shape expectations look consistent with licensee builder

The context_with_data fixture and test_build_licensee_data expectations line up with build_licensee_data’s use of accounts.client_account.id, accounts.seller.id, accounts.buyer.id, and accounts.user_group.id. This should give good confidence the new context-driven wiring behaves as intended.

Also applies to: 17-40


43-59: Remove unused # noqa: WPS218 to satisfy Ruff

Ruff reports the # noqa: WPS218 on Line 43 as unused. Since this rule is no longer being triggered for test_create_licensee, the directive should be dropped.

-async def test_create_licensee(mocker, client_client, context_with_data):  # noqa: WPS218
+async def test_create_licensee(mocker, client_client, context_with_data):
⛔ Skipped due to learnings
Learnt from: jentyk
Repo: softwareone-platform/mpt-api-python-client PR: 136
File: tests/e2e/notifications/subscribers/conftest.py:14-25
Timestamp: 2025-12-01T10:48:52.586Z
Learning: The repository softwareone-platform/mpt-api-python-client uses wemake-python-styleguide linter, so noqa directives for WPS rules should not be flagged as unused.
tests/seed/accounts/test_api_token.py (3)

12-28: Context fixture and test_build_api_token_data correctly reflect new context-based IDs

The context_with_data fixture and expected_data in test_build_api_token_data align with build_api_token_data’s use of accounts.client_account.id and accounts.module.id. This looks correct and keeps the tests close to the seeding contract.


33-47: test_create_api_token thoroughly validates the create payload

The AsyncMock wiring and payload assertions ensure create_api_token passes the expected account and module IDs into mpt_ops.accounts.api_tokens.create, which should catch regressions in the new create-based flow.


49-56: test_seed_api_token correctly asserts init_resource wiring

Patching seed.accounts.api_tokens.init_resource and asserting it is called once with "accounts.api_token.id" and create_api_token neatly validates the new init_resource-based seeding behavior.

seed/accounts/buyer.py (3)

9-9: Context-driven buyer data construction looks correct

Switching build_buyer_data to use require_context_id for accounts.client_account.id and accounts.seller.id matches the new seeding convention and yields a payload shape consistent with the Buyer API.

Also applies to: 16-37


40-50: create_buyer implementation matches the new create+ICON pattern

Using build_buyer_data(context=context) with the injected Context and mpt_operations, and passing ICON.open("rb") into buyers.create, is consistent with the other account seeding flows and keeps the creation path straightforward.


52-56: seed_buyer correctly delegates to init_resource

seed_buyer now defers to init_resource("accounts.buyer.id", create_buyer), which aligns with the shared seeding helper and should ensure the buyer is created on demand and cached in the context.

@robcsegal robcsegal force-pushed the MPT-16315-update-account-seeding-to-latest-convention branch from 22c94cf to 54a00af Compare December 10, 2025 00:08
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: 2

🧹 Nitpick comments (4)
tests/seed/accounts/test_buyer.py (1)

58-65: Consider verifying init_resource arguments for more robust test coverage.

The test only asserts that init_resource was awaited once but doesn't verify the namespace or factory function passed. This could miss bugs where the wrong namespace or factory is used.

 async def test_seed_buyer(mocker):
     mock_init_resource = mocker.patch(
         "seed.accounts.buyer.init_resource", new_callable=mocker.AsyncMock
     )

     await seed_buyer()

-    mock_init_resource.assert_awaited_once()
+    mock_init_resource.assert_awaited_once_with("accounts.buyer.id", create_buyer)
seed/accounts/licensee.py (1)

16-16: Remove unused noqa directive.

Static analysis (Ruff) indicates the noqa: WPS238 directive is no longer needed.

-def build_licensee_data(  # noqa: WPS238
+def build_licensee_data(
     context: Context = Provide[Container.context],
 ) -> dict[str, object]:
tests/seed/accounts/test_licensee.py (1)

62-69: Consider validating init_resource arguments.

Unlike similar tests in test_api_token.py and test_user_group.py, this test only verifies that init_resource was called but doesn't validate the arguments (namespace and factory function). Consider adding argument validation for consistency.

     await seed_licensee()

-    mock_init_resource.assert_awaited_once()
+    mock_init_resource.assert_awaited_once_with("accounts.licensee.id", create_licensee)
tests/seed/accounts/test_user_group.py (1)

51-58: Consider validating init_resource arguments.

Similar to test_seed_licensee, this test only verifies that init_resource was called but doesn't validate the arguments. For consistency with test_seed_api_token, consider adding argument validation.

     await seed_user_group()

-    mock_init_resource.assert_awaited_once()
+    mock_init_resource.assert_awaited_once_with("accounts.user_group.id", create_user_group)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22c94cf and 54a00af.

📒 Files selected for processing (26)
  • e2e_config.test.json (1 hunks)
  • mpt_api_client/resources/accounts/account.py (2 hunks)
  • mpt_api_client/resources/accounts/buyers.py (2 hunks)
  • mpt_api_client/resources/accounts/licensees.py (2 hunks)
  • seed/accounts/account.py (1 hunks)
  • seed/accounts/accounts.py (2 hunks)
  • seed/accounts/api_tokens.py (2 hunks)
  • seed/accounts/buyer.py (2 hunks)
  • seed/accounts/licensee.py (2 hunks)
  • seed/accounts/module.py (1 hunks)
  • seed/accounts/seller.py (2 hunks)
  • seed/accounts/user_group.py (2 hunks)
  • tests/e2e/accounts/buyers/conftest.py (1 hunks)
  • tests/e2e/accounts/buyers/test_async_buyers.py (3 hunks)
  • tests/e2e/accounts/buyers/test_sync_buyers.py (2 hunks)
  • tests/e2e/accounts/licensees/conftest.py (2 hunks)
  • tests/e2e/catalog/pricing_policies/conftest.py (1 hunks)
  • tests/e2e/conftest.py (1 hunks)
  • tests/seed/accounts/test_account.py (1 hunks)
  • tests/seed/accounts/test_accounts.py (2 hunks)
  • tests/seed/accounts/test_api_token.py (1 hunks)
  • tests/seed/accounts/test_buyer.py (2 hunks)
  • tests/seed/accounts/test_licensee.py (2 hunks)
  • tests/seed/accounts/test_module.py (3 hunks)
  • tests/seed/accounts/test_seller.py (2 hunks)
  • tests/seed/accounts/test_user_group.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • e2e_config.test.json
  • tests/e2e/catalog/pricing_policies/conftest.py
  • tests/e2e/conftest.py
  • mpt_api_client/resources/accounts/account.py
  • tests/e2e/accounts/buyers/conftest.py
  • tests/seed/accounts/test_account.py
🧰 Additional context used
🧠 Learnings (1)
📚 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/e2e/accounts/buyers/test_async_buyers.py
🧬 Code graph analysis (15)
tests/seed/accounts/test_user_group.py (3)
seed/accounts/user_group.py (2)
  • create_user_group (33-39)
  • build_user_group_data (15-29)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_module.py (1)
  • context_with_data (23-26)
seed/accounts/seller.py (2)
seed/helper.py (1)
  • init_resource (44-84)
mpt_api_client/resources/accounts/sellers.py (1)
  • Seller (13-14)
tests/e2e/accounts/licensees/conftest.py (2)
tests/e2e/conftest.py (3)
  • seller_id (132-133)
  • buyer_id (137-138)
  • client_account_id (127-128)
tests/e2e/accounts/conftest.py (1)
  • user_group_factory (45-60)
tests/seed/accounts/test_seller.py (3)
seed/accounts/seller.py (3)
  • build_seller_data (14-29)
  • create_seller (33-38)
  • seed_seller (41-45)
tests/seed/conftest.py (2)
  • context (14-15)
  • operations_client (24-25)
seed/context.py (1)
  • Context (12-33)
seed/accounts/api_tokens.py (2)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
mpt_api_client/resources/accounts/buyers.py (2)
mpt_api_client/http/mixins.py (4)
  • CreateFileMixin (115-144)
  • UpdateFileMixin (147-184)
  • AsyncCreateFileMixin (187-216)
  • AsyncUpdateFileMixin (219-256)
mpt_api_client/resources/catalog/mixins.py (2)
  • ActivatableMixin (109-132)
  • AsyncActivatableMixin (135-160)
seed/accounts/user_group.py (2)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_api_token.py (2)
seed/accounts/api_tokens.py (3)
  • create_api_token (31-38)
  • seed_api_token (41-45)
  • build_api_token_data (15-27)
seed/context.py (1)
  • Context (12-33)
seed/accounts/module.py (4)
seed/helper.py (1)
  • init_resource (44-84)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/resources/accounts/modules.py (1)
  • Module (11-12)
tests/e2e/accounts/buyers/test_sync_buyers.py (3)
tests/e2e/conftest.py (2)
  • client_account_id (127-128)
  • account_id (122-123)
tests/e2e/accounts/buyers/conftest.py (2)
  • buyer_factory (10-34)
  • invalid_buyer_id (5-6)
tests/e2e/accounts/conftest.py (1)
  • account_icon (20-21)
seed/accounts/buyer.py (4)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/mpt_client.py (1)
  • AsyncMPTClient (20-71)
seed/accounts/licensee.py (2)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/accounts/accounts.py (1)
seed/accounts/account.py (1)
  • seed_account_ids (34-39)
mpt_api_client/resources/accounts/licensees.py (2)
mpt_api_client/http/mixins.py (4)
  • CreateFileMixin (115-144)
  • UpdateFileMixin (147-184)
  • AsyncCreateFileMixin (187-216)
  • AsyncUpdateFileMixin (219-256)
mpt_api_client/resources/accounts/mixins.py (2)
  • EnablableMixin (30-53)
  • AsyncEnablableMixin (162-185)
seed/accounts/account.py (4)
mpt_api_client/resources/accounts/account.py (1)
  • Account (27-28)
seed/container.py (1)
  • Container (7-30)
seed/context.py (1)
  • Context (12-33)
seed/helper.py (1)
  • init_resource (44-84)
🪛 Ruff (0.14.8)
tests/seed/accounts/test_licensee.py

43-43: Unused noqa directive (unknown: WPS218)

Remove unused noqa directive

(RUF100)

seed/accounts/licensee.py

16-16: Unused noqa directive (unknown: WPS238)

Remove unused noqa directive

(RUF100)

seed/accounts/accounts.py

14-14: Unused noqa directive (unknown: WPS217, WPS213)

Remove unused noqa directive

(RUF100)

seed/accounts/account.py

15-15: Unused noqa directive (non-enabled: RUF029)

Remove unused noqa directive

(RUF100)


19-19: Avoid specifying long messages outside the exception class

(TRY003)


25-25: Unused noqa directive (non-enabled: RUF029)

Remove unused noqa directive

(RUF100)


29-29: Avoid specifying long messages outside the exception class

(TRY003)

⏰ 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 (38)
mpt_api_client/resources/accounts/licensees.py (2)

36-38: LGTM! Type parameter tightening improves type safety.

Narrowing the generic type parameters from Model to Licensee for CreateFileMixin, UpdateFileMixin, and EnablableMixin provides better type inference for callers. Methods like create(), update(), enable(), and disable() will now return Licensee instead of the more generic Model, improving IDE support and type checking.


49-51: LGTM! Async mixins updated consistently.

The async service mixins mirror the synchronous service changes, ensuring consistent type safety across both synchronous and asynchronous API surfaces. This completes the pattern by aligning all mixins with the specific Licensee type.

tests/e2e/accounts/licensees/conftest.py (1)

15-34: LGTM! Consistent naming refactor.

The parameter rename from licensee_account_id to client_account_id is consistently applied throughout the fixture and aligns with the broader PR changes.

tests/seed/accounts/test_accounts.py (1)

5-7: LGTM! Proper test coverage for new seed function.

The test correctly patches and asserts seed_account_ids is invoked during the seed_accounts() flow, following the same pattern as the existing seed function mocks.

Also applies to: 28-28

tests/seed/accounts/test_seller.py (1)

3-3: LGTM! Tests properly validate the refactored seller seeding.

The tests correctly validate both the create_seller function (payload structure and API call) and the seed_seller orchestration through init_resource. The new context_without_data fixture is defined but unused in the current tests—this is acceptable if it's intended for future use or other test modules.

Also applies to: 8-9, 32-53

tests/seed/accounts/test_module.py (1)

4-4: LGTM! Tests properly validate the refactored module seeding.

The addition of context_with_data fixture and the updates to both test functions correctly validate the refactored module seeding flow that relies on context-based IDs and init_resource orchestration.

Also applies to: 22-27, 43-44, 54-54, 58-65

seed/accounts/module.py (1)

10-10: LGTM! Refactoring addresses previous feedback.

The module seeding has been properly refactored:

  • refresh_module now directly filters and fetches the module, storing its ID in context
  • seed_module return type has been corrected to -> None (addressing the previous review comment)
  • The seed orchestration properly uses init_resource

Also applies to: 16-31, 34-38

seed/accounts/account.py (1)

34-39: LGTM! Proper account ID seeding orchestration.

The function correctly orchestrates the initialization of both vendor and client account IDs through init_resource, with appropriate logging.

seed/accounts/user_group.py (1)

9-9: LGTM! Consistent refactor to context-based ID sourcing.

The refactoring properly transitions from environment-based to context-based ID retrieval using require_context_id. The function rename from init_user_group to create_user_group better reflects its creation-only semantics, and the tightened return types (UserGroup instead of UserGroup | None) improve type safety. These changes align with the broader seeding refactor pattern across the PR.

Also applies to: 19-20, 33-39, 42-46

seed/accounts/accounts.py (1)

3-3: LGTM! The noqa directive is necessary.

The addition of seed_account_ids() at the start of the seeding flow is appropriate, ensuring account IDs are available for dependent seeds.

The noqa: WPS217, WPS213 directive on line 14 is correctly used. The repository uses wemake-python-styleguide, and these WPS rules are active for this file (they are not disabled in the per-file-ignores configuration for seed/accounts/*.py). The directive should be kept as-is.

tests/seed/accounts/test_buyer.py (2)

7-12: LGTM!

The context_with_data fixture correctly populates the required context keys (accounts.client_account.id and accounts.seller.id) needed by build_buyer_data.


41-55: LGTM!

The test properly mocks the create method, invokes create_buyer, and verifies both the return value and key payload fields.

seed/accounts/licensee.py (2)

20-23: LGTM!

The use of require_context_id for all four dependencies (client_account, seller, buyer, user_group) ensures clear error messages if any prerequisite resource is missing.


48-57: LGTM!

The create_licensee function follows the same pattern as other create functions, properly building data and creating the resource with an icon file.

tests/e2e/accounts/buyers/test_sync_buyers.py (2)

9-14: LGTM!

The fixture correctly uses the renamed client_account_id parameter, aligning with the broader refactor of account naming conventions.


78-91: LGTM!

The test functions consistently use client_account_id throughout, maintaining alignment with the renamed fixtures and the PR's naming convention changes.

seed/accounts/seller.py (2)

32-38: LGTM!

The create_seller function is correctly simplified since sellers don't depend on other seeded resources. The self-contained data generation via build_seller_data() with UUID-based externalId is appropriate.


41-45: LGTM!

The seed_seller function correctly uses init_resource with the appropriate namespace, following the new seeding pattern.

seed/accounts/buyer.py (3)

15-37: LGTM!

The build_buyer_data function correctly uses require_context_id to fetch both client_account_id and seller_id from context, ensuring proper error handling if prerequisites are missing.


40-49: LGTM!

The create_buyer function follows the established pattern: building data with context, then creating via API with the icon file.


52-56: LGTM!

The seed_buyer function correctly delegates to init_resource with the accounts.buyer.id namespace.

mpt_api_client/resources/accounts/buyers.py (2)

40-51: LGTM!

Tightening the generic type parameters from Model to Buyer improves type safety. Methods from these mixins will now correctly return Buyer instances instead of the generic Model type.


73-84: LGTM!

The async service class receives the same type parameter improvements, ensuring consistent type safety across both sync and async APIs.

tests/seed/accounts/test_api_token.py (4)

11-16: LGTM!

The context fixture provides appropriate test data for validating the API token creation flow.


19-30: LGTM!

The test correctly validates that build_api_token_data constructs the expected payload structure with IDs from context.


33-47: LGTM!

The test thoroughly validates both the return value and the payload structure sent to the API, ensuring that IDs are correctly sourced from the context.


49-56: LGTM!

The test correctly validates that seed_api_token delegates to init_resource with the appropriate namespace and factory function.

tests/seed/accounts/test_licensee.py (3)

7-14: LGTM!

The fixture provides comprehensive test data for licensee creation, including all required account-related IDs.


17-40: LGTM!

The test thoroughly validates the licensee payload structure, ensuring all fields including seller, buyer, account, and groups are correctly populated from context.


44-59: LGTM!

The test comprehensively validates the licensee creation, checking both the return value and the payload structure with all required IDs.

tests/e2e/accounts/buyers/test_async_buyers.py (1)

10-14: LGTM!

The rename from buyer_account_id to client_account_id is consistently applied across all occurrences, aligning with the PR's objective to standardize account identifier naming.

Also applies to: 81-84, 94-97

tests/seed/accounts/test_user_group.py (3)

12-16: LGTM!

The context fixture appropriately provides test data for user group creation validation.


19-31: LGTM!

The test correctly validates that build_user_group_data constructs the expected payload with IDs sourced from context.


34-49: LGTM!

The test comprehensively validates both the return value and the payload structure, ensuring IDs are correctly sourced from context.

seed/accounts/api_tokens.py (4)

9-9: LGTM!

The imports correctly bring in the helper functions needed for the new context-based resource initialization pattern.


14-27: LGTM!

The function correctly uses require_context_id to ensure required IDs are present in context, providing clear error messages if dependencies are missing. The key names align with the PR's standardization of account identifier naming.


30-38: LGTM!

The function has a clean implementation following the create-only pattern. It correctly delegates payload construction to build_api_token_data and returns the created API token.


40-45: LGTM!

The seeding function correctly uses init_resource to manage resource creation and ID caching, ensuring the API token is created only when needed.

@robcsegal robcsegal force-pushed the MPT-16315-update-account-seeding-to-latest-convention branch 2 times, most recently from 01597b4 to b3543dd Compare December 10, 2025 13:46
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

♻️ Duplicate comments (1)
seed/accounts/account.py (1)

14-20: Cleanup unused context parameter / noqa and align with Ruff

init_account_id() never uses context, so Ruff reports ARG001 and the # noqa: RUF029 is also flagged as unused (RUF100). Either start using context here, or remove the parameter and the noqa to keep the signature minimal and satisfy linting. If your local Ruff config still requires RUF029 suppression while CI doesn’t, it’d be good to reconcile the configs so this pattern is consistent across the repo.

🧹 Nitpick comments (9)
seed/accounts/module.py (1)

23-27: Redundant context assignment.

refresh_module stores the module ID in context["accounts.module.id"] at line 26, but init_resource (from seed/helper.py lines 79-80) also stores the returned value under the same namespace. This results in the ID being written twice.

Consider returning just the module and letting init_resource handle the context storage:

     if modules:
         first_module = modules[0]
         if isinstance(first_module, Module):
-            context["accounts.module.id"] = first_module.id
             return first_module
         logger.warning("First module is not a Module instance.")
         return None
tests/seed/accounts/test_buyer.py (1)

58-65: Consider verifying init_resource arguments.

The test only asserts that init_resource was awaited once but doesn't verify the namespace or factory function. This could miss regressions if the namespace changes.

     await seed_buyer()

-    mock_init_resource.assert_awaited_once()
+    mock_init_resource.assert_awaited_once_with("accounts.buyer.id", create_buyer)
tests/seed/accounts/test_licensee.py (1)

62-69: Consider verifying init_resource arguments for consistency.

Similar to the buyer test, verifying the namespace and factory function would make the test more robust.

     await seed_licensee()

-    mock_init_resource.assert_awaited_once()
+    mock_init_resource.assert_awaited_once_with("accounts.licensee.id", create_licensee)
seed/accounts/licensee.py (1)

62-64: Inconsistent logging level.

seed_licensee uses logger.info for completion (line 64) while other seed functions in this PR use logger.debug for both start and completion messages. Consider aligning for consistency.

     logger.debug("Seeding licensee ...")
     await init_resource("accounts.licensee.id", create_licensee)
-    logger.info("Seeding licensee completed.")
+    logger.debug("Seeding licensee completed.")
seed/accounts/seller.py (1)

32-38: Confirm create-only seller seeding semantics

create_seller() is now a pure create factory and seed_seller() delegates to init_resource("accounts.seller.id", create_seller), so each time the seeding context is fresh you’ll create a new Seller (no lookup by externalId). That’s fine if the target environment is ephemeral, but in a long-lived environment this can accumulate many seeded sellers. If you want idempotent behavior per external ID, consider a get-or-create path keyed by externalId instead.

Also applies to: 41-45

seed/accounts/account.py (1)

23-38: Minor polish for seeding log message and duplication

seed_account_ids() seeds three IDs (vendor, client, operations) but the log message on Line 25 only mentions “Seeding vendor account ...”. Consider either broadening the wording (e.g., “Seeding account IDs ...”) or adding separate log lines per ID. You could also DRY the three init_resource calls via a small loop over (namespace, env_var) pairs to reduce repetition.

tests/seed/accounts/test_module.py (2)

22-27: Strengthen refresh_module test by asserting context mutation

refresh_module()’s main responsibility is to both return the module and set "accounts.module.id" in the provided Context. test_refresh_module() currently only asserts the return value. Consider also asserting that context_with_data["accounts.module.id"] is updated to module.id after the call, so regressions in the context‑write behavior are caught. The mocked modules_service.refresh assignment is also unused and can be removed.

Also applies to: 43-55


58-65: Tighten seed_module test to verify init_resource arguments

test_seed_module() only checks that init_resource was awaited once. To better guard against regressions, assert the exact call, e.g. mock_init_resource.assert_awaited_once_with("accounts.module.id", refresh_module) so a wrong namespace or factory won’t silently pass.

seed/accounts/api_tokens.py (1)

30-45: Confirm create-only API token seeding behavior

create_api_token() is a pure create factory and seed_api_token() now delegates to init_resource("accounts.api_token.id", create_api_token). As with the seller flow, this will create a new token whenever seeding runs with a fresh Context; over time that can accumulate many API tokens in a persistent environment. If you expect to rerun seeding regularly against the same account/module, consider whether a get-or-create strategy (or periodic cleanup) is preferable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54a00af and 01597b4.

📒 Files selected for processing (27)
  • e2e_config.test.json (1 hunks)
  • mpt_api_client/resources/accounts/account.py (2 hunks)
  • mpt_api_client/resources/accounts/buyers.py (2 hunks)
  • mpt_api_client/resources/accounts/licensees.py (2 hunks)
  • seed/accounts/account.py (1 hunks)
  • seed/accounts/accounts.py (2 hunks)
  • seed/accounts/api_tokens.py (2 hunks)
  • seed/accounts/buyer.py (2 hunks)
  • seed/accounts/licensee.py (2 hunks)
  • seed/accounts/module.py (1 hunks)
  • seed/accounts/seller.py (2 hunks)
  • seed/accounts/user_group.py (2 hunks)
  • seed/helper.py (1 hunks)
  • tests/e2e/accounts/buyers/conftest.py (1 hunks)
  • tests/e2e/accounts/buyers/test_async_buyers.py (3 hunks)
  • tests/e2e/accounts/buyers/test_sync_buyers.py (2 hunks)
  • tests/e2e/accounts/licensees/conftest.py (2 hunks)
  • tests/e2e/catalog/pricing_policies/conftest.py (1 hunks)
  • tests/e2e/conftest.py (1 hunks)
  • tests/seed/accounts/test_account.py (1 hunks)
  • tests/seed/accounts/test_accounts.py (2 hunks)
  • tests/seed/accounts/test_api_token.py (1 hunks)
  • tests/seed/accounts/test_buyer.py (2 hunks)
  • tests/seed/accounts/test_licensee.py (2 hunks)
  • tests/seed/accounts/test_module.py (3 hunks)
  • tests/seed/accounts/test_seller.py (2 hunks)
  • tests/seed/accounts/test_user_group.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • mpt_api_client/resources/accounts/account.py
  • tests/seed/accounts/test_user_group.py
  • tests/e2e/conftest.py
  • seed/accounts/buyer.py
  • tests/seed/accounts/test_api_token.py
  • tests/e2e/accounts/buyers/conftest.py
  • tests/e2e/accounts/buyers/test_sync_buyers.py
  • tests/e2e/accounts/buyers/test_async_buyers.py
  • tests/seed/accounts/test_accounts.py
  • mpt_api_client/resources/accounts/licensees.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-01T10:48:52.586Z
Learnt from: jentyk
Repo: softwareone-platform/mpt-api-python-client PR: 136
File: tests/e2e/notifications/subscribers/conftest.py:14-25
Timestamp: 2025-12-01T10:48:52.586Z
Learning: The repository softwareone-platform/mpt-api-python-client uses wemake-python-styleguide linter, so noqa directives for WPS rules should not be flagged as unused.

Applied to files:

  • tests/seed/accounts/test_licensee.py
🧬 Code graph analysis (9)
tests/e2e/accounts/licensees/conftest.py (2)
tests/e2e/conftest.py (3)
  • seller_id (132-133)
  • buyer_id (137-138)
  • client_account_id (127-128)
tests/e2e/accounts/conftest.py (1)
  • user_group_factory (45-60)
seed/helper.py (1)
mpt_api_client/models/model.py (1)
  • id (119-121)
seed/accounts/user_group.py (3)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
mpt_api_client/resources/accounts/user_groups.py (1)
  • UserGroup (11-12)
seed/accounts/module.py (4)
seed/helper.py (1)
  • init_resource (44-84)
seed/context.py (1)
  • Context (12-33)
mpt_api_client/resources/accounts/modules.py (1)
  • Module (11-12)
mpt_api_client/models/model.py (1)
  • id (119-121)
tests/seed/accounts/test_module.py (4)
seed/accounts/module.py (2)
  • refresh_module (16-31)
  • seed_module (34-38)
tests/seed/accounts/test_user_group.py (1)
  • context_with_data (12-16)
seed/context.py (1)
  • Context (12-33)
tests/seed/conftest.py (2)
  • operations_client (24-25)
  • context (14-15)
tests/e2e/catalog/pricing_policies/conftest.py (1)
tests/e2e/conftest.py (2)
  • client_account_id (127-128)
  • product_id (96-97)
mpt_api_client/resources/accounts/buyers.py (2)
mpt_api_client/resources/catalog/mixins.py (2)
  • ActivatableMixin (109-132)
  • AsyncActivatableMixin (135-160)
mpt_api_client/resources/accounts/mixins.py (6)
  • ActivatableMixin (4-27)
  • EnablableMixin (30-53)
  • ValidateMixin (56-68)
  • AsyncActivatableMixin (134-159)
  • AsyncEnablableMixin (162-185)
  • AsyncValidateMixin (188-200)
tests/seed/accounts/test_account.py (5)
seed/accounts/account.py (2)
  • init_account_id (15-20)
  • seed_account_ids (23-38)
tests/seed/conftest.py (1)
  • context (14-15)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_seller.py (1)
  • context_without_data (8-9)
seed/helper.py (1)
  • init_resource (44-84)
seed/accounts/seller.py (4)
seed/helper.py (1)
  • init_resource (44-84)
mpt_api_client/mpt_client.py (1)
  • AsyncMPTClient (20-71)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/resources/accounts/sellers.py (1)
  • Seller (13-14)
🪛 Ruff (0.14.8)
seed/accounts/accounts.py

14-14: Unused noqa directive (unknown: WPS217, WPS213)

Remove unused noqa directive

(RUF100)

tests/seed/accounts/test_licensee.py

43-43: Unused noqa directive (unknown: WPS218)

Remove unused noqa directive

(RUF100)

seed/accounts/account.py

15-15: Unused function argument: context

(ARG001)


15-15: Unused noqa directive (non-enabled: RUF029)

Remove unused noqa directive

(RUF100)


19-19: Avoid specifying long messages outside the exception class

(TRY003)

seed/accounts/licensee.py

16-16: Unused noqa directive (unknown: WPS238)

Remove unused noqa directive

(RUF100)

🔇 Additional comments (22)
e2e_config.test.json (1)

4-4: LGTM - Config rename aligns with client_account refactoring.

The key rename from accounts.buyer.account.id to accounts.client_account.id is consistent with the broader refactoring to standardize account identification terminology across the codebase.

tests/e2e/catalog/pricing_policies/conftest.py (1)

7-11: LGTM - Parameter rename consistent with refactoring.

The parameter rename from buyer_account_id to client_account_id correctly propagates through the fixture signature and payload construction. The fixture dependency is properly defined in tests/e2e/conftest.py.

tests/e2e/accounts/licensees/conftest.py (1)

15-34: LGTM - Consistent licensee fixture refactoring.

The fixture correctly replaces licensee_account_id with client_account_id throughout the function signature, user_group_factory call, and account payload. All references are properly updated.

mpt_api_client/resources/accounts/buyers.py (2)

41-45: LGTM - Improved type safety with concrete Buyer type.

Tightening the mixin type parameters from Model to Buyer improves type safety and provides better IDE support. The mixins' _resource_action calls will now return the more specific Buyer type instead of the generic Model.


74-78: LGTM - Async mixins consistently typed.

The async service mixins are correctly updated with the same type parameter changes as the sync version, maintaining consistency across the codebase.

seed/helper.py (1)

82-82: LGTM - Flexible resource ID extraction.

The enhancement to handle both string IDs and objects with an id attribute is a sensible generalization that maintains backward compatibility while adding flexibility. The isinstance check correctly handles both cases, and the docstring appropriately documents the expected behavior.

tests/seed/accounts/test_account.py (3)

7-9: LGTM - Clean test fixture.

The context_without_data fixture provides a clean Context instance for testing account initialization in isolation.


12-23: LGTM - Comprehensive environment variable testing.

The parametrized test correctly verifies that init_account_id retrieves account IDs from environment variables for all three account types (VENDOR, CLIENT, OPERATIONS). The test uses appropriate pytest patterns.


26-36: LGTM - Proper seeding verification.

The test correctly mocks init_resource and verifies that seed_account_ids initializes all three account ID types. The use of assert_any_call appropriately validates the expected namespace arguments.

seed/accounts/accounts.py (4)

3-3: LGTM - Import correctly added.

The import for seed_account_ids is properly added and used at line 18.


14-14: Static analysis false positive - noqa codes are valid for wemake-python-styleguide.

The Ruff warning about unknown noqa codes is a false positive. The WPS217 and WPS213 codes are from the wemake-python-styleguide linter, not Ruff. If your project uses wemake, these directives are appropriate.


18-18: LGTM - Account IDs seeded first.

Calling seed_account_ids() before other seeding functions is correct, as downstream entities depend on these account IDs being available in the context.


27-27: LGTM - Completion logging added.

The completion log message provides clear feedback that the seeding process has finished, complementing the opening log at line 16.

tests/seed/accounts/test_seller.py (4)

3-9: LGTM - Imports and fixture updated for new API.

The imports correctly reflect the new create_seller API surface, and the context_without_data fixture provides a clean testing environment consistent with other test files.


12-29: LGTM - Existing test unchanged.

The test_build_seller_data test correctly validates the seller data payload structure and remains unchanged.


32-43: LGTM - Comprehensive create_seller test.

The test properly validates both the return value and payload structure of create_seller. The mock assertion correctly extracts and verifies that the payload contains the expected seller name.


46-53: LGTM - Seeding test updated for init_resource pattern.

The test correctly verifies that seed_seller delegates to init_resource, aligning with the new generalized seeding approach. The async mock and assertion are properly configured.

tests/seed/accounts/test_licensee.py (1)

43-43: noqa: WPS218 is intentional.

Based on learnings, the repository uses wemake-python-styleguide, and WPS218 suppresses "too many assert statements". Ruff doesn't recognize WPS-specific directives, making this a false positive.

seed/accounts/user_group.py (1)

14-46: Clean refactor to create-only flow.

The changes correctly implement the unified seeding pattern:

  • require_context_id validates required dependencies upfront
  • create_user_group has clear create-only semantics
  • seed_user_group properly delegates to init_resource

This aligns well with the broader PR pattern.

seed/accounts/licensee.py (2)

16-16: noqa: WPS238 directive.

Based on learnings, the repository uses wemake-python-styleguide. WPS238 flags "too many expressions" in a function. Given the function builds a large dictionary, this suppression is likely intentional.


48-57: LGTM on create_licensee implementation.

Clean implementation using context manager for the icon file and properly delegating data building to build_licensee_data.

seed/accounts/api_tokens.py (1)

14-27: Context‑driven API token payload looks solid

Using require_context_id for both accounts.client_account.id and accounts.module.id gives clear, early failures if prerequisites weren’t seeded, and keeps build_api_token_data() focused on payload construction. This aligns well with the new context‑first seeding approach.

@robcsegal robcsegal force-pushed the MPT-16315-update-account-seeding-to-latest-convention branch from b3543dd to 6b782e6 Compare December 10, 2025 13:51
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: 3

🧹 Nitpick comments (4)
seed/accounts/account.py (2)

14-20: Consider using context or removing it if unnecessary.

The context parameter is injected but never used in the function body. If it's intentionally unused (kept for DI wiring consistency), consider prefixing with underscore (_context) to indicate intent and silence ARG001.

 @inject
-async def init_account_id(env_var: str, context: Context = Provide[Container.context]) -> str:  # noqa: RUF029
+async def init_account_id(env_var: str, _context: Context = Provide[Container.context]) -> str:  # noqa: RUF029

23-38: Consider improving log message clarity.

The initial log says "Seeding vendor account" but the function seeds vendor, client, and operations accounts. Consider updating to reflect the full scope:

 async def seed_account_ids() -> None:
-    """Seed account."""
-    logger.debug("Seeding vendor account ...")
+    """Seed account IDs from environment variables."""
+    logger.debug("Seeding account IDs ...")
tests/seed/accounts/test_user_group.py (1)

12-16: Solid coverage of user group build/create/seed flow; consider tightening the seed assertion

The fixture and tests nicely validate that:

  • build_user_group_data pulls IDs from context_with_data.
  • create_user_group forwards those IDs into the payload sent to accounts.user_groups.create.
  • seed_user_group delegates to init_resource.

If you want stricter guarantees, you could also assert the exact arguments used when seeding:

mock_init_resource.assert_awaited_once_with(
    "accounts.user_group.id",
    create_user_group,
)

Also applies to: 19-31, 34-49, 52-58

tests/seed/accounts/test_module.py (1)

22-27: Tests exercise the new module flow; you can simplify mocks and strengthen assertions

The updated tests correctly:

  • Use context_with_data when calling refresh_module.
  • Mock the modules filter/iterate chain to return a Module.
  • Verify that seed_module awaits init_resource.

Two small optional tweaks:

  • In test_refresh_module, modules_service.refresh is mocked but never used by refresh_module; you can drop that mock to reduce noise.
  • You might also assert that context_with_data["accounts.module.id"] was updated, to validate the side effect.
  • In test_seed_module, consider asserting the arguments as well:
mock_init_resource.assert_awaited_once_with(
    "accounts.module.id",
    refresh_module,
)

Also applies to: 43-55, 58-65

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01597b4 and 6b782e6.

📒 Files selected for processing (24)
  • e2e_config.test.json (1 hunks)
  • seed/accounts/account.py (1 hunks)
  • seed/accounts/accounts.py (2 hunks)
  • seed/accounts/api_tokens.py (2 hunks)
  • seed/accounts/buyer.py (2 hunks)
  • seed/accounts/licensee.py (2 hunks)
  • seed/accounts/module.py (1 hunks)
  • seed/accounts/seller.py (2 hunks)
  • seed/accounts/user_group.py (2 hunks)
  • seed/helper.py (1 hunks)
  • tests/e2e/accounts/buyers/conftest.py (1 hunks)
  • tests/e2e/accounts/buyers/test_async_buyers.py (3 hunks)
  • tests/e2e/accounts/buyers/test_sync_buyers.py (2 hunks)
  • tests/e2e/accounts/licensees/conftest.py (2 hunks)
  • tests/e2e/catalog/pricing_policies/conftest.py (1 hunks)
  • tests/e2e/conftest.py (1 hunks)
  • tests/seed/accounts/test_account.py (1 hunks)
  • tests/seed/accounts/test_accounts.py (2 hunks)
  • tests/seed/accounts/test_api_token.py (1 hunks)
  • tests/seed/accounts/test_buyer.py (2 hunks)
  • tests/seed/accounts/test_licensee.py (2 hunks)
  • tests/seed/accounts/test_module.py (3 hunks)
  • tests/seed/accounts/test_seller.py (2 hunks)
  • tests/seed/accounts/test_user_group.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • e2e_config.test.json
  • tests/seed/accounts/test_account.py
  • tests/e2e/catalog/pricing_policies/conftest.py
  • tests/e2e/accounts/licensees/conftest.py
  • tests/seed/accounts/test_accounts.py
  • tests/e2e/accounts/buyers/test_async_buyers.py
  • tests/e2e/conftest.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-01T10:48:52.586Z
Learnt from: jentyk
Repo: softwareone-platform/mpt-api-python-client PR: 136
File: tests/e2e/notifications/subscribers/conftest.py:14-25
Timestamp: 2025-12-01T10:48:52.586Z
Learning: The repository softwareone-platform/mpt-api-python-client uses wemake-python-styleguide linter, so noqa directives for WPS rules should not be flagged as unused.

Applied to files:

  • tests/seed/accounts/test_licensee.py
🧬 Code graph analysis (11)
seed/accounts/seller.py (4)
seed/helper.py (1)
  • init_resource (44-84)
mpt_api_client/mpt_client.py (1)
  • AsyncMPTClient (20-71)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/resources/accounts/sellers.py (1)
  • Seller (13-14)
tests/e2e/accounts/buyers/conftest.py (1)
tests/e2e/conftest.py (2)
  • client_account_id (127-128)
  • account_id (122-123)
tests/e2e/accounts/buyers/test_sync_buyers.py (3)
tests/e2e/conftest.py (2)
  • client_account_id (127-128)
  • account_id (122-123)
tests/e2e/accounts/buyers/conftest.py (1)
  • buyer_factory (10-34)
tests/e2e/accounts/conftest.py (1)
  • account_icon (20-21)
tests/seed/accounts/test_buyer.py (7)
seed/accounts/buyer.py (3)
  • build_buyer_data (16-37)
  • create_buyer (41-49)
  • seed_buyer (52-56)
tests/seed/conftest.py (1)
  • context (14-15)
seed/context.py (1)
  • Context (12-33)
tests/seed/accounts/test_module.py (1)
  • context_with_data (23-26)
tests/seed/accounts/test_user_group.py (1)
  • context_with_data (12-16)
tests/e2e/accounts/buyers/test_async_buyers.py (1)
  • test_create_buyer (64-67)
tests/e2e/accounts/buyers/test_sync_buyers.py (1)
  • test_create_buyer (62-65)
seed/accounts/buyer.py (4)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
mpt_api_client/resources/accounts/buyers.py (1)
  • Buyer (26-27)
tests/seed/accounts/test_seller.py (3)
seed/accounts/seller.py (3)
  • build_seller_data (14-29)
  • create_seller (33-38)
  • seed_seller (41-45)
tests/seed/conftest.py (2)
  • context (14-15)
  • operations_client (24-25)
seed/context.py (1)
  • Context (12-33)
seed/accounts/user_group.py (3)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
tests/seed/accounts/test_user_group.py (2)
seed/accounts/user_group.py (3)
  • create_user_group (33-39)
  • seed_user_group (42-46)
  • build_user_group_data (15-29)
seed/context.py (1)
  • Context (12-33)
seed/helper.py (1)
mpt_api_client/models/model.py (1)
  • id (119-121)
seed/accounts/api_tokens.py (3)
seed/helper.py (2)
  • init_resource (44-84)
  • require_context_id (23-40)
seed/context.py (1)
  • Context (12-33)
seed/container.py (1)
  • Container (7-30)
seed/accounts/account.py (4)
seed/container.py (1)
  • Container (7-30)
tests/seed/conftest.py (1)
  • context (14-15)
seed/context.py (1)
  • Context (12-33)
seed/helper.py (1)
  • init_resource (44-84)
🪛 Ruff (0.14.8)
tests/seed/accounts/test_licensee.py

43-43: Unused noqa directive (unknown: WPS218)

Remove unused noqa directive

(RUF100)

seed/accounts/licensee.py

16-16: Unused noqa directive (unknown: WPS238)

Remove unused noqa directive

(RUF100)

seed/accounts/account.py

15-15: Unused function argument: context

(ARG001)


15-15: Unused noqa directive (non-enabled: RUF029)

Remove unused noqa directive

(RUF100)


19-19: Avoid specifying long messages outside the exception class

(TRY003)

seed/accounts/accounts.py

14-14: Unused noqa directive (unknown: WPS217, WPS213)

Remove unused noqa directive

(RUF100)

⏰ 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 (20)
tests/e2e/accounts/buyers/conftest.py (1)

10-13: LGTM! Clean parameter rename to standardize naming conventions.

The fixture parameter rename from buyer_account_id to client_account_id is consistent with the fixture defined in tests/e2e/conftest.py and aligns with the broader PR objective of standardizing account naming conventions across the test suite.

tests/e2e/accounts/buyers/test_sync_buyers.py (3)

10-14: LGTM! Fixture parameter consistently updated.

The created_buyer fixture correctly uses the renamed client_account_id parameter, maintaining consistency with the updated buyer_factory fixture.


78-80: LGTM! Test function properly updated.

The test function signature and buyer_factory call are correctly updated to use client_account_id.


87-91: LGTM! Test function properly updated.

The test function signature and buyer_factory call are correctly updated to use client_account_id.

seed/helper.py (1)

81-83: LGTM! Clean dual-type handling for resource factory returns.

The isinstance check appropriately handles both string IDs (from environment variable lookups) and Model objects (from API calls), enabling unified usage of init_resource across the seeding workflow.

seed/accounts/buyer.py (2)

16-37: LGTM! Clean context-driven data construction.

The use of require_context_id for both client_account_id and seller_id ensures proper dependency ordering and clear error messages if prerequisites are missing.


40-56: LGTM! Simplified creation flow.

The create_buyer function cleanly encapsulates data building and API call with icon upload. The seed_buyer function properly delegates to init_resource for consistent resource initialization.

seed/accounts/api_tokens.py (2)

14-27: LGTM! Consistent context-driven data construction.

The build_api_token_data function properly uses require_context_id for both account_id and module_id, ensuring dependencies are validated before token creation.


30-45: LGTM! Clean API token creation flow.

The create_api_token function follows the same pattern as other seed modules, and seed_api_token properly delegates to init_resource.

seed/accounts/accounts.py (1)

14-27: LGTM! Correct seeding orchestration with proper dependency ordering.

The seed_account_ids() call at the beginning ensures account IDs are populated before dependent resources are seeded. The sequence correctly respects dependencies: accounts → seller → buyer → module → api_token → user_group → licensee.

tests/seed/accounts/test_seller.py (1)

32-53: LGTM! Good test coverage for the refactored seller flow.

The test_create_seller properly verifies the payload structure, and test_seed_seller correctly validates that init_resource is invoked during seeding.

tests/seed/accounts/test_licensee.py (2)

7-14: LGTM! Comprehensive fixture setup.

The context_with_data fixture correctly populates all required IDs (client_account, seller, buyer, user_group) needed for licensee creation.


43-69: LGTM! Thorough test coverage for licensee creation.

The test_create_licensee properly validates all key payload fields, and test_seed_licensee correctly verifies the init_resource invocation. Based on learnings, the noqa: WPS218 directive is required for wemake-python-styleguide compliance.

tests/seed/accounts/test_buyer.py (2)

7-38: LGTM! Well-structured fixture and data test.

The context_with_data fixture correctly sets up required IDs, and test_build_buyer_data validates the expected payload structure with the new client_account_id field.


41-65: LGTM! Comprehensive test coverage for buyer creation flow.

The test_create_buyer properly validates payload fields including account and seller IDs, and test_seed_buyer correctly verifies the init_resource invocation pattern.

seed/accounts/licensee.py (1)

20-23: Context-based IDs and init_resource wiring look consistent

Using require_context_id for all dependent IDs and seeding via await init_resource("accounts.licensee.id", create_licensee) matches the new convention used by other account seeders. The async factory signature and payload (including groups: [{"id": group_id}] and file upload via ICON) look correct.

Also applies to: 41-45, 49-57, 60-63

seed/accounts/module.py (1)

34-38: seed_module’s use of init_resource matches the shared seeding pattern

Changing seed_module to return None and delegate to await init_resource("accounts.module.id", refresh_module) keeps it consistent with the other seeders and centralizes caching behavior in the helper.

seed/accounts/seller.py (1)

33-38: Seller creation and seeding refactor looks correct

create_seller cleanly wraps build_seller_data and mpt_operations.accounts.sellers.create, and seed_seller now follows the shared init_resource("accounts.seller.id", create_seller) pattern. The zero-arg async factory signature aligns with init_resource expectations.

Also applies to: 41-45

seed/accounts/user_group.py (1)

15-29: User group seeding now consistently uses context-based IDs and init_resource

The switch to require_context_id for "accounts.client_account.id" and "accounts.module.id", plus the create_user_group + init_resource("accounts.user_group.id", create_user_group) wiring, aligns well with the new seeding conventions and the updated tests. No issues from a correctness standpoint.

Also applies to: 33-40, 42-45

tests/seed/accounts/test_api_token.py (1)

12-16: API token tests cleanly validate the new builder, factory, and seeding behavior

The context_with_data fixture, payload comparison in test_build_api_token_data, argument inspection in test_create_api_token, and the seed_api_token check against init_resource("accounts.api_token.id", create_api_token) together give good confidence in the new flow. No changes needed here.

Also applies to: 19-31, 33-47, 50-56

Comment on lines 7 to +9
@pytest.fixture
def seller():
return Seller({"id": "SEL-123", "name": "Test Seller"})


@pytest.fixture
def sellers_service(mocker):
return mocker.Mock(spec=AsyncSellersService)


async def test_get_seller(context: Context, operations_client, seller, sellers_service):
context["accounts.seller.id"] = seller.id
sellers_service.get.return_value = seller
operations_client.accounts.sellers = sellers_service

result = await get_seller(context=context, mpt_operations=operations_client)

assert result == seller
assert context.get_resource("accounts.seller", seller.id) == seller


async def test_get_seller_without_id(context: Context):
result = await get_seller(context=context)
assert result is None
def context_without_data() -> Context:
return Context()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "context_without_data" tests/

Repository: softwareone-platform/mpt-api-python-client

Length of output: 477


Remove unused fixture context_without_data.

The context_without_data fixture defined at lines 7-9 is not used by any test function in this file. It should be removed.

🤖 Prompt for AI Agents
In tests/seed/accounts/test_seller.py around lines 7 to 9, the fixture named
context_without_data is defined but unused; remove the entire fixture definition
(the @pytest.fixture decorator and the def context_without_data() -> Context:
return Context() body) from the file to eliminate dead code and any linter
warnings.

@sonarqubecloud
Copy link

@robcsegal robcsegal closed this Dec 10, 2025
@d3rky d3rky deleted the MPT-16315-update-account-seeding-to-latest-convention branch January 7, 2026 18:25
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