Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MWPW-156357 Price-literals - fail gracefully #2815

Merged
merged 18 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion libs/blocks/merch/merch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
import { replaceKey } from '../../features/placeholders.js';

export const PRICE_LITERALS_URL = 'https://www.adobe.com/federal/commerce/price-literals.json';
export const DEFAULT_PRICE_LITERALS_PATH = '/libs/features/mas/commerce/default-price-literals.json';
export const CHECKOUT_LINK_CONFIG_PATH = '/commerce/checkout-link.json'; // relative to libs.

export const PRICE_TEMPLATE_DISCOUNT = 'discount';
Expand Down Expand Up @@ -179,10 +180,21 @@ export async function fetchEntitlements() {
return fetchEntitlements.promise;
}

async function loadDefaultPriceLiterals() {
return fetch(DEFAULT_PRICE_LITERALS_PATH);
}

export async function fetchLiterals(url) {
fetchLiterals.promise = fetchLiterals.promise ?? new Promise((resolve) => {
fetch(url)
.then((response) => response.json().then(({ data }) => resolve(data)));
.catch(() => loadDefaultPriceLiterals())
.then(async (response) => {
if (response.ok) {
return response.json().then(({ data }) => resolve(data));
}
const defaultPriceLiterals = await loadDefaultPriceLiterals();
return defaultPriceLiterals.json().then(({ data }) => resolve(data));
});
bozojovicic marked this conversation as resolved.
Show resolved Hide resolved
});
return fetchLiterals.promise;
}
Expand Down
1 change: 1 addition & 0 deletions libs/features/mas/commerce/default-price-literals.json

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions test/blocks/merch/merch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ describe('Merch Block', () => {
document.head.innerHTML = await readMockText('/test/blocks/merch/mocks/head.html');
document.body.innerHTML = await readMockText('/test/blocks/merch/mocks/body.html');
({ setCheckoutLinkConfigs, setSubscriptionsData } = await mockFetch());
fetchLiterals.promise = null;
config.commerce = { priceLiteralsPromise: fetchLiterals(PRICE_LITERALS_URL) };
setCheckoutLinkConfigs(CHECKOUT_LINK_CONFIGS);
});
Expand Down Expand Up @@ -228,6 +229,35 @@ describe('Merch Block', () => {
});
});

describe('price literals', () => {
it('loads standard price literals', async () => {
fetchLiterals.promise = null;
const data = await fetchLiterals(PRICE_LITERALS_URL);
expect(Array.isArray(data)).to.be.true;
expect(data.length).to.equal(1);
expect(data[0].lang).to.equal('en');
expect(data[0].default).to.be.false;
});

it('loads default price literals after 404', async () => {
fetchLiterals.promise = null;
const data = await fetchLiterals('https://www.adobe.com/federal/commerce/price-literals-404.json');
expect(Array.isArray(data)).to.be.true;
expect(data.length).to.equal(1);
expect(data[0].lang).to.equal('en');
expect(data[0].default).to.be.true;
});

it('loads default price literals after 500', async () => {
fetchLiterals.promise = null;
const data = await fetchLiterals('https://www.adobe.com/federal/commerce/price-literals-500.json');
expect(Array.isArray(data)).to.be.true;
expect(data.length).to.equal(1);
expect(data[0].lang).to.equal('en');
expect(data[0].default).to.be.true;
});
});

describe('promo prices', () => {
it('renders merch link to promo price with discount', async () => {
await validatePriceSpan('.merch.price.oldprice', { promotionCode: undefined });
Expand Down
22 changes: 22 additions & 0 deletions test/blocks/merch/mocks/default-price-literals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"total":1,
"offset":0,
"limit":1,
"data":[
{
"lang":"en",
"default": true,
"recurrenceLabel":"{recurrenceTerm, select, MONTH {/mo} YEAR {/yr} other {}}",
"recurrenceAriaLabel":"{recurrenceTerm, select, MONTH {per month} YEAR {per year} other {}}",
"perUnitLabel":"{perUnit, select, LICENSE {per license} other {}}",
"perUnitAriaLabel":"{perUnit, select, LICENSE {per license} other {}}",
"freeLabel":"Free",
"freeAriaLabel":"Free",
"taxExclusiveLabel":"{taxTerm, select, GST {excl. GST} VAT {excl. VAT} TAX {excl. tax} IVA {excl. IVA} SST {excl. SST} KDV {excl. KDV} other {}}",
"taxInclusiveLabel":"{taxTerm, select, GST {incl. GST} VAT {incl. VAT} TAX {incl. tax} IVA {incl. IVA} SST {incl. SST} KDV {incl. KDV} other {}}",
"alternativePriceAriaLabel":"Alternatively at {alternativePrice}",
"strikethroughAriaLabel":"Regularly at {strikethroughPrice}"
}
],
":type":"sheet"
}
29 changes: 28 additions & 1 deletion test/blocks/merch/mocks/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export async function mockFetch() {
// this path allows to import this mock from tests for other blocks (e.g. commerce)
const basePath = '/test/blocks/merch/mocks/';
const literals = await readMockJSON(`${basePath}literals.json`);
const defaultLiterals = await readMockJSON(`${basePath}default-price-literals.json`);
const offers = await readMockJSON(`${basePath}offers.json`);
const namedOffers = await readMockJSON(`${basePath}named-offers.json`);

Expand Down Expand Up @@ -51,14 +52,40 @@ export async function mockFetch() {
};

sinon.stub(window, 'fetch').callsFake((...args) => {
const { href, pathname, searchParams } = new URL(String(args[0]));
let url;
try {
url = new URL(String(args[0]));
} catch (err) {
url = {
href: args[0],
pathname: args[0],
searchParams: null,
};
}
const { href, pathname, searchParams } = url;
// literals mock
if (href === PRICE_LITERALS_URL) {
return Promise.resolve({
ok: true,
json: () => Promise.resolve(literals),
});
}

if (href.includes('/default-price-literals')) {
return Promise.resolve({
ok: true,
json: () => Promise.resolve(defaultLiterals),
});
}

if (href.includes('/price-literals-404')) {
return Promise.resolve({ ok: false });
}

if (href.includes('/price-literals-500')) {
return Promise.reject(new Error('fetch error'));
}

// wcs mock
if (pathname.endsWith('/web_commerce_artifact')) {
const osis = searchParams.get('offer_selector_ids').split(',');
Expand Down
1 change: 1 addition & 0 deletions test/blocks/merch/mocks/literals.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"data": [{
"lang": "en",
"default": false,
"recurrenceLabel": "{recurrenceTerm, select, MONTH {/mo} YEAR {/yr} other {}}",
"recurrenceAriaLabel": "{recurrenceTerm, select, MONTH {per month} YEAR {per year} other {}}",
"perUnitLabel": "{perUnit, select, LICENSE {per license} other {}}",
Expand Down