From f109fc7db0db9215ab888100ff19480e3ffc7345 Mon Sep 17 00:00:00 2001 From: "Erika Colette - NYC (she/her)" <72584889+erikacolette29@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:52:15 -0400 Subject: [PATCH] feat: logic to handle merchant including placement and page-type parameters the SDK (#1050) --- src/library/controllers/message/interface.js | 27 +++++++++++---- src/library/controllers/message/setup.js | 4 ++- src/library/zoid/message/component.js | 6 ---- src/library/zoid/message/validation.js | 24 +++---------- .../spec/src/zoid/message/validation.test.js | 34 +++---------------- 5 files changed, 31 insertions(+), 64 deletions(-) diff --git a/src/library/controllers/message/interface.js b/src/library/controllers/message/interface.js index 5adf85c0d4..278da78215 100644 --- a/src/library/controllers/message/interface.js +++ b/src/library/controllers/message/interface.js @@ -20,6 +20,25 @@ import { import { getMessageComponent } from '../../zoid/message'; import { Modal } from '../modal'; +function getMerchantOptions(jsOptions, container) { + const globalOptions = getGlobalState().config; + const inlineOptions = getInlineOptions(container); + + // Use the spread operator to clone jsOptions and inlineOptions, while directly overriding and deleting properties as needed + const mergedOptions = { + ...globalOptions, + ...jsOptions, + ...inlineOptions, + // Override pageType if not set in jsOptions but set in placement, prioritize inlineOptions' pageType if available + pageType: inlineOptions.pageType || jsOptions.pageType || inlineOptions.placement || jsOptions.placement + }; + + // Explicitly delete the placement property from the final mergedOptions + delete mergedOptions.placement; + + return mergedOptions; +} + export default (options = {}) => ({ render: (selector = '[data-pp-message]') => { addPerformanceMeasure(PERFORMANCE_MEASURE_KEYS.FIRST_RENDER_DELAY); @@ -64,10 +83,7 @@ export default (options = {}) => ({ // return resolved render and updateProps const renderOrUpdateMessage = () => { try { - const merchantOptions = objectMerge( - getGlobalState().config, - objectMerge(options, getInlineOptions(container)) - ); + const merchantOptions = getMerchantOptions(options, container); if (!container.hasAttribute('data-pp-id')) { container.setAttribute('data-pp-id', nextIndex()); @@ -80,7 +96,6 @@ export default (options = {}) => ({ customerId, currency, amount, - placement, pageType, style, offer, @@ -119,7 +134,6 @@ export default (options = {}) => ({ const messageProps = { ...commonProps, index, - placement, pageType, style, offer, @@ -166,7 +180,6 @@ export default (options = {}) => ({ style: ${JSON.stringify(style)}, amount: ${amount}, buyerCountry: ${buyerCountry}, - placement: ${placement}, pageType: ${pageType}, renderStart: ${new Date(renderStart).toLocaleString()}, diff --git a/src/library/controllers/message/setup.js b/src/library/controllers/message/setup.js index 1ad011a27f..15e6f39f81 100644 --- a/src/library/controllers/message/setup.js +++ b/src/library/controllers/message/setup.js @@ -9,7 +9,8 @@ import { isZoidComponent, ppDebug, getOverflowObserver, - ensureTreatments + ensureTreatments, + getPageType } from '../../../utils'; import Messages from './adapter'; import { getMessageComponent } from '../../zoid/message'; @@ -34,6 +35,7 @@ export default function setup() { account: partnerAccount || getAccount(), merchantId: partnerAccount && getAccount(), currency: getCurrency(), + pageType: getPageType(), ...inlineScriptOptions }); } diff --git a/src/library/zoid/message/component.js b/src/library/zoid/message/component.js index c4eccc00d7..a816dc1848 100644 --- a/src/library/zoid/message/component.js +++ b/src/library/zoid/message/component.js @@ -82,12 +82,6 @@ export default createGlobalVariableGetter('__paypal_credit_message__', () => required: false, value: validate.currency }, - placement: { - type: 'string', - queryParam: true, - required: false, - value: validate.placement - }, pageType: { type: 'string', queryParam: 'page_type', diff --git a/src/library/zoid/message/validation.js b/src/library/zoid/message/validation.js index 242465872c..a256b18ade 100644 --- a/src/library/zoid/message/validation.js +++ b/src/library/zoid/message/validation.js @@ -1,7 +1,7 @@ import arrayIncludes from 'core-js-pure/stable/array/includes'; import numberIsNaN from 'core-js-pure/stable/number/is-nan'; import stringStartsWith from 'core-js-pure/stable/string/starts-with'; -import { logger, memoize, getEnv, getPageType } from '../../../utils'; +import { logger, memoize, getEnv } from '../../../utils'; import { OFFER } from '../../../utils/constants'; export const Types = { @@ -188,30 +188,14 @@ export default { return undefined; }, - placement: ({ props: { placement } }) => { - if (typeof placement !== 'undefined') { - const options = ['home', 'category', 'product', 'cart', 'payment', 'product-list']; - - if (!validateType(Types.STRING, placement)) { - logInvalidType('placement', Types.STRING, placement); - } else if (!arrayIncludes(options, placement)) { - logInvalidOption('placement', options, placement); - } else { - return placement; - } - } - - return undefined; - }, pageType: ({ props: { pageType } }) => { - const sdkPageType = getPageType(); - if (sdkPageType) { - return sdkPageType; - } if (typeof pageType !== 'undefined') { const options = [ 'home', 'category', + 'product', + 'payment', + 'product-list', 'product-listing', 'search-results', 'product-details', diff --git a/tests/unit/spec/src/zoid/message/validation.test.js b/tests/unit/spec/src/zoid/message/validation.test.js index 11052c5869..404eab730a 100644 --- a/tests/unit/spec/src/zoid/message/validation.test.js +++ b/tests/unit/spec/src/zoid/message/validation.test.js @@ -242,38 +242,13 @@ describe('validate', () => { ); }); }); - - test('validates placement', () => { - ['home', 'category', 'product', 'cart', 'payment', 'product-list'].forEach(supportedPlacement => { - const placement = validate.placement({ props: { placement: supportedPlacement } }); - - expect(placement).toEqual(supportedPlacement); - expect(console.warn).not.toHaveBeenCalled(); - }); - - { - const placement = validate.placement({ props: {} }); - - expect(placement).toBeUndefined(); - expect(console.warn).not.toHaveBeenCalled(); - } - - [12345, 'abc', null].forEach((invalidPlacement, index) => { - const placement = validate.placement({ props: { placement: invalidPlacement } }); - - expect(placement).toBeUndefined(); - expect(console.warn).toHaveBeenCalledTimes(index + 1); - expect(console.warn).toHaveBeenLastCalledWith( - expect.stringContaining('invalid_option_value'), - expect.objectContaining({ location: 'placement' }) - ); - }); - }); - - test('validates pageType', () => { + test('validates pageType with placement values added', () => { [ 'home', 'category', + 'product', + 'payment', + 'product-list', 'product-listing', 'search-results', 'product-details', @@ -305,7 +280,6 @@ describe('validate', () => { ); }); }); - test('validates buyerCountry', () => { ['US', 'DE', 'FR', 'GB', 'AU'].forEach(supportedBuyerCountry => { const buyerCountry = validate.buyerCountry({ props: { buyerCountry: supportedBuyerCountry } });