Skip to content

Commit

Permalink
MWPW-156220: Support pa code and product code for (#2712)
Browse files Browse the repository at this point in the history
* MWPW-156220: Support pa code and product code for

checkout link configuration in addition to product family.

* optimize perf

* PR feedback

* PR feedback
  • Loading branch information
yesil authored Aug 12, 2024
1 parent 36051c6 commit b407c02
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 35 deletions.
60 changes: 48 additions & 12 deletions libs/blocks/merch/merch.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,28 +192,48 @@ export async function fetchCheckoutLinkConfigs(base = '') {
?? fetch(`${base}${CHECKOUT_LINK_CONFIG_PATH}`).catch((e) => {
log?.error('Failed to fetch checkout link configs', e);
}).then((mappings) => {
if (!mappings?.ok) return undefined;
if (!mappings?.ok) return { data: [] };
return mappings.json();
});
return fetchCheckoutLinkConfigs.promise;
}

export async function getCheckoutLinkConfig(productFamily) {
export async function getCheckoutLinkConfig(productFamily, productCode, paCode) {
let { base } = getConfig();
if (/\.page$/.test(document.location.origin)) {
/* c8 ignore next 2 */
base = base.replace('.live', '.page');
}
const checkoutLinkConfigs = await fetchCheckoutLinkConfigs(base);
if (!checkoutLinkConfigs.data.length) return undefined;
const { locale: { region } } = getConfig();
const productFamilyConfigs = checkoutLinkConfigs.data?.filter(
({ [NAME_PRODUCT_FAMILY]: mappingProductFamily }) => mappingProductFamily === productFamily,
);
if (productFamilyConfigs.length === 0) return undefined;
const checkoutLinkConfig = productFamilyConfigs.find(

const {
paCodeConfigs,
productCodeConfigs,
productFamilyConfigs,
} = checkoutLinkConfigs.data.reduce((acc, config) => {
if (config[NAME_PRODUCT_FAMILY] === paCode) {
acc.paCodeConfigs.push(config);
} else if (config[NAME_PRODUCT_FAMILY] === productCode) {
acc.productCodeConfigs.push(config);
} else if (config[NAME_PRODUCT_FAMILY] === productFamily) {
acc.productFamilyConfigs.push(config);
}
return acc;
}, { paCodeConfigs: [], productCodeConfigs: [], productFamilyConfigs: [] });

// helps to fallback to product family config
// if no locale specific config is found below.
const productCheckoutLinkConfigs = [
...paCodeConfigs, ...productCodeConfigs, ...productFamilyConfigs,
];

if (!productCheckoutLinkConfigs.length) return undefined;
const checkoutLinkConfig = productCheckoutLinkConfigs.find(
({ [NAME_LOCALE]: locale }) => locale === '',
);
const checkoutLinkConfigOverride = productFamilyConfigs.find(
const checkoutLinkConfigOverride = productCheckoutLinkConfigs.find(
({ [NAME_LOCALE]: locale }) => locale === region,
) ?? {};
const overrides = Object.fromEntries(
Expand All @@ -231,14 +251,22 @@ export async function getCheckoutLinkConfig(productFamily) {
export async function getDownloadAction(
options,
imsSignedInPromise,
[{ offerType, productArrangement: { productFamily: offerFamily } = {} }],
[{
offerType,
productArrangementCode,
productArrangement: { productCode, productFamily: offerFamily } = {},
}],
) {
if (options.entitlement !== true) return undefined;
const loggedIn = await imsSignedInPromise;
if (!loggedIn) return undefined;
const entitlements = await fetchEntitlements();
if (!entitlements?.length) return undefined;
const checkoutLinkConfig = await getCheckoutLinkConfig(offerFamily);
const checkoutLinkConfig = await getCheckoutLinkConfig(
offerFamily,
productCode,
productArrangementCode,
);
if (!checkoutLinkConfig?.DOWNLOAD_URL) return undefined;
const offer = entitlements.find((
{ offer: { product_arrangement: { family: subscriptionFamily } } },
Expand Down Expand Up @@ -355,9 +383,17 @@ export async function openModal(e, url, offerType) {
}

export async function getModalAction(offers, options) {
const [{ offerType, productArrangement: { productFamily: offerFamily } = {} }] = offers ?? [{}];
const [{
offerType,
productArrangementCode,
productArrangement: { productCode, productFamily: offerFamily } = {},
}] = offers ?? [{}];
if (options.modal !== true) return undefined;
const checkoutLinkConfig = await getCheckoutLinkConfig(offerFamily);
const checkoutLinkConfig = await getCheckoutLinkConfig(
offerFamily,
productCode,
productArrangementCode,
);
if (!checkoutLinkConfig) return undefined;
const columnName = (offerType === OFFER_TYPE_TRIAL) ? FREE_TRIAL_PATH : BUY_NOW_PATH;
let url = checkoutLinkConfig[columnName];
Expand Down
69 changes: 46 additions & 23 deletions test/blocks/merch/merch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ const CHECKOUT_LINK_CONFIGS = {
BUY_NOW_PATH: '',
LOCALE: '',
},
{
PRODUCT_FAMILY: 'testPaCode',
DOWNLOAD_TEXT: 'paCode',
},
{
PRODUCT_FAMILY: 'testProductCode',
DOWNLOAD_TEXT: 'productCode',
},
],
};

Expand Down Expand Up @@ -489,8 +497,7 @@ describe('Merch Block', () => {
fetchCheckoutLinkConfigs.promise = undefined;
setCheckoutLinkConfigs(null);
const mappings = await fetchCheckoutLinkConfigs('http://localhost:2000/libs');
expect(mappings).to.be.undefined;
setCheckoutLinkConfigs(CHECKOUT_LINK_CONFIGS);
expect(mappings.data).to.empty;
fetchCheckoutLinkConfigs.promise = undefined;
});

Expand Down Expand Up @@ -522,27 +529,6 @@ describe('Merch Block', () => {
expect(url).to.equal('https://creativecloud.adobe.com/apps/download');
});

it('getModalAction: returns undefined if checkout-link config is not found', async () => {
fetchCheckoutLinkConfigs.promise = undefined;
setCheckoutLinkConfigs(CHECKOUT_LINK_CONFIGS);
const action = await getModalAction([{ productArrangement: { productFamily: 'XZY' } }], { modal: true });
expect(action).to.be.undefined;
});

it('getModalAction: returns undefined if modal path is cancelled', async () => {
setConfig({
...config,
pathname: '/fr/test.html',
locales: { fr: { ietf: 'fr-FR' } },
prodDomains: PROD_DOMAINS,
placeholders: { download: 'Télécharger' },
});
fetchCheckoutLinkConfigs.promise = undefined;
setCheckoutLinkConfigs(CHECKOUT_LINK_CONFIGS);
const action = await getModalAction([{ productArrangement: { productFamily: 'PHOTOSHOP' } }], { modal: true });
expect(action).to.be.undefined;
});

it('getCheckoutAction: handles errors gracefully', async () => {
const imsSignedInPromise = new Promise((resolve, reject) => {
setTimeout(() => {
Expand Down Expand Up @@ -590,6 +576,7 @@ describe('Merch Block', () => {
expect(modal).to.exist;
document.querySelector('.modal-curtain').click();
});

it('renders Milo TWP modal', async () => {
mockIms();
const el = document.querySelector('.merch.cta.milo.twp');
Expand Down Expand Up @@ -632,6 +619,7 @@ describe('Merch Block', () => {
expect(modal).to.exist;
document.querySelector('.modal-curtain').click();
});

it('renders TWP modal with preselected plan', async () => {
mockIms();
const meta = document.createElement('meta');
Expand All @@ -648,6 +636,41 @@ describe('Merch Block', () => {
document.querySelector('meta[name="preselect-plan"]').remove();
});

it('getCheckoutLinkConfig: finds using paCode', async () => {
let checkoutLinkConfig = await getCheckoutLinkConfig(undefined, undefined, 'testPaCode');
expect(checkoutLinkConfig.DOWNLOAD_TEXT).to.equal('paCode');
checkoutLinkConfig = await getCheckoutLinkConfig('', '', 'testPaCode');
expect(checkoutLinkConfig.DOWNLOAD_TEXT).to.equal('paCode');
});

it('getCheckoutLinkConfig: finds using productCode', async () => {
let checkoutLinkConfig = await getCheckoutLinkConfig(undefined, 'testProductCode', undefined);
expect(checkoutLinkConfig.DOWNLOAD_TEXT).to.equal('productCode');
checkoutLinkConfig = await getCheckoutLinkConfig('', 'testProductCode', '');
expect(checkoutLinkConfig.DOWNLOAD_TEXT).to.equal('productCode');
});

it('getModalAction: returns undefined if modal path is cancelled', async () => {
setConfig({
...config,
pathname: '/fr/test.html',
locales: { fr: { ietf: 'fr-FR' } },
prodDomains: PROD_DOMAINS,
placeholders: { download: 'Télécharger' },
});
fetchCheckoutLinkConfigs.promise = undefined;
setCheckoutLinkConfigs(CHECKOUT_LINK_CONFIGS);
const action = await getModalAction([{ productArrangement: { productFamily: 'PHOTOSHOP' } }], { modal: true });
expect(action).to.be.undefined;
});

it('getModalAction: returns undefined if checkout-link config is not found', async () => {
fetchCheckoutLinkConfigs.promise = undefined;
setCheckoutLinkConfigs(CHECKOUT_LINK_CONFIGS);
const action = await getModalAction([{ productArrangement: { productFamily: 'XZY' } }], { modal: true });
expect(action).to.be.undefined;
});

const MODAL_URLS = [
{
url: 'https://www.adobe.com/mini-plans/illustrator1.html?mid=ft&web=1',
Expand Down

0 comments on commit b407c02

Please sign in to comment.