From 2c337a7fc67b74962a5276b816f93ac6a1df3f4f Mon Sep 17 00:00:00 2001 From: Chris Barton Date: Wed, 2 Oct 2024 17:42:30 -0700 Subject: [PATCH] fix: remove CvvElement, impl other review feedback --- lib/recurly.js | 2 +- lib/recurly/element/card-cvv.js | 1 + lib/recurly/element/cvv.js | 11 ----- lib/recurly/elements.js | 4 +- lib/recurly/token.js | 2 +- .../fixtures/field.html.ejs | 14 +++--- test/e2e/display.test.js | 8 ++-- test/e2e/support/helpers.js | 5 +- test/types/elements.ts | 3 -- test/unit/elements.test.js | 3 -- test/unit/token.test.js | 48 ++++++++++++------- types/lib/elements.d.ts | 2 - 12 files changed, 49 insertions(+), 54 deletions(-) delete mode 100644 lib/recurly/element/cvv.js diff --git a/lib/recurly.js b/lib/recurly.js index faccc76e3..b8c56aff8 100644 --- a/lib/recurly.js +++ b/lib/recurly.js @@ -288,7 +288,7 @@ export class Recurly extends Emitter { deepAssign(this.config.fields, options.fields); } - if (typeof options.required === 'object') { + if (Array.isArray(options.required)) { this.config.required = uniq([...this.config.required, ...options.required]); } diff --git a/lib/recurly/element/card-cvv.js b/lib/recurly/element/card-cvv.js index 6dde05a10..cdc4002f7 100644 --- a/lib/recurly/element/card-cvv.js +++ b/lib/recurly/element/card-cvv.js @@ -7,4 +7,5 @@ export function factory (options) { export class CardCvvElement extends Element { static type = 'cvv'; static elementClassName = 'CardCvvElement'; + static supportsTokenization = true; } diff --git a/lib/recurly/element/cvv.js b/lib/recurly/element/cvv.js deleted file mode 100644 index 0c7353594..000000000 --- a/lib/recurly/element/cvv.js +++ /dev/null @@ -1,11 +0,0 @@ -import Element from './element'; - -export function factory (options) { - return new CvvElement({ ...options, elements: this }); -} - -export class CvvElement extends Element { - static type = 'cvv'; - static elementClassName = 'CvvElement'; - static supportsTokenization = true; -} diff --git a/lib/recurly/elements.js b/lib/recurly/elements.js index 321aa4fad..a2778c6b6 100644 --- a/lib/recurly/elements.js +++ b/lib/recurly/elements.js @@ -7,7 +7,6 @@ import { factory as cardNumberElementFactory, CardNumberElement } from './elemen import { factory as cardMonthElementFactory, CardMonthElement } from './element/card-month'; import { factory as cardYearElementFactory, CardYearElement } from './element/card-year'; import { factory as cardCvvElementFactory, CardCvvElement } from './element/card-cvv'; -import { factory as cvvElementFactory, CvvElement } from './element/cvv'; import uid from '../util/uid'; const debug = require('debug')('recurly:elements'); @@ -30,11 +29,10 @@ export default class Elements extends Emitter { CardMonthElement = cardMonthElementFactory; CardYearElement = cardYearElementFactory; CardCvvElement = cardCvvElementFactory; - CvvElement = cvvElementFactory; static VALID_SETS = [ [ CardElement ], - [ CvvElement ], + [ CardCvvElement ], [ CardNumberElement, CardMonthElement, CardYearElement, CardCvvElement ], ]; diff --git a/lib/recurly/token.js b/lib/recurly/token.js index 014a9c8b3..6c1fa333e 100644 --- a/lib/recurly/token.js +++ b/lib/recurly/token.js @@ -182,7 +182,7 @@ function token (customerData, bus, done) { .then(() => this.request.post({ route: '/token', data: inputs, done: complete })) .done(); } else { - this.request.post({ route: '/token', data: inputs, done: complete.bind(this) }); + this.request.post({ route: '/token', data: inputs, done: complete }); } } diff --git a/packages/public-api-fixture-server/fixtures/field.html.ejs b/packages/public-api-fixture-server/fixtures/field.html.ejs index 569c5fde5..be99f92d4 100644 --- a/packages/public-api-fixture-server/fixtures/field.html.ejs +++ b/packages/public-api-fixture-server/fixtures/field.html.ejs @@ -19,10 +19,13 @@ } // Stub broker behavior - var tokenizeElementType = config().recurly.fields.tokenizeElement || 'number'; - if (config().type === tokenizeElementType) { - window.addEventListener('message', receivePostMessage, false); + function setStubTokenizationElementName (name) { + window.stubTokenizationElementName = name; + if (config().type === name) { + window.addEventListener('message', receivePostMessage, false); + } } + setStubTokenizationElementName('number'); sendMessage(prefix + ':ready', { type: config().type }); @@ -39,9 +42,8 @@ // Event handlers function onToken (body) { - const recurlyConfig = getRecurlyConfig(); - var recurly = new parent.recurly.Recurly(recurlyConfig); - if (recurlyConfig.fields.tokenizeElement === 'cvv') { + var recurly = new parent.recurly.Recurly(getRecurlyConfig()); + if (stubTokenizationElementName === 'cvv') { recurly.config.required = ['cvv']; } var inputs = body.inputs; diff --git a/test/e2e/display.test.js b/test/e2e/display.test.js index 5cd32c2d5..bea154027 100644 --- a/test/e2e/display.test.js +++ b/test/e2e/display.test.js @@ -33,7 +33,7 @@ maybeDescribe('Display', () => { describe('distinct elements', async function () { it('matches distinct elements baseline', async function () { - const { CardElement, CvvElement, ...distinctElements } = ELEMENT_TYPES; + const { CardElement, ...distinctElements } = ELEMENT_TYPES; for (const element in distinctElements) { await createElement(element, { style: { fontFamily: 'Pacifico' } }); } @@ -44,9 +44,9 @@ maybeDescribe('Display', () => { }); }); - describe('CvvElement', async function () { - it('matches CvvElement baseline', async function () { - await createElement(ELEMENT_TYPES.CvvElement, { style: { fontFamily: 'Pacifico' } }); + describe('distinct CardCvvElement', async function () { + it('matches CardCvvElement baseline', async function () { + await createElement(ELEMENT_TYPES.CardCvvElement, { style: { fontFamily: 'Pacifico' } }); await fillCvvElement(); await clickFirstName(); diff --git a/test/e2e/support/helpers.js b/test/e2e/support/helpers.js index c64ed7c3e..1c2ccedf1 100644 --- a/test/e2e/support/helpers.js +++ b/test/e2e/support/helpers.js @@ -23,7 +23,6 @@ const ELEMENT_TYPES = { CardMonthElement: 'CardMonthElement', CardYearElement: 'CardYearElement', CardCvvElement: 'CardCvvElement', - CvvElement: 'CvvElement', }; const FIELD_TYPES = { @@ -138,9 +137,9 @@ function elementAndFieldSuite ({ maybeRun(distinctCardElements); }); - describe('CvvElement', function () { + describe('distinct CardCvvElement', function () { beforeEach(async function () { - await createElement(ELEMENT_TYPES.CvvElement); + await createElement(ELEMENT_TYPES.CardCvvElement); }); maybeRun(cvvElement); }); diff --git a/test/types/elements.ts b/test/types/elements.ts index 76b27e08e..aa7cef16c 100644 --- a/test/types/elements.ts +++ b/test/types/elements.ts @@ -33,12 +33,9 @@ export default function elements () { } }; - const cvvElement = elements.CvvElement(elementOptions); - const el = document.querySelector('div'); if (el) { cardElement.attach(el).configure({}).focus().remove(); - cvvElement.attach(el).configure({}).focus().remove(); } [ diff --git a/test/unit/elements.test.js b/test/unit/elements.test.js index 9bc860f5c..ddc12cc98 100644 --- a/test/unit/elements.test.js +++ b/test/unit/elements.test.js @@ -26,7 +26,6 @@ describe('Elements', function () { 'CardMonthElement', 'CardYearElement', 'CardCvvElement', - 'CvvElement', ].forEach(elementName => { const elements = new Elements({ recurly: this.recurly }); const element = elements[elementName](); @@ -90,8 +89,6 @@ describe('Elements', function () { const invalidSets = [ ['CardElement', 'CardNumberElement'], ['CardElement', 'CardCvvElement'], - ['CardElement', 'CvvElement'], - ['CardNumberElement', 'CvvElement'], ['CardNumberElement', 'CardElement'], ['CardNumberElement', 'CardMonthElement', 'CardYearElement', 'CardCvvElement', 'CardElement'] ]; diff --git a/test/unit/token.test.js b/test/unit/token.test.js index 2ed380c32..a66a6c287 100644 --- a/test/unit/token.test.js +++ b/test/unit/token.test.js @@ -18,7 +18,7 @@ describe('Recurly.token', function () { last_name: 'bar' }; - const ELEMENTS_MAP = { + const elementsMap = { card: 'CardElement', number: 'CardNumberElement', month: 'CardMonthElement', @@ -128,22 +128,27 @@ describe('Recurly.token', function () { }); describe('Cvv standalone', function () { - this.ctx.fixture = () => ` -
-
- -
- `; - applyFixtures(); - buildRecurly({ fields: { tokenizeElement: 'cvv' } }); + buildRecurly(); - describe('when called with a plain object', function () { - cvvSuite(plainObjectBuilder); - }); + describe('when using a HostedField', function () { + this.ctx.fixture = () => ` +
+
+ +
+ `; + beforeEach(function () { + this.recurly.hostedFields.fields[0].iframe.contentWindow.setStubTokenizationElementName('cvv'); + }); - describe('when called with an HTMLFormElement', function () { - cvvSuite(formBuilder); + describe('when called with a plain object', function () { + cvvSuite(plainObjectBuilder); + }); + + describe('when called with an HTMLFormElement', function () { + cvvSuite(formBuilder); + }); }); describe('when called with an Elements instance', function () { @@ -154,10 +159,19 @@ describe('Recurly.token', function () { `; - cvvSuite(elementsBuilder, { elementsMap: { cvv: 'CvvElement' } }); + function setupStub (builder) { + return function (...args) { + return builder.call(this, ...args).then(res => { + this.elements.elements[0].iframe.contentWindow.setStubTokenizationElementName('cvv'); + return res; + }); + }; + } + + cvvSuite(setupStub(elementsBuilder)); describe('when called with an HTMLFormElement', function () { - cvvSuite(elementsFormOnlyBuilder, { elementsMap: { cvv: 'CvvElement' } }); + cvvSuite(setupStub(elementsFormOnlyBuilder)); }); }); }); @@ -214,7 +228,7 @@ describe('Recurly.token', function () { /** * For each example, updates corresponding input field or Element */ - function elementsBuilder ({ elementsMap = ELEMENTS_MAP, ...example }) { + function elementsBuilder (example) { const form = window.document.querySelector('#test-form'); const container = form.querySelector('#recurly-elements'); const elements = this.elements = this.recurly.Elements(); diff --git a/types/lib/elements.d.ts b/types/lib/elements.d.ts index 40b4859fc..b893c8779 100644 --- a/types/lib/elements.d.ts +++ b/types/lib/elements.d.ts @@ -261,8 +261,6 @@ export interface ElementsInstance extends Emitter { CardMonthElement: (cardMonthElementOptions?: IndividualElementOptions) => IndividualElement; CardYearElement: (cardYearElementOptions?: IndividualElementOptions) => IndividualElement; CardCvvElement: (cardCvvElementOptions?: IndividualElementOptions) => IndividualElement; - - CvvElement: (cvvElementOptions?: IndividualElementOptions) => IndividualElement; } export type Elements = () => ElementsInstance;