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); + }); + }); });