Skip to content

MWPW-204225: Support per-OSI promo codes for soft bundle placeholders - #1195

Open
Andrei4226 wants to merge 10 commits into
mainfrom
MWPW-204225
Open

MWPW-204225: Support per-OSI promo codes for soft bundle placeholders#1195
Andrei4226 wants to merge 10 commits into
mainfrom
MWPW-204225

Conversation

@Andrei4226

@Andrei4226 Andrei4226 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Resolves https://jira.corp.adobe.com/browse/MWPW-204225
QA Checklist: https://wiki.corp.adobe.com/display/adobedotcom/M@S+Engineering+QA+Use+Cases

Adds support for "soft bundles" to combine multiple offers (e.g. 3 OSI promo codes together) — to each have their own promo code, instead of forcing all offers in the bundle to share a single code.

Example: if a card bundles 3 offers and you want offer 1 to show "PROMO1", offer 2 to show "PROMO2" and offer 3 to show "PROMO3", you can now do that.
Before, you could only apply one promo code to the whole bundle.

Also included: a small cleanup so a promo code list like " CODE1, CODE2 " (extra spaces, stray commas) is parsed correctly instead of keeping the whitespace as part of the code.

Rules for OSI ↔ promo code pairing:

  1. 1 OSI + 1 promo code = unchanged: that code applies to that OSI.
    osi="A" promo="PROMOCODE1" --> A=PROMOCODE1

  2. Multiple OSIs + exactly 1 promo code = unchanged: broadcasts to all.
    osi="A,B,C" promo="PROMOCODE1" --> A=PROMOCODE1, B=PROMOCODE1, C=PROMOCODE1

  3. Multiple OSIs + 2+ promo codes --> paired by position (1st OSI ↔ 1st code, etc).
    osi="A,B,C" promo="PROMOCODE1,PROMOCODE2,PROMOCODE3" --> A=PROMOCODE1, B=PROMOCODE2, C=PROMOCODE3

  4. More OSIs than codes --> extra OSIs get no promo code.
    osi="A,B,C" promo="PROMOCODE1,PROMOCODE2" --> A=PROMOCODE1, B=PROMOCODE2, C=(none)

  5. More codes than OSIs --> extra codes are ignored.
    osi="A,B" promo="PROMOCODE1,PROMOCODE2,PROMOCODE3" --> A=PROMOCODE1, B=PROMOCODE2, (PROMOCODE3 ignored)

  6. A blank OSI slot drops its paired code too, so later OSIs keep their own code.
    osi="A,,C" promo="PROMOCODE1,PROMOCODE2,PROMOCODE3" --> A=PROMOCODE1, C=PROMOCODE3 (PROMOCODE2 dropped, not shifted onto C)

Test links:
Studio:

Before: https://mas.adobe.com/studio.html?ost=new#fragmentId=c075f0c7-a08d-4e42-8d45-03a5169dd877&page=fragment-editor&path=sandbox
After: https://mwpw-204225--mas--adobecom.aem.live/studio.html?ost=new#fragmentId=c075f0c7-a08d-4e42-8d45-03a5169dd877&maslibs=MWPW-204225&page=fragment-editor&path=sandbox

Preview:
Before: https://main--milo--adobecom.aem.page/merch/mas/preview?fragment-id=c075f0c7-a08d-4e42-8d45-03a5169dd877&content-type=merch-card&locale=en_US
After: https://main--milo--adobecom.aem.page/merch/mas/preview?fragment-id=c075f0c7-a08d-4e42-8d45-03a5169dd877&content-type=merch-card&locale=en_US&maslibs=MWPW-204225

Before:
image
After:
image

image (It also appears in Axel's extension)

Please do the steps below before submitting your PR for a code review or QA

  • C1. Cover code with Unit Tests
  • C2. Add a Nala test (double check with #fishbags if nala test is needed)
  • C3. Verify all Checks are green (unit tests, nala tests)
  • C4. PR description contains working Test Page link where the feature can be tested
  • C5: you are ready to do a demo from Test Page in PR (bonus: write a working demo script that you'll use on Thursday, you can eventually put in your PR)
  • C.6 read your Jira one more time to validate that you've addressed all AC's and nothing is missing

🧪 Nala E2E Tests

Nala tests run automatically when you open this PR.

To run Nala tests again:

  1. Add the run nala label to this PR (in the right sidebar)
  2. Tests will run automatically on the current commit
  3. Any future commits will also trigger tests as long as the label remains

To stop automatic Nala tests:

  • Remove the run nala label

Note: Tests only run on commits if the run nala label is present. Add the label whenever you need tests to run on new changes.

Test URLs:

@Andrei4226 Andrei4226 self-assigned this Sep 1, 2026
@aem-code-sync

aem-code-sync Bot commented Sep 1, 2026

Copy link
Copy Markdown

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-sync branch
Commits

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.77%. Comparing base (2f2e131) to head (96b2828).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1195      +/-   ##
==========================================
+ Coverage   90.71%   90.77%   +0.05%     
==========================================
  Files         318      318              
  Lines      101712   101768      +56     
==========================================
+ Hits        92271    92375     +104     
+ Misses       9441     9393      -48     
Files with missing lines Coverage Δ
web-components/src/checkout.js 100.00% <100.00%> (ø)
web-components/src/merch-card.js 89.85% <100.00%> (+<0.01%) ⬆️
web-components/src/price.js 99.33% <100.00%> (+0.02%) ⬆️
web-components/src/utilities.js 97.92% <100.00%> (+0.31%) ⬆️
web-components/src/wcs.js 97.57% <100.00%> (+0.06%) ⬆️

... and 10 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2f2e131...96b2828. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Axelcureno Axelcureno left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice, per-OSI zip is clean and the wcs tests asserting real URLs are great.

Ran your branch with osi="abm,,stock-abm" and promo="P1,P2,P3": wcsOsi comes back length 2, promotionCodes length 3, and stock-abm requests promotion_code=P2 instead of P3. toOfferSelectorIds drops blanks, toPromotionCodes keeps them, and wcs zips by index. Worth pairing before filtering.

Nit: promotionCodes holds undefined entries where the JSDoc says ''.

Resolves dist conflicts in commerce.js, mas.js, merch-card-collection.js, merch-card.js by rebuilding from source.
@Andrei4226

Andrei4226 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Nice, per-OSI zip is clean and the wcs tests asserting real URLs are great.

Ran your branch with osi="abm,,stock-abm" and promo="P1,P2,P3": wcsOsi comes back length 2, promotionCodes length 3, and stock-abm requests promotion_code=P2 instead of P3. toOfferSelectorIds drops blanks, toPromotionCodes keeps them, and wcs zips by index. Worth pairing before filtering.

Nit: promotionCodes holds undefined entries where the JSDoc says ''.

Thanks!
I fixed both: pairing OSI and promo codes by index before dropping blanks (toWcsOsiAndPromotionCodes), so stock-abm now correctly gets P3 instead of P2. Also removed the now-unused toOfferSelectorIds in favor of it. Left the undefined/'' nit as-is since it's expected downstream (computePromoStatus resolves a blank code to undefined, which wcs.js already coalesces back to '' via ?? '') and updated the JSDoc to call that out instead of changing the behavior.
Added tests covering these scenarios.

@Axelcureno

Copy link
Copy Markdown
Member

Verified, zipping before the blank filter fixes it: abm,,stock-abm + P1,P2,P3 now gives ['abm','stock-abm'] / ['P1','P3'], toOfferSelectorIds has no callers left, and trailing blanks / extra codes / missing codes all degrade cleanly.

One tiny thing on the nit: computePromoStatus(code).effectivePromoCode ?? '' at the two map sites (price.js:58, checkout.js:71) makes the array actually string[], so the wcs.js:290 JSDoc is true. omitProperties treats '' and undefined the same, so nothing downstream shifts. Otherwise good to go.

@Axelcureno Axelcureno left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Verified above, approving. The ?? '' nit is optional.

Branch is conflicting with main, needs a merge before this can land.

@seanchoi0 seanchoi0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving but you should resolve the conflict

# Conflicts:
#	web-components/dist/commerce.js
#	web-components/dist/mas.js
#	web-components/dist/merch-card-collection.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants