Skip to content

Commit

Permalink
Merge pull request #52 from square/deanpapastrat/fix-null-token-sca-r…
Browse files Browse the repository at this point in the history
…eference

Fix null access error when an SCA validation fails
  • Loading branch information
deanpapastrat authored Jan 7, 2020
2 parents 4984685 + f1aaabf commit 899a22e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 1 deletion.
4 changes: 3 additions & 1 deletion addon/components/square-payment-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -735,14 +735,16 @@ export default Component.extend({
nonce,
this.createVerificationDetails(),
(verificationErrors, result) => {
const verificationToken = result ? result.token : null;

this.onCardNonceResponseReceived(
errors,
nonce,
cardData,
billingContact,
shippingContact,
shippingOption,
result.token
verificationToken
);
}
);
Expand Down
89 changes: 89 additions & 0 deletions tests/browser/sca.test.js
Original file line number Diff line number Diff line change
@@ -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:');
});
});
Empty file.
29 changes: 29 additions & 0 deletions tests/dummy/app/controllers/testing/card-only-sca.js
Original file line number Diff line number Diff line change
@@ -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
});
}
}
});
1 change: 1 addition & 0 deletions tests/dummy/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
21 changes: 21 additions & 0 deletions tests/dummy/app/templates/testing/card-only-sca.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<SquarePaymentFormStyled
@acceptCreditCards={{true}}
@applicationId="sandbox-sq0idb-TsZm7fSKPzmM1HRI9zDfAQ"
@locationId="0GHJWTYEMR5N1"
@style="light"
@onCardNonceResponseReceived={{action "handleCardNonceResponse"}}
@createVerificationDetails={{action "createVerificationDetails"}}
/>

{{#if nonceResponse}}
<div class="nonce-response">
<h3>Results</h3>
<pre class="nonce-response__errors">{{nonceResponse.errors}}</pre>
<pre class="nonce-response__nonce">{{nonceResponse.nonce}}</pre>
<pre class="nonce-response__card-data">{{nonceResponse.cardData}}</pre>
<pre class="nonce-response__billing-contact">{{nonceResponse.billingContact}}</pre>
<pre class="nonce-response__shipping-contact">{{nonceResponse.shippingContact}}</pre>
<pre class="nonce-response__shipping-option">{{nonceResponse.shippingOption}}</pre>
<pre class="nonce-response__verification-token">{{nonceResponse.verificationToken}}</pre>
</div>
{{/if}}

0 comments on commit 899a22e

Please sign in to comment.