diff --git a/addon/components/square-payment-form.js b/addon/components/square-payment-form.js index 96a3287..1836cfa 100644 --- a/addon/components/square-payment-form.js +++ b/addon/components/square-payment-form.js @@ -735,6 +735,8 @@ export default Component.extend({ nonce, this.createVerificationDetails(), (verificationErrors, result) => { + const verificationToken = result ? result.token : null; + this.onCardNonceResponseReceived( errors, nonce, @@ -742,7 +744,7 @@ export default Component.extend({ billingContact, shippingContact, shippingOption, - result.token + verificationToken ); } ); diff --git a/tests/browser/sca.test.js b/tests/browser/sca.test.js new file mode 100644 index 0000000..1498c6c --- /dev/null +++ b/tests/browser/sca.test.js @@ -0,0 +1,89 @@ +describe('Card-Only Payment FormĀ w/SCA Enabled', () => { + beforeAll(async () => { + await page.goto('http://localhost:4200'); + jest.setTimeout(90000); + }); + + it('can get a nonce', async () => { + await page.goto('http://localhost:4200/testing/card-only-sca'); + await page.waitFor('iframe.square-payment-form--styled--light__input'); + + const [ + ccInputFrame, + expDateInputFrame, + cvvInputFrame, + postalCodeInputFrame + ] = await page.$$('iframe.square-payment-form--styled--light__input'); + + // Allow iframes to fully load. + await page.waitFor(1000); + + await ccInputFrame.focus('input'); + await page.keyboard.type('4310 0000 0000 0007'); + + await expDateInputFrame.focus('input'); + await page.keyboard.type('12/24'); + + await cvvInputFrame.focus('input'); + await page.keyboard.type('111'); + + await postalCodeInputFrame.focus('input'); + await page.keyboard.type('12345'); + + await page.click('button.square-payment-form--styled__button--charge'); + await page.waitFor('iframe#sq-nudata-iframe'); + + const scaFrame = await page.$('#sq-nudata-iframe'); + const scaFrameContent = await scaFrame.contentFrame(); + + await scaFrameContent.waitFor('#userDataEntry'); + await scaFrameContent.focus('#userDataEntry'); + await page.keyboard.type('123456'); + await scaFrameContent.click('#verify-challenge-btn'); + + await page.waitFor('.nonce-response'); + + const errorsHandle = await page.$('.nonce-response__errors'); + const nonceHandle = await page.$('.nonce-response__nonce'); + const cardDataHandle = await page.$('.nonce-response__card-data'); + const billingContactHandle = await page.$('.nonce-response__billing-contact'); + const shippingContactHandle = await page.$('.nonce-response__shipping-contact'); + const shippingOptionHandle = await page.$('.nonce-response__shipping-option'); + const verificationTokenHandle = await page.$('.nonce-response__verification-token'); + + await expect( + await errorsHandle.evaluate(node => node.innerText) + ).toBe('null'); + + await expect( + await nonceHandle.evaluate(node => node.innerText) + ).toMatch('cnon:'); + + await expect( + await cardDataHandle.evaluate(node => node.innerText) + ).toMatch(`{ + "digital_wallet_type": "NONE", + "card_brand": "VISA", + "last_4": "0007", + "exp_month": 12, + "exp_year": 2024, + "billing_postal_code": "12345" +}`); + + await expect( + await billingContactHandle.evaluate(node => node.innerText) + ).toMatch(''); + + await expect( + await shippingContactHandle.evaluate(node => node.innerText) + ).toMatch(''); + + await expect( + await shippingOptionHandle.evaluate(node => node.innerText) + ).toMatch(''); + + await expect( + await verificationTokenHandle.evaluate(node => node.innerText) + ).toMatch('verf:'); + }); +}); diff --git a/tests/dummy/app/controllers/.gitkeep b/tests/dummy/app/controllers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/dummy/app/controllers/testing/card-only-sca.js b/tests/dummy/app/controllers/testing/card-only-sca.js new file mode 100644 index 0000000..2e63695 --- /dev/null +++ b/tests/dummy/app/controllers/testing/card-only-sca.js @@ -0,0 +1,29 @@ +import Controller from '@ember/controller'; + +export default Controller.extend({ + nonceResponse: null, + + actions: { + createVerificationDetails() { + return { + billingContact: { + givenName: 'Dean' + }, + currencyCode: 'USD', + intent: 'CHARGE', + amount: '1000.00' + }; + }, + handleCardNonceResponse(errors, nonce, cardData, billingContact, shippingContact, shippingOption, verificationToken) { + this.set('nonceResponse', { + errors: JSON.stringify(errors, null, ' '), + nonce, + cardData: JSON.stringify(cardData, null, ' '), + billingContact: JSON.stringify(billingContact, null, ' '), + shippingContact: JSON.stringify(shippingContact, null, ' '), + shippingOption: JSON.stringify(shippingOption, null, ' '), + verificationToken + }); + } + } +}); diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 0adeda5..5a0e5d8 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -9,6 +9,7 @@ const Router = AddonDocsRouter.extend({ Router.map(function() { this.route('testing', function() { this.route('card-only'); + this.route('card-only-sca'); }); this.route('examples', function() { diff --git a/tests/dummy/app/templates/testing/card-only-sca.hbs b/tests/dummy/app/templates/testing/card-only-sca.hbs new file mode 100644 index 0000000..f5f6d41 --- /dev/null +++ b/tests/dummy/app/templates/testing/card-only-sca.hbs @@ -0,0 +1,21 @@ + + +{{#if nonceResponse}} +
+

Results

+
{{nonceResponse.errors}}
+
{{nonceResponse.nonce}}
+
{{nonceResponse.cardData}}
+
{{nonceResponse.billingContact}}
+
{{nonceResponse.shippingContact}}
+
{{nonceResponse.shippingOption}}
+
{{nonceResponse.verificationToken}}
+
+{{/if}} \ No newline at end of file