Skip to content

Commit

Permalink
refactor: add onsubmit to PaymentCardEmbed
Browse files Browse the repository at this point in the history
  • Loading branch information
pheekus committed Jun 14, 2024
1 parent e4a5f8d commit 13fde73
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
36 changes: 27 additions & 9 deletions src/customer/PaymentCardEmbed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ import type { PaymentCardEmbedConfig } from './types';
* console.log('Token:', await embed.tokenize());
*/
export class PaymentCardEmbed {
/**
* An event handler that is triggered when Enter is pressed in the card form.
* This feature is not available for template sets configured with the `stripe_connect`
* hosted payment gateway due to the limitations of Stripe.js.
*/
onsubmit: (() => void) | null = null;

private __tokenizationRequests: {
resolve: (token: string) => void;
reject: () => void;
Expand All @@ -23,15 +30,26 @@ export class PaymentCardEmbed {
private __iframeMessageHandler = (evt: MessageEvent) => {
const data = JSON.parse(evt.data);

if (data.type === 'resize') {
if (this.__iframe) this.__iframe.style.height = data.height;
} else if (data.type === 'tokenization_response') {
const request = this.__tokenizationRequests.find(r => r.id === data.id);
data.token ? request?.resolve(data.token) : request?.reject();
this.__tokenizationRequests = this.__tokenizationRequests.filter(r => r.id !== data.id);
} else if (data.type === 'ready') {
this.configure(this.__config);
this.__mountingTask?.resolve();
switch (data.type) {
case 'tokenization_response': {
const request = this.__tokenizationRequests.find(r => r.id === data.id);
data.token ? request?.resolve(data.token) : request?.reject();
this.__tokenizationRequests = this.__tokenizationRequests.filter(r => r.id !== data.id);
break;
}
case 'submit': {
this.onsubmit?.();
break;
}
case 'resize': {
if (this.__iframe) this.__iframe.style.height = data.height;
break;
}
case 'ready': {
this.configure(this.__config);
this.__mountingTask?.resolve();
break;
}
}
};

Expand Down
18 changes: 18 additions & 0 deletions tests/customer/PaymentCardEmbed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,5 +270,23 @@ describe('Customer', () => {
// It must set the height of the iframe
expect(testIframe.style.height).toBe('200px');
});

it('calls .onsubmit on "submit" event', async () => {
const embed = new TestPaymentCardEmbed({ url: 'https://embed.foxy.test/v1.html?demo=default' });
const mountingPromise = embed.mount((new TestElement() as unknown) as Element);
const loadListener = testIframe.addEventListener.mock.calls.find(([event]) => event === 'load')[1];
const messageListener = testMessageChannel.port1.addEventListener.mock.calls.find(([e]) => e === 'message')[1];
const onSubmit = jest.fn();

await new Promise(resolve => setTimeout(resolve, 0));
loadListener({ currentTarget: testIframe });
messageListener({ data: JSON.stringify({ type: 'ready' }) });
await mountingPromise;
jest.clearAllMocks();
embed.onsubmit = onSubmit;
messageListener({ data: JSON.stringify({ type: 'submit' }) });

expect(onSubmit).toHaveBeenCalledTimes(1);
});
});
});

0 comments on commit 13fde73

Please sign in to comment.