From 3e92635baa3c2d7d40a08fcfaeb5816dd2948d33 Mon Sep 17 00:00:00 2001 From: antoniof Date: Wed, 21 Aug 2024 09:51:35 +0200 Subject: [PATCH] refactor card holder name fix --- .../lib/src/components/Card/Card.test.tsx | 52 ++++++++++++++----- packages/lib/src/components/Card/Card.tsx | 8 +-- .../components/CardInput/CardInput.test.tsx | 8 --- .../Card/components/CardInput/CardInput.tsx | 6 +-- 4 files changed, 46 insertions(+), 28 deletions(-) diff --git a/packages/lib/src/components/Card/Card.test.tsx b/packages/lib/src/components/Card/Card.test.tsx index c272998614..40a746dbd6 100644 --- a/packages/lib/src/components/Card/Card.test.tsx +++ b/packages/lib/src/components/Card/Card.test.tsx @@ -128,18 +128,46 @@ describe('Card', () => { }); }); - // describe('formatData', () => { - // test.only('should echo back holderName in storedPaymentMethods', () => { - // const i18n = global.i18n; - // const resources = global.resources; - // const srPanel = global.srPanel; - - // const card = new CardElement({ loadingContext: 'test', i18n, modules: {resources, srPanel}, storedPaymentMethodId: 'xxx', holderName: 'Test Holder' }); - // render(card.render()); - - // expect(card.formatData().paymentMethod).toContain('Test Holder'); - // }); - // }) + describe('formatData', () => { + const i18n = global.i18n; + const resources = global.resources; + const srPanel = global.srPanel; + + const coreProps = { loadingContext: 'test', i18n, modules: { resources, srPanel } }; + + test('should echo back holderName if is a stored card', () => { + const card = new CardElement({ ...coreProps, storedPaymentMethodId: 'xxx', holderName: 'Test Holder' }); + render(card.render()); + + expect(card.formatData().paymentMethod.holderName).toContain('Test Holder'); + }); + + test('should NOT echo back holderName from data if is a stored card', () => { + const card = new CardElement({ ...coreProps, storedPaymentMethodId: 'xxx', data: { holderName: 'Test Holder' } }); + render(card.render()); + + expect(card.formatData().paymentMethod.holderName).toContain(''); + }); + + test('if no holderName specificed and is stored card, holder name should be empty string', () => { + const card = new CardElement({ ...coreProps, storedPaymentMethodId: 'xxx' }); + + expect(card.formatData().paymentMethod.holderName).toContain(''); + }); + + test('if no holderName specificed and is not stored card, holder name should be empty string', () => { + const card = new CardElement({ ...coreProps, storedPaymentMethodId: 'xxx' }); + + expect(card.formatData().paymentMethod.holderName).toContain(''); + }); + + test('should NOT echo back holderName if is not a stored card', () => { + const card = new CardElement({ ...coreProps, holderName: 'Test Holder' }); + render(card.render()); + + expect(card.formatData().paymentMethod.holderName).toBeUndefined(); + }); + }); describe('isValid', () => { test('returns false if there is no state', () => { diff --git a/packages/lib/src/components/Card/Card.tsx b/packages/lib/src/components/Card/Card.tsx index 6c19faa3a3..524db985af 100644 --- a/packages/lib/src/components/Card/Card.tsx +++ b/packages/lib/src/components/Card/Card.tsx @@ -80,8 +80,6 @@ export class CardElement extends UIElement { ...props, // Mismatch between hasHolderName & holderNameRequired which can mean card can never be valid holderNameRequired: !props.hasHolderName ? false : props.holderNameRequired, - // Force hasHolderName if it's a storedPayment method, and has holderName - hasHolderName: props.storedPaymentMethodId ? true : props.hasHolderName, // False for *stored* BCMC cards & if merchant explicitly wants to hide the CVC field hasCVC: !((props.brand && props.brand === 'bcmc') || props.hideCVC), // billingAddressRequired only available for non-stored cards @@ -127,12 +125,14 @@ export class CardElement extends UIElement { * the shopper makes a brand selection */ const cardBrand = this.state.selectedBrandValue || this.props.brand; - return { paymentMethod: { type: CardElement.type, ...this.state.data, - ...(this.props.storedPaymentMethodId && { storedPaymentMethodId: this.props.storedPaymentMethodId }), + ...(this.props.storedPaymentMethodId && { + storedPaymentMethodId: this.props.storedPaymentMethodId, + holderName: this.props.holderName ?? '' + }), ...(cardBrand && { brand: cardBrand }), ...(this.props.fundingSource && { fundingSource: this.props.fundingSource }) }, diff --git a/packages/lib/src/components/Card/components/CardInput/CardInput.test.tsx b/packages/lib/src/components/Card/components/CardInput/CardInput.test.tsx index 8b46714e87..ab788c8c03 100644 --- a/packages/lib/src/components/Card/components/CardInput/CardInput.test.tsx +++ b/packages/lib/src/components/Card/components/CardInput/CardInput.test.tsx @@ -150,14 +150,6 @@ describe('CardInput > holderName', () => { expect(data.holderName).toBe('J Smith'); }); - // test('holderName ', () => { - // const dataObj = { holderName: 'J Smith' }; - // mount(); - - // expect(valid.holderName).toBe(true); - // expect(data.holderName).toBe('J Smith'); - // }); - test('does not show the holder name first by default', () => { render(); diff --git a/packages/lib/src/components/Card/components/CardInput/CardInput.tsx b/packages/lib/src/components/Card/components/CardInput/CardInput.tsx index 63f861039d..cdc08c98e3 100644 --- a/packages/lib/src/components/Card/components/CardInput/CardInput.tsx +++ b/packages/lib/src/components/Card/components/CardInput/CardInput.tsx @@ -75,10 +75,8 @@ const CardInput: FunctionalComponent = props => { const [valid, setValid] = useState({ ...(props.holderNameRequired && { holderName: false }) }); - - const defaultHolderName = props.data.holderName ?? props.holderName ?? ''; const [data, setData] = useState({ - ...(props.hasHolderName && { holderName: defaultHolderName }) + ...(props.hasHolderName && { holderName: props.data.holderName ?? '' }) }); const [sortedErrorList, setSortedErrorList] = useState(null); @@ -124,7 +122,7 @@ const CardInput: FunctionalComponent = props => { setErrors: setFormErrors } = useForm({ schema: [], - defaultData: { ...props.data, holderName: defaultHolderName }, + defaultData: props.data, formatters: cardInputFormatters, rules: cardInputValidationRules });