Skip to content

MPT-17580 Implement validation#718

Merged
jentyk merged 2 commits intomainfrom
feat/MPT-16491
Feb 3, 2026
Merged

MPT-17580 Implement validation#718
jentyk merged 2 commits intomainfrom
feat/MPT-16491

Conversation

@jentyk
Copy link
Copy Markdown
Member

@jentyk jentyk commented Jan 18, 2026

Closes MPT-17580

  • Add adobe_transfer: new Context field to hold transfer-related state during validation flows
  • Remove vendor-based filtering when processing agreement lines; compute SKUs for all lines and skip only if vendor externalId missing
  • Implement transfer validation in AddResellerChangeLinesToOrder:
    • Build order lines from transfer items (_get_order_lines_from_transfer)
    • Map and process transfer items to reseller items (_process_transfer_items, _process_transfer_item)
    • Compare order vs transfer lines with _transfer_order_lines_match and raise ERR_ADOBE_RESSELLER_CHANGE_LINES on mismatch
  • Insert GetPreviewOrder and UpdatePrices steps into validate_reseller_change pipeline; integrate price/update helpers and improved logging
  • Replace context.subscriptions usages with context.adobe_subscriptions and populate context.authorization_id, order_id, product_id, market_segment as part of transfer flow
  • Remove unused constants: TRANSFER_RESELLER_PRODUCT_ID and ERR_ADOBE_RESELLER_CHANGE_PRODUCT_NOT_CONFIGURED
  • Add and update tests/fixtures to cover transfer/reseller-change validation scenarios (new fixtures, expanded tests, and additional mocks)
  • Minor pyproject formatting adjustments and linter config tweaks

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 18, 2026

📝 Walkthrough

Walkthrough

Removes two transfer-related constants, adds an adobe_transfer field to Context, removes vendor-based filtering from agreement line processing, and significantly extends the reseller-change transfer validation flow with new helper methods, pipeline steps, context enrichment, and expanded tests and fixtures.

Changes

Cohort / File(s) Summary
Constants & Context
adobe_vipm/flows/constants.py, adobe_vipm/flows/context.py
Deleted TRANSFER_RESELLER_PRODUCT_ID and ERR_ADOBE_RESELLER_CHANGE_PRODUCT_NOT_CONFIGURED; added adobe_transfer: dict | None attribute to Context.
Agreement sync
adobe_vipm/flows/sync/agreement.py
Removed vendor-based exclusion; now attempts to read vendor externalId defensively and computes actual_sku via models.get_adobe_sku(vendor_id, get_market_segment(...)), appending valid (line, sku) pairs.
Transfer validation flow
adobe_vipm/flows/validation/transfer.py
Large refactor: enriches Context (authorization_id, order_id, product_id, market segment, etc.), adds helper methods (_get_order_lines_from_transfer, _process_transfer_items, _process_transfer_item, _transfer_order_lines_match), inserts GetPreviewOrder and UpdatePrices into pipeline, replaces context.subscriptions with context.adobe_subscriptions, improves transfer-line processing/matching and error handling, and removes the removed constant from public errors.
Tests — fixtures & mocks
tests/conftest.py, tests/flows/validation/conftest.py
Added adobe_transfer_items_factory() and changed adobe_reseller_change_preview_factory to use transfer items; added mocks/patches for update_order, get_product_items_by_skus, get_adobe_product_by_marketplace_sku, get_agreement, GetPreviewOrder, AddResellerChangeLinesToOrder, ValidateResellerChange, UpdatePrices, send_error, and get_one_time_skus.
Tests — behavior
tests/flows/validation/test_reseller_change.py, tests/flows/validation/test_transfer.py
Introduced TestValidateResellerChange with many new cases covering success, reviving, expired codes, API errors, missing subscriptions/items, line/vendor/count mismatches, deployment filtering; applied @pytest.mark.usefixtures("mock_get_agreement") widely.
Project config / lint
pyproject.toml
Formatting/spacing changes across metadata and tool.ruff sections; added WPS201 and WPS602 to per-file-ignores for transfer.py.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Jira Issue Key In Title ✅ Passed The PR title contains exactly one Jira issue key in the correct format (MPT-17580).
Test Coverage Required ✅ Passed The pull request modifies multiple code files and includes comprehensive changes to test files within the tests/ folder, meeting the pass criteria.
Single Commit Required ✅ Passed The PR contains exactly one commit (48993df) which satisfies the requirement for maintaining clean git history.

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

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (4)
  • MPT-17580: Cannot read properties of undefined (reading 'map')
  • MPT-16491: Cannot read properties of undefined (reading 'map')
  • MPT-17422: Cannot read properties of undefined (reading 'map')
  • MPT-17425: Cannot read properties of undefined (reading 'map')

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

@jentyk jentyk force-pushed the feat/MPT-16491 branch 29 times, most recently from c0bf8a7 to fb6b1cc Compare January 27, 2026 14:36
@jentyk jentyk force-pushed the feat/MPT-16491 branch 3 times, most recently from 95332a7 to 878afc0 Compare January 30, 2026 15:38
@jentyk jentyk marked this pull request as ready for review January 30, 2026 15:39
Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@adobe_vipm/flows/validation/transfer.py`:
- Around line 628-632: The if-condition that checks adobe_subscription status
uses identity comparison ("is not") which is wrong for strings; update the
condition in the transfer.py block that checks adobe_subscription and
AdobeStatus.SUBSCRIPTION_ACTIVE.value to use value inequality (!=) instead of
"is not" so the comparison reads adobe_subscription["status"] !=
AdobeStatus.SUBSCRIPTION_ACTIVE.value (keeping the same null-check order and
continue behavior).
🧹 Nitpick comments (2)
adobe_vipm/flows/helpers.py (1)

713-716: Consider explicit error handling for subscription fetch.

The get_subscriptions call is placed after the reseller_change_request succeeds but is not wrapped in its own try-except. If this call fails, the error will propagate with a generic message rather than a specific subscription-fetch error context.

This may be acceptable if subscription fetch failures should halt the flow entirely, but consider whether a more specific error message would help with debugging.

adobe_vipm/flows/validation/transfer.py (1)

649-661: Set-based comparison may incorrectly match orders with duplicate lines.

The current implementation uses sets for comparison, which loses multiplicity information. If there are duplicate (vendor, quantity) pairs, the comparison may incorrectly pass. For example:

  • Order lines: [(SKU-A, 10), (SKU-A, 10), (SKU-B, 5)]
  • Transfer lines: [(SKU-A, 10), (SKU-B, 5), (SKU-B, 5)]

Both would produce the same set {(SKU-A, 10), (SKU-B, 5)} despite representing different distributions.

If duplicate lines with identical (vendor, quantity) pairs can occur in practice, consider using collections.Counter instead:

from collections import Counter

def key(line: dict) -> tuple[str, int]:
    return (line["item"]["externalIds"]["vendor"], line["quantity"])

return Counter(map(key, order_lines)) == Counter(map(key, transfer_lines))

If duplicates are impossible by design, a clarifying comment would be helpful.

Comment thread adobe_vipm/flows/validation/transfer.py Outdated
Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@tests/flows/validation/test_reseller_change.py`:
- Around line 601-643: The error message string includes an unintended trailing
space; remove the trailing space from the f-string that raises the MPTError (the
f"No reseller item found for partial SKU '{partial_sku}' " in transfer.py) so it
becomes f"No reseller item found for partial SKU '{partial_sku}'", and then
update the test assertions in tests/flows/validation/test_reseller_change.py
(the assert checking str(exc_info.value) and the
mock_send_error.assert_called_once_with message) to expect the message without
the trailing space.
🧹 Nitpick comments (2)
adobe_vipm/flows/validation/transfer.py (2)

588-594: Clarify intent: updating order with empty lines before validation failure.

When no transfer lines and no order lines exist, calling update_order with an empty order_lines_from_transfer list effectively clears the order. If this is intentional state synchronization, consider adding a brief comment explaining why this is needed before returning a validation failure.


673-685: Consider documenting the no-duplicates assumption.

The set-based comparison works correctly under the assumption that (vendor, quantity) pairs cannot repeat within the same order. A brief comment documenting this business constraint would help future maintainers understand why Counter isn't needed here.

     `@staticmethod`
     def _transfer_order_lines_match(order_lines: list[dict], transfer_lines: list[dict]) -> bool:
-        """Compare order lines based on relevant fields only."""
+        """Compare order lines based on relevant fields only.
+        
+        Note: Uses set comparison since duplicate (vendor, quantity) pairs
+        cannot occur within the same order per business rules.
+        """
         if len(order_lines) != len(transfer_lines):
             return False

Comment thread tests/flows/validation/test_reseller_change.py Outdated
Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@adobe_vipm/flows/validation/transfer.py`:
- Around line 651-652: The error message string in transfer.py unnecessarily
includes a trailing space in the f-string assigned to error_msg; update the
f-string used where error_msg and logger.error are set (referencing variables
error_msg, partial_sku and the logger usage) to remove the trailing space so the
message becomes "No reseller item found for partial SKU '{partial_sku}'" before
calling logger.error.
🧹 Nitpick comments (1)
tests/flows/validation/test_reseller_change.py (1)

599-602: Local mock override shadows the fixture.

The test_skip_one_time_skus method creates a local mock_get_one_time_skus patch that shadows the fixture from conftest. While this works, consider using mocker.patch to modify the fixture's return value instead, or parameterize the fixture to accept return values.

♻️ Alternative approach using fixture configuration

You could modify the conftest fixture to accept a parameter:

`@pytest.fixture`
def mock_get_one_time_skus(mocker, request):
    return_value = getattr(request, 'param', [])
    return mocker.patch(
        "adobe_vipm.flows.validation.transfer.get_one_time_skus",
        return_value=return_value,
        autospec=True,
    )

Then use @pytest.mark.parametrize("mock_get_one_time_skus", [["99999999CA"]], indirect=True) on specific tests.

Comment thread adobe_vipm/flows/validation/transfer.py Outdated
@jentyk jentyk force-pushed the feat/MPT-16491 branch 2 times, most recently from d6af7b8 to 9ec1747 Compare February 2, 2026 09:57
Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@tests/flows/validation/test_reseller_change.py`:
- Around line 599-602: The inline mock patch of get_one_time_skus
(mock_get_one_time_skus) lacks autospec and should be replaced with an
autospec'd patch or, preferably, a fixture override; change the test to patch
"adobe_vipm.flows.validation.transfer.get_one_time_skus" with autospec=True (or
create a pytest fixture that yields a monkeypatch of get_one_time_skus returning
["99999999CA"] and use that fixture in tests) so the mock respects the real
function signature and follow the guideline to prefer a fixture for varying
return values.

Comment thread tests/flows/validation/test_reseller_change.py Outdated
@jentyk jentyk changed the title MPT-17422, MPT-17425 Adobe Reseller Transfer: remove fake item and use information from the transfer order MPT-17580 Implement validation Feb 2, 2026
@jentyk jentyk changed the base branch from main to feat/MPT-17580 February 2, 2026 11:31
Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@adobe_vipm/flows/sync/agreement.py`:
- Around line 567-571: The loop that appends (line, actual_sku) calls
models.get_adobe_sku for every line and will fail if
line["item"]["externalIds"]["vendor"] is missing or unmapped; update the code
around models.get_adobe_sku/get_market_segment to first check for the vendor ID,
call models.get_adobe_sku inside a try/conditional, and if vendor is missing or
the mapping returns None/raises, skip appending that line and emit a warning
(e.g., via logger.warn or the module logger) referencing the line id and
product_id so price sync continues resiliently; ensure agreement_lines only
receives tuples with a valid actual_sku.
🧹 Nitpick comments (1)
tests/flows/validation/test_reseller_change.py (1)

207-287: Add a test for upsize-line rejection in reseller-change validation.

Once the upsize guard is enforced, add a test that creates an order with an upsize line (quantity increase) and asserts validation fails with the appropriate error and no preview order is requested.

Based on learnings: Rule: In reseller transfer validation flows (validate_reseller_change), upsize lines are not allowed as a business rule, only new lines are permitted.

Comment thread adobe_vipm/flows/sync/agreement.py Outdated
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Feb 2, 2026

Copy link
Copy Markdown
Contributor

@albertsola albertsola left a comment

Choose a reason for hiding this comment

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

I would not reformat the pyproject.toml

Comment thread adobe_vipm/flows/sync/agreement.py
Comment thread adobe_vipm/flows/validation/transfer.py
Comment thread adobe_vipm/flows/validation/transfer.py
Comment thread adobe_vipm/flows/validation/transfer.py
Comment thread adobe_vipm/flows/validation/transfer.py
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.

3 participants