From a89858369f56c28706b67802d945e801edd76cc1 Mon Sep 17 00:00:00 2001 From: Julia F Date: Mon, 29 Jan 2024 16:31:28 -0500 Subject: [PATCH 1/2] refactor: update contextual_component query param to contextual_components (#1046) --- src/components/message/Message.js | 6 ++--- .../modal/v2/lib/hooks/calculator.js | 4 ++-- src/components/modal/v2/lib/utils.js | 4 ++-- src/components/modal/v2/parts/Container.jsx | 4 ++-- src/library/controllers/message/interface.js | 6 ++--- src/library/controllers/modal/interface.js | 4 ++-- src/library/zoid/message/component.js | 6 ++--- src/library/zoid/message/validation.js | 22 +++++++++---------- src/library/zoid/modal/component.js | 6 ++--- src/utils/elements.js | 2 +- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/components/message/Message.js b/src/components/message/Message.js index 13c9356ed0..714811a5d0 100644 --- a/src/components/message/Message.js +++ b/src/components/message/Message.js @@ -125,7 +125,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { style, merchantConfigHash, channel, - contextualComponent, + contextualComponents, treatmentsHash, disableSetCookie, features @@ -143,7 +143,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { merchantId, merchantConfigHash, channel, - contextualComponent, + contextualComponents, disableSetCookie, features }); @@ -167,7 +167,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { stageTag, merchant_config: merchantConfigHash, channel, - contextualComponent, + contextualComponents, deviceID: getOrCreateDeviceID(), treatments: treatmentsHash, disableSetCookie, diff --git a/src/components/modal/v2/lib/hooks/calculator.js b/src/components/modal/v2/lib/hooks/calculator.js index 2b16d60bde..ae1db39fbf 100644 --- a/src/components/modal/v2/lib/hooks/calculator.js +++ b/src/components/modal/v2/lib/hooks/calculator.js @@ -65,7 +65,7 @@ export default function useCalculator({ autoSubmit = false } = {}) { integrationType, channel, ecToken, - contextualComponent, + contextualComponents, devTouchpoint, disableSetCookie, features @@ -94,7 +94,7 @@ export default function useCalculator({ autoSubmit = false } = {}) { integrationType, channel, ecToken, - contextualComponent, + contextualComponents, devTouchpoint, deviceID: getOrCreateDeviceID(), disableSetCookie, diff --git a/src/components/modal/v2/lib/utils.js b/src/components/modal/v2/lib/utils.js index 687db048d6..8f6ad3729d 100644 --- a/src/components/modal/v2/lib/utils.js +++ b/src/components/modal/v2/lib/utils.js @@ -21,7 +21,7 @@ export const getContent = memoize( integrationType, channel, ecToken, - contextualComponent, + contextualComponents, devTouchpoint, disableSetCookie, features @@ -43,7 +43,7 @@ export const getContent = memoize( integrationType, channel, ec_token: ecToken, - contextual_component: contextualComponent, + contextual_components: contextualComponents, devTouchpoint, disableSetCookie, features diff --git a/src/components/modal/v2/parts/Container.jsx b/src/components/modal/v2/parts/Container.jsx index f69049f922..0fa9e1ab6a 100644 --- a/src/components/modal/v2/parts/Container.jsx +++ b/src/components/modal/v2/parts/Container.jsx @@ -34,7 +34,7 @@ const Container = ({ children }) => { stageTag, channel, ecToken, - contextualComponent, + contextualComponents, disableSetCookie, features } = useXProps(); @@ -78,7 +78,7 @@ const Container = ({ children }) => { stageTag, channel, ecToken, - contextualComponent, + contextualComponents, deviceID: getOrCreateDeviceID(), disableSetCookie, features diff --git a/src/library/controllers/message/interface.js b/src/library/controllers/message/interface.js index b2e2d47cf9..603301c531 100644 --- a/src/library/controllers/message/interface.js +++ b/src/library/controllers/message/interface.js @@ -90,7 +90,7 @@ export default (options = {}) => ({ onApply, channel, ecToken, - contextualComponent, + contextualComponents, cspNonce } = merchantOptions; @@ -106,7 +106,7 @@ export default (options = {}) => ({ ignoreCache, channel, ecToken, - contextualComponent, + contextualComponents, cspNonce }; const modalProps = { @@ -156,7 +156,7 @@ export default (options = {}) => ({ ignoreCache: ${ignoreCache}, channel: ${channel}, ecToken: ${ecToken}, - contextualComponent: ${contextualComponent}, + contextualComponents: ${contextualComponents}, index: data-pp-id="${index}", style: ${JSON.stringify(style)}, diff --git a/src/library/controllers/modal/interface.js b/src/library/controllers/modal/interface.js index ea3be0b49a..ef76b8de7e 100644 --- a/src/library/controllers/modal/interface.js +++ b/src/library/controllers/modal/interface.js @@ -38,7 +38,7 @@ const memoizedModal = memoizeOnProps( onClose, channel, ecToken, - contextualComponent, + contextualComponents, cspNonce, integrationIdentifier }) => { @@ -62,7 +62,7 @@ const memoizedModal = memoizeOnProps( onClose, channel, ecToken, - contextualComponent, + contextualComponents, cspNonce, integrationIdentifier }); diff --git a/src/library/zoid/message/component.js b/src/library/zoid/message/component.js index 86d317b581..8b1f4f3b2f 100644 --- a/src/library/zoid/message/component.js +++ b/src/library/zoid/message/component.js @@ -126,11 +126,11 @@ export default createGlobalVariableGetter('__paypal_credit_message__', () => required: false, value: validate.ecToken }, - contextualComponent: { + contextualComponents: { type: 'string', - queryParam: 'contextual_component', + queryParam: 'contextual_components', required: false, - value: validate.contextualComponent + value: validate.contextualComponents }, // Callbacks onClick: { diff --git a/src/library/zoid/message/validation.js b/src/library/zoid/message/validation.js index 58f235099b..04634fcf7d 100644 --- a/src/library/zoid/message/validation.js +++ b/src/library/zoid/message/validation.js @@ -237,15 +237,15 @@ export default { return undefined; }, - contextualComponent: ({ props: { contextualComponent } }) => { - if (typeof contextualComponent !== 'undefined') { - if (!validateType(Types.STRING, contextualComponent)) { - logInvalidType('contextualComponent', Types.STRING, contextualComponent); + contextualComponents: ({ props: { contextualComponents } }) => { + if (typeof contextualComponents !== 'undefined') { + if (!validateType(Types.STRING, contextualComponents)) { + logInvalidType('contextualComponents', Types.STRING, contextualComponents); return undefined; } // contextualComponent values can either be a single string value or a comma-separated string of values - const typesArray = contextualComponent.toUpperCase().split(','); + const typesArray = contextualComponents.toUpperCase().split(','); // Check if values are of the same type (all buttons or all marks) const allButtons = typesArray.every(type => type.endsWith('_BUTTON')); @@ -253,14 +253,14 @@ export default { if (!allButtons && !allMarks) { logInvalidCombination( - 'contextualComponent', - "Expected all contextualComponent values to be either of type '_button' or '_mark'", - contextualComponent + 'contextualComponents', + "Expected all contextualComponents values to be either of type 'button' or 'mark'", + contextualComponents ); - } else if (typesArray.filter(type => type.endsWith('_mark')).length > 1) { - logInvalid('contextualComponent', 'Ensure only one type of _mark value is provided.'); + } else if (typesArray.filter(type => type.endsWith('_MARK')).length > 1) { + logInvalid('contextualComponents', 'Ensure only one type of mark value is provided.'); } else { - return contextualComponent.toUpperCase().split(',').sort().join(','); + return contextualComponents.toUpperCase().split(',').sort().join(','); } } diff --git a/src/library/zoid/modal/component.js b/src/library/zoid/modal/component.js index 96c4958fd2..330719bd8a 100644 --- a/src/library/zoid/modal/component.js +++ b/src/library/zoid/modal/component.js @@ -136,11 +136,11 @@ export default createGlobalVariableGetter('__paypal_credit_modal__', () => required: false, value: validate.ecToken }, - contextualComponent: { + contextualComponents: { type: 'string', - queryParam: 'contextual_component', + queryParam: 'contextual_components', required: false, - value: validate.contextualComponent + value: validate.contextualComponents }, // Callbacks diff --git a/src/utils/elements.js b/src/utils/elements.js index e9e1551203..e3b70b8b9d 100644 --- a/src/utils/elements.js +++ b/src/utils/elements.js @@ -43,7 +43,7 @@ export function getInlineOptions(container) { merchantid: 'merchantId', cspnonce: 'cspNonce', ectoken: 'ecToken', - contextualcomponent: 'contextualComponent', + contextualcomponents: 'contextualComponents', customerid: 'customerId', fontfamily: 'fontFamily', fontsource: 'fontSource', From c879cad3f6004ebc991e02ca84d3b602854ada18 Mon Sep 17 00:00:00 2001 From: perco12 <141269770+perco12@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:29:12 -0600 Subject: [PATCH 2/2] feat: enhance feature param (#1048) --- src/library/controllers/message/interface.js | 6 +++-- src/library/controllers/modal/interface.js | 6 +++-- src/library/zoid/message/component.js | 2 +- src/library/zoid/message/validation.js | 10 ++++++++ src/library/zoid/modal/component.js | 2 +- .../spec/src/zoid/message/validation.test.js | 23 +++++++++++++++++++ 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/library/controllers/message/interface.js b/src/library/controllers/message/interface.js index 603301c531..f0bdfd435b 100644 --- a/src/library/controllers/message/interface.js +++ b/src/library/controllers/message/interface.js @@ -91,7 +91,8 @@ export default (options = {}) => ({ channel, ecToken, contextualComponents, - cspNonce + cspNonce, + features } = merchantOptions; // Explicitly select props to pass in to avoid unintentionally sending @@ -107,7 +108,8 @@ export default (options = {}) => ({ channel, ecToken, contextualComponents, - cspNonce + cspNonce, + features }; const modalProps = { ...commonProps, diff --git a/src/library/controllers/modal/interface.js b/src/library/controllers/modal/interface.js index ef76b8de7e..d800cdc654 100644 --- a/src/library/controllers/modal/interface.js +++ b/src/library/controllers/modal/interface.js @@ -40,7 +40,8 @@ const memoizedModal = memoizeOnProps( ecToken, contextualComponents, cspNonce, - integrationIdentifier + integrationIdentifier, + features }) => { addPerformanceMeasure(PERFORMANCE_MEASURE_KEYS.FIRST_MODAL_RENDER_DELAY); @@ -64,7 +65,8 @@ const memoizedModal = memoizeOnProps( ecToken, contextualComponents, cspNonce, - integrationIdentifier + integrationIdentifier, + features }); // Fired from inside the default onReady callback let renderProm; diff --git a/src/library/zoid/message/component.js b/src/library/zoid/message/component.js index 8b1f4f3b2f..2f6275f78b 100644 --- a/src/library/zoid/message/component.js +++ b/src/library/zoid/message/component.js @@ -473,7 +473,7 @@ export default createGlobalVariableGetter('__paypal_credit_message__', () => type: 'string', queryParam: 'features', required: false, - value: getFeatures + value: validate.features ?? getFeatures } } }) diff --git a/src/library/zoid/message/validation.js b/src/library/zoid/message/validation.js index 04634fcf7d..60d07e5bb0 100644 --- a/src/library/zoid/message/validation.js +++ b/src/library/zoid/message/validation.js @@ -285,6 +285,16 @@ export default { return merchantConfig; } + return undefined; + }, + features: ({ props: { features } }) => { + if (typeof features !== 'undefined') { + if (!validateType(Types.STRING, features)) { + logInvalidType('features', Types.STRING, features); + } else { + return features; + } + } return undefined; } }; diff --git a/src/library/zoid/modal/component.js b/src/library/zoid/modal/component.js index 330719bd8a..cace559cab 100644 --- a/src/library/zoid/modal/component.js +++ b/src/library/zoid/modal/component.js @@ -442,7 +442,7 @@ export default createGlobalVariableGetter('__paypal_credit_modal__', () => type: 'string', queryParam: 'features', required: false, - value: getFeatures + value: validate.features ?? getFeatures } } }) diff --git a/tests/unit/spec/src/zoid/message/validation.test.js b/tests/unit/spec/src/zoid/message/validation.test.js index 3c9a3542a5..8c72208977 100644 --- a/tests/unit/spec/src/zoid/message/validation.test.js +++ b/tests/unit/spec/src/zoid/message/validation.test.js @@ -269,4 +269,27 @@ describe('validate', () => { ); }); }); + test('validates features', () => { + // features passed + ['DEMO', 'test', 'FEATURE'].forEach(validFeatures => { + const features = validate.features({ props: { features: validFeatures } }); + + expect(features).toEqual(validFeatures); + expect(console.warn).not.toHaveBeenCalled(); + }); + // no features passed + { + const features = validate.features({ props: {} }); + + expect(features).toBeUndefined(); + expect(console.warn).not.toHaveBeenCalled(); + } + // invalid features pass + [12345, null, {}, ['Hi']].forEach((invalidFeature, index) => { + const features = validate.features({ props: { features: invalidFeature } }); + + expect(features).toBeUndefined(); + expect(console.warn).toHaveBeenCalledTimes(index + 1); + }); + }); });