Skip to content

Commit

Permalink
feat(PAYMENTS-21797): add form submit action
Browse files Browse the repository at this point in the history
  • Loading branch information
simbirromanmakarov committed Dec 12, 2024
1 parent 9b0805a commit 29c5c57
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 38 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ declare const headlessCheckout: {
* Allows you to prepare components before a user can interact with them.
*/
activate(): void;

/**
* Initiate form submit.
* To get submit action response listen onNextAction events
*/
submit(): void;
};

/**
Expand Down
10 changes: 10 additions & 0 deletions src/features/headless-checkout/headless-checkout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FormStatus } from '../../core/status/form-status.enum';
import { noopStub } from '../../tests/stubs/noop.stub';
import { headlessCheckoutAppUrl } from './environment';
import { ThemesLoader } from '../../core/customization/themes-loader';
import { submitHandler } from './post-messages-handlers/submit/submit.handler';

const mockMessage: Message = {
name: EventName.initPayment,
Expand Down Expand Up @@ -247,4 +248,13 @@ describe('HeadlessCheckout', () => {
headlessCheckout.form.onFieldsStatusChange(noopStub);
expect(spy).toHaveBeenCalled();
});

it('Should init', async () => {

Check failure on line 252 in src/features/headless-checkout/headless-checkout.spec.ts

View workflow job for this annotation

GitHub Actions / lint

Async arrow function has no 'await' expression
const spy = spyOn(postMessagesClient, 'send');
headlessCheckout.form.submit();

Check failure on line 254 in src/features/headless-checkout/headless-checkout.spec.ts

View workflow job for this annotation

GitHub Actions / lint

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
expect(spy).toHaveBeenCalledWith(
{ name: EventName.submitForm },
submitHandler,
);
});
});
17 changes: 16 additions & 1 deletion src/features/headless-checkout/headless-checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { getCountryListHandler } from './post-messages-handlers/get-country-list
import { CountryResponse } from '../../core/country-response.interface';
import { FormLoader } from '../../core/form/form-loader';
import { InitialOptions } from './initial-options.interface';
import { submitHandler } from './post-messages-handlers/submit/submit.handler';

@singleton()
export class HeadlessCheckout {
Expand Down Expand Up @@ -138,8 +139,18 @@ export class HeadlessCheckout {
activate: (): void => {
this.formStatus = FormStatus.active;
},

setupAndAwaitFieldsLoading: async (fields: Field[]): Promise<void> =>
this.formLoader.setupAndAwaitFieldsLoading(fields),

submit: async (): Promise<void> => {
await this.postMessagesClient.send(
{
name: EventName.submitForm,
},
submitHandler,
);
},
};

public get formConfiguration(): FormConfiguration | undefined {
Expand Down Expand Up @@ -411,8 +422,12 @@ export class HeadlessCheckout {
private async listenCoreIframeLoading(): Promise<void> {
return new Promise((resolve) => {
const handler = (event: MessageEvent): void => {
if (typeof event.data !== 'string') {
return;
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (JSON.parse(event.data as string).name === EventName.isReady) {
if (JSON.parse(event.data).name === EventName.isReady) {
resolve();
this.window.removeEventListener('message', handler);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EventName } from '../../../../core/event-name.enum';
import { Message } from '../../../../core/message.interface';
import { PaymentMethod } from '../../../../core/payment-method.interface';
import { submitHandler } from './submit.handler';

const mockMessage: Message<{ methods: PaymentMethod[] }> = {
name: EventName.submitForm,
data: { methods: [] },
};
describe('submitHandler', () => {
it('Should handle data', () => {
expect(submitHandler(mockMessage)).toEqual({
isHandled: true,
});
});
it('Should return null', () => {
expect(submitHandler({ name: EventName.initPayment })).toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Handler } from '../../../../core/post-messages-client/handler.type';
import { Message } from '../../../../core/message.interface';
import { EventName } from '../../../../core/event-name.enum';

export const submitHandler: Handler<void> = (
message: Message,
): { isHandled: boolean } | null => {
if (message.name === EventName.submitForm) {
return {
isHandled: true,
};
}
return null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EventName } from '../../../../../core/event-name.enum';
import { HeadlessCheckout } from '../../../headless-checkout';
import { DefaultSubmitButtonAttributes } from './default-submit-button-attributes.enum';
import { getSubmitButtonTemplate } from './default-submit-button.template';
import { defaultSubmitButtonHandler } from './default-submit-button.handler';
import { submitHandler } from '../../../post-messages-handlers/submit/submit.handler';
import { Message } from '../../../../../core/message.interface';
import { Handler } from '../../../../../core/post-messages-client/handler.type';
import { isSubmitButtonLoadingMessage } from '../../../../../core/guards/submit-button-loading-message.guard';
Expand Down Expand Up @@ -75,7 +75,7 @@ export class DefaultSubmitButtonComponent extends WebComponentAbstract {

void this.postMessagesClient.send(
{ name: EventName.submitForm },
defaultSubmitButtonHandler,
submitHandler,
);

this.render();
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 29c5c57

Please sign in to comment.