From 121ce3b5db06377f6f277ab7bb1924e55763f9d7 Mon Sep 17 00:00:00 2001 From: guilhermer Date: Tue, 19 Nov 2024 12:56:05 +0100 Subject: [PATCH] ratepay tests --- .../tests/e2e/openInvoices/ratepay.spec.ts | 54 ---- .../src/components/RatePay/RatePay.test.ts | 219 ++++++++++++++++ .../src/components/RatePay/RatePay.test.tsx | 17 -- .../RatePay/RatePayDirectDebit.test.ts | 237 ++++++++++++++++++ .../RatePayDirectDebit.stories.tsx | 24 ++ 5 files changed, 480 insertions(+), 71 deletions(-) delete mode 100644 packages/e2e-playwright/tests/e2e/openInvoices/ratepay.spec.ts create mode 100644 packages/lib/src/components/RatePay/RatePay.test.ts delete mode 100644 packages/lib/src/components/RatePay/RatePay.test.tsx create mode 100644 packages/lib/src/components/RatePay/RatePayDirectDebit.test.ts create mode 100644 packages/lib/storybook/stories/open-invoice/RatePayDirectDebit.stories.tsx diff --git a/packages/e2e-playwright/tests/e2e/openInvoices/ratepay.spec.ts b/packages/e2e-playwright/tests/e2e/openInvoices/ratepay.spec.ts deleted file mode 100644 index 9b03349174..0000000000 --- a/packages/e2e-playwright/tests/e2e/openInvoices/ratepay.spec.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { test } from '../../../fixtures/openInvoices.fixture'; - -const getComponentData = () => { - return globalThis.component.data; -}; - -const mockAddressGermany = { - city: 'City', - country: 'DE', - houseNumberOrName: '123', - postalCode: '12345', - stateOrProvince: 'N/A', - street: 'Street' -}; - -test('should make a Ratepay payment', async () => { - // Fill in the form data - // Check the consent checkbox - // Submit the payment - // Expect success payment - // const checkboxLabelGender = Selector('.ratepay-direct-field .adyen-checkout__field--gender .adyen-checkout__radio_group__label'); - // const payButton = Selector('.ratepay-direct-field adyen-checkout__button--pay'); - // - // // Opens dropdown - // await t - // .typeText('.ratepay-direct-field .adyen-checkout__input--firstName', 'First') - // .typeText('.ratepay-direct-field .adyen-checkout__input--lastName', 'Last') - // // Click checkbox (in reality click its label - for some reason clicking the actual checkboxes takes ages) - // .click(checkboxLabelGender.nth(0)) - // .typeText('.ratepay-direct-field .adyen-checkout__input--dateOfBirth', '01011990', { caretPos: 1 }) - // .typeText('.ratepay-direct-field .adyen-checkout__input--shopperEmail', 'test@test.com') - // .typeText('.ratepay-direct-field .adyen-checkout__input--telephoneNumber', '612345678') - // .typeText('.ratepay-direct-field .adyen-checkout__iban-input__owner-name', 'A. Schneider') - // .typeText('.ratepay-direct-field .adyen-checkout__iban-input__iban-number', 'DE87123456781234567890') - // .typeText('.ratepay-direct-field .adyen-checkout__input--street', mockAddressGermany.street) - // .typeText('.ratepay-direct-field .adyen-checkout__input--houseNumberOrName', mockAddressGermany.houseNumberOrName) - // .typeText('.ratepay-direct-field .adyen-checkout__input--city', mockAddressGermany.city) - // .typeText('.ratepay-direct-field .adyen-checkout__input--postalCode', mockAddressGermany.postalCode) - // // Can't use the checkboxLabelGender trick to speed up the click 'cos this label contains a link - so use a Selector with a timeout - // .click(payButton) - // .wait(5000); -}); - -test('should not submit a Ratepay payment if the form in not valid', async () => { - // Fill in the wrong form data - // Click pay button - // Expect error -}); - -test('should not submit a Ratepay payment if the consent checkbox is not checked', async () => { - // Fill in the wrong form data - // Click pay button - // Expect error -}); diff --git a/packages/lib/src/components/RatePay/RatePay.test.ts b/packages/lib/src/components/RatePay/RatePay.test.ts new file mode 100644 index 0000000000..a7cd0e9cb7 --- /dev/null +++ b/packages/lib/src/components/RatePay/RatePay.test.ts @@ -0,0 +1,219 @@ +import RatePay from './RatePay'; +import { render, screen, within } from '@testing-library/preact'; +import userEvent from '@testing-library/user-event'; +import { setupServer } from 'msw/node'; +import { http, HttpResponse } from 'msw'; + +const server = setupServer( + http.get('https://checkoutshopper-live.adyen.com/checkoutshopper/datasets/countries/en-US.json', () => { + return HttpResponse.json([{ id: 'DE', name: 'Germany' }]); + }) +); + +beforeAll(() => server.listen()); +afterEach(() => server.resetHandlers()); +afterAll(() => server.close()); + +describe('RatePay Direct Debit', () => { + test('should make a payment', async () => { + const user = userEvent.setup(); + const onSubmitMock = jest.fn(); + + const ratepay = new RatePay(global.core, { + countryCode: 'DE', + modules: { analytics: global.analytics, resources: global.resources, srPanel: global.srPanel }, + i18n: global.i18n, + onSubmit: onSubmitMock, + loadingContext: 'https://checkoutshopper-live.adyen.com/checkoutshopper/' + }); + + render(ratepay.render()); + + const firstNameInput = await screen.findByLabelText('First name'); + const lastNameInput = await screen.findByLabelText('Last name'); + const maleRadioInput = await screen.findByLabelText('Male'); + const dateOfBirthInput = await screen.findByLabelText('Date of birth'); + const emailAddressInput = await screen.findByLabelText('Email address'); + const telephoneNumberInput = await screen.findByLabelText('Telephone number'); + + const streetInput = await screen.findByLabelText('Street'); + const houseNumberInput = await screen.findByLabelText('House number'); + const postalCodeInput = await screen.findByLabelText('Postal code'); + const cityInput = await screen.findByLabelText('City'); + + // Personal details + await user.type(firstNameInput, 'Jose'); + await user.type(lastNameInput, 'Fernandez'); + await user.click(maleRadioInput); + await user.type(dateOfBirthInput, '1990-01-01'); + await user.type(emailAddressInput, 'jose@adyen.com'); + await user.type(telephoneNumberInput, '612345678'); + + // Billing address + await user.type(streetInput, 'Lichtenberger Str'); + await user.type(houseNumberInput, '100000'); + await user.type(postalCodeInput, '10179'); + await user.type(cityInput, 'Berlin'); + + const payButton = await screen.findByRole('button', { name: 'Confirm purchase' }); + await user.click(payButton); + + expect(onSubmitMock).toHaveBeenCalledTimes(1); + expect(onSubmitMock).toHaveBeenCalledWith( + expect.objectContaining({ + data: { + billingAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '100000', + postalCode: '10179', + stateOrProvince: 'N/A', + street: 'Lichtenberger Str' + }, + clientStateDataIndicator: true, + dateOfBirth: '1990-01-01', + deliveryAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '100000', + postalCode: '10179', + stateOrProvince: 'N/A', + street: 'Lichtenberger Str' + }, + paymentMethod: { checkoutAttemptId: 'fetch-checkoutAttemptId-failed', type: 'ratepay' }, + shopperEmail: 'jose@adyen.com', + shopperName: { firstName: 'Jose', gender: 'MALE', lastName: 'Fernandez' }, + telephoneNumber: '612345678' + }, + isValid: true + }), + expect.anything(), + expect.anything() + ); + }); + + test('should send a different delivery address when checking the checkbox', async () => { + const user = userEvent.setup(); + const onSubmitMock = jest.fn(); + + const ratepay = new RatePay(global.core, { + countryCode: 'DE', + modules: { analytics: global.analytics, resources: global.resources, srPanel: global.srPanel }, + i18n: global.i18n, + onSubmit: onSubmitMock, + loadingContext: 'https://checkoutshopper-live.adyen.com/checkoutshopper/' + }); + + const { container } = render(ratepay.render()); + + const firstNameInput = await screen.findByLabelText('First name'); + const lastNameInput = await screen.findByLabelText('Last name'); + const maleRadioInput = await screen.findByLabelText('Male'); + const dateOfBirthInput = await screen.findByLabelText('Date of birth'); + const emailAddressInput = await screen.findByLabelText('Email address'); + const telephoneNumberInput = await screen.findByLabelText('Telephone number'); + + const streetInput = await screen.findByLabelText('Street'); + const houseNumberInput = await screen.findByLabelText('House number'); + const postalCodeInput = await screen.findByLabelText('Postal code'); + const cityInput = await screen.findByLabelText('City'); + + // Personal details + await user.type(firstNameInput, 'Jose'); + await user.type(lastNameInput, 'Fernandez'); + await user.click(maleRadioInput); + await user.type(dateOfBirthInput, '1990-01-01'); + await user.type(emailAddressInput, 'jose@adyen.com'); + await user.type(telephoneNumberInput, '612345678'); + + // Billing address + await user.type(streetInput, 'Lichtenberger Str'); + await user.type(houseNumberInput, '100000'); + await user.type(postalCodeInput, '10179'); + await user.type(cityInput, 'Berlin'); + + const deliveryAddressCheckbox = await screen.findByRole('checkbox', { name: 'Specify a separate delivery address' }); + await user.click(deliveryAddressCheckbox); + + // eslint-disable-next-line testing-library/no-node-access,testing-library/no-container + const [deliveryAddressSection] = container.querySelectorAll('.adyen-checkout__fieldset--deliveryAddress'); + + const deliveryStreetInput = await within(deliveryAddressSection).findByLabelText('Street'); + const deliveryHouseNumberInput = await within(deliveryAddressSection).findByLabelText('House number'); + const deliveryPostalCodeInput = await within(deliveryAddressSection).findByLabelText('Postal code'); + const deliveryCityInput = await within(deliveryAddressSection).findByLabelText('City'); + + // Delivery address + await user.type(deliveryStreetInput, 'Carmilgestraat'); + await user.type(deliveryHouseNumberInput, '62813'); + await user.type(deliveryPostalCodeInput, '00089'); + await user.type(deliveryCityInput, 'Berlin'); + + const payButton = await screen.findByRole('button', { name: 'Confirm purchase' }); + await user.click(payButton); + + expect(onSubmitMock).toHaveBeenCalledTimes(1); + expect(onSubmitMock).toHaveBeenCalledWith( + expect.objectContaining({ + data: { + billingAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '100000', + postalCode: '10179', + stateOrProvince: 'N/A', + street: 'Lichtenberger Str' + }, + clientStateDataIndicator: true, + dateOfBirth: '1990-01-01', + deliveryAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '62813', + postalCode: '00089', + stateOrProvince: 'N/A', + street: 'Carmilgestraat' + }, + paymentMethod: { checkoutAttemptId: 'fetch-checkoutAttemptId-failed', type: 'ratepay' }, + shopperEmail: 'jose@adyen.com', + shopperName: { firstName: 'Jose', gender: 'MALE', lastName: 'Fernandez' }, + telephoneNumber: '612345678' + }, + isValid: true + }), + expect.anything(), + expect.anything() + ); + }); + + test('should not submit the payment if form is not valid', async () => { + const user = userEvent.setup(); + const onSubmitMock = jest.fn(); + + const ratepay = new RatePay(global.core, { + countryCode: 'DE', + modules: { analytics: global.analytics, resources: global.resources, srPanel: global.srPanel }, + i18n: global.i18n, + onSubmit: onSubmitMock, + loadingContext: 'https://checkoutshopper-live.adyen.com/checkoutshopper/' + }); + + render(ratepay.render()); + + const payButton = await screen.findByRole('button', { name: 'Confirm purchase' }); + await user.click(payButton); + + expect(onSubmitMock).toHaveBeenCalledTimes(0); + + expect(screen.getByText('Enter your first name')).toBeInTheDocument(); + expect(screen.getByText('Enter your last name')).toBeInTheDocument(); + expect(screen.getByText('Select your gender')).toBeInTheDocument(); + expect(screen.getByText('Enter the date of birth')).toBeInTheDocument(); + expect(screen.getByText('Enter the email address')).toBeInTheDocument(); + expect(screen.getByText('Enter the telephone number')).toBeInTheDocument(); + expect(screen.getByText('Enter the street')).toBeInTheDocument(); + expect(screen.getByText('Enter the house number')).toBeInTheDocument(); + expect(screen.getByText('Enter the postal code')).toBeInTheDocument(); + expect(screen.getByText('Enter the city')).toBeInTheDocument(); + }); +}); diff --git a/packages/lib/src/components/RatePay/RatePay.test.tsx b/packages/lib/src/components/RatePay/RatePay.test.tsx deleted file mode 100644 index 3f736fe368..0000000000 --- a/packages/lib/src/components/RatePay/RatePay.test.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import RatePay from './RatePay'; - -describe('RatePay', () => { - describe('isValid', () => { - test('returns false if there is no state', () => { - const ratePay = new RatePay(global.core); - expect(ratePay.isValid).toBe(false); - }); - }); - - describe('get data', () => { - test('returns a type', () => { - const ratePay = new RatePay(global.core); - expect(ratePay.data.paymentMethod.type).toBe('ratepay'); - }); - }); -}); diff --git a/packages/lib/src/components/RatePay/RatePayDirectDebit.test.ts b/packages/lib/src/components/RatePay/RatePayDirectDebit.test.ts new file mode 100644 index 0000000000..4b184e9dac --- /dev/null +++ b/packages/lib/src/components/RatePay/RatePayDirectDebit.test.ts @@ -0,0 +1,237 @@ +import RatePayDirectDebit from './RatePayDirectDebit'; +import { render, screen, within } from '@testing-library/preact'; +import userEvent from '@testing-library/user-event'; +import { setupServer } from 'msw/node'; +import { http, HttpResponse } from 'msw'; + +const server = setupServer( + http.get('https://checkoutshopper-live.adyen.com/checkoutshopper/datasets/countries/en-US.json', () => { + return HttpResponse.json([{ id: 'DE', name: 'Germany' }]); + }) +); + +beforeAll(() => server.listen()); +afterEach(() => server.resetHandlers()); +afterAll(() => server.close()); + +describe('RatePay Direct Debit', () => { + test('should make a payment', async () => { + const user = userEvent.setup(); + const onSubmitMock = jest.fn(); + + const ratepay = new RatePayDirectDebit(global.core, { + countryCode: 'DE', + modules: { analytics: global.analytics, resources: global.resources, srPanel: global.srPanel }, + i18n: global.i18n, + onSubmit: onSubmitMock, + loadingContext: 'https://checkoutshopper-live.adyen.com/checkoutshopper/' + }); + + render(ratepay.render()); + + const firstNameInput = await screen.findByLabelText('First name'); + const lastNameInput = await screen.findByLabelText('Last name'); + const maleRadioInput = await screen.findByLabelText('Male'); + const dateOfBirthInput = await screen.findByLabelText('Date of birth'); + const emailAddressInput = await screen.findByLabelText('Email address'); + const telephoneNumberInput = await screen.findByLabelText('Telephone number'); + + const holderNameInput = await screen.findByLabelText('Holder Name'); + const accountNumberInput = await screen.findByLabelText('Account Number (IBAN)'); + + const streetInput = await screen.findByLabelText('Street'); + const houseNumberInput = await screen.findByLabelText('House number'); + const postalCodeInput = await screen.findByLabelText('Postal code'); + const cityInput = await screen.findByLabelText('City'); + + // Personal details + await user.type(firstNameInput, 'Jose'); + await user.type(lastNameInput, 'Fernandez'); + await user.click(maleRadioInput); + await user.type(dateOfBirthInput, '1990-01-01'); + await user.type(emailAddressInput, 'jose@adyen.com'); + await user.type(telephoneNumberInput, '612345678'); + + // Bank account + await user.type(holderNameInput, 'A. Schneider'); + await user.type(accountNumberInput, 'DE87123456781234567890'); + + // Billing address + await user.type(streetInput, 'Lichtenberger Str'); + await user.type(houseNumberInput, '100000'); + await user.type(postalCodeInput, '10179'); + await user.type(cityInput, 'Berlin'); + + const payButton = await screen.findByRole('button', { name: 'Confirm purchase' }); + await user.click(payButton); + + expect(onSubmitMock).toHaveBeenCalledTimes(1); + expect(onSubmitMock).toHaveBeenCalledWith( + expect.objectContaining({ + data: { + bankAccount: { countryCode: 'DE', iban: 'DE87 1234 5678 1234 5678 90', ownerName: 'A. Schneider' }, + billingAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '100000', + postalCode: '10179', + stateOrProvince: 'N/A', + street: 'Lichtenberger Str' + }, + clientStateDataIndicator: true, + dateOfBirth: '1990-01-01', + deliveryAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '100000', + postalCode: '10179', + stateOrProvince: 'N/A', + street: 'Lichtenberger Str' + }, + paymentMethod: { checkoutAttemptId: 'fetch-checkoutAttemptId-failed', type: 'ratepay_directdebit' }, + shopperEmail: 'jose@adyen.com', + shopperName: { firstName: 'Jose', gender: 'MALE', lastName: 'Fernandez' }, + telephoneNumber: '612345678' + }, + isValid: true + }), + expect.anything(), + expect.anything() + ); + }); + + test('should send a different delivery address when checking the checkbox', async () => { + const user = userEvent.setup(); + const onSubmitMock = jest.fn(); + + const ratepay = new RatePayDirectDebit(global.core, { + countryCode: 'DE', + modules: { analytics: global.analytics, resources: global.resources, srPanel: global.srPanel }, + i18n: global.i18n, + onSubmit: onSubmitMock, + loadingContext: 'https://checkoutshopper-live.adyen.com/checkoutshopper/' + }); + + const { container } = render(ratepay.render()); + + const firstNameInput = await screen.findByLabelText('First name'); + const lastNameInput = await screen.findByLabelText('Last name'); + const maleRadioInput = await screen.findByLabelText('Male'); + const dateOfBirthInput = await screen.findByLabelText('Date of birth'); + const emailAddressInput = await screen.findByLabelText('Email address'); + const telephoneNumberInput = await screen.findByLabelText('Telephone number'); + + const holderNameInput = await screen.findByLabelText('Holder Name'); + const accountNumberInput = await screen.findByLabelText('Account Number (IBAN)'); + + const streetInput = await screen.findByLabelText('Street'); + const houseNumberInput = await screen.findByLabelText('House number'); + const postalCodeInput = await screen.findByLabelText('Postal code'); + const cityInput = await screen.findByLabelText('City'); + + // Personal details + await user.type(firstNameInput, 'Jose'); + await user.type(lastNameInput, 'Fernandez'); + await user.click(maleRadioInput); + await user.type(dateOfBirthInput, '1990-01-01'); + await user.type(emailAddressInput, 'jose@adyen.com'); + await user.type(telephoneNumberInput, '612345678'); + + // Bank account + await user.type(holderNameInput, 'A. Schneider'); + await user.type(accountNumberInput, 'DE87123456781234567890'); + + // Billing address + await user.type(streetInput, 'Lichtenberger Str'); + await user.type(houseNumberInput, '100000'); + await user.type(postalCodeInput, '10179'); + await user.type(cityInput, 'Berlin'); + + const deliveryAddressCheckbox = await screen.findByRole('checkbox', { name: 'Specify a separate delivery address' }); + await user.click(deliveryAddressCheckbox); + + // eslint-disable-next-line testing-library/no-node-access,testing-library/no-container + const [deliveryAddressSection] = container.querySelectorAll('.adyen-checkout__fieldset--deliveryAddress'); + + const deliveryStreetInput = await within(deliveryAddressSection).findByLabelText('Street'); + const deliveryHouseNumberInput = await within(deliveryAddressSection).findByLabelText('House number'); + const deliveryPostalCodeInput = await within(deliveryAddressSection).findByLabelText('Postal code'); + const deliveryCityInput = await within(deliveryAddressSection).findByLabelText('City'); + + // Delivery address + await user.type(deliveryStreetInput, 'Carmilgestraat'); + await user.type(deliveryHouseNumberInput, '62813'); + await user.type(deliveryPostalCodeInput, '00089'); + await user.type(deliveryCityInput, 'Berlin'); + + const payButton = await screen.findByRole('button', { name: 'Confirm purchase' }); + await user.click(payButton); + + expect(onSubmitMock).toHaveBeenCalledTimes(1); + expect(onSubmitMock).toHaveBeenCalledWith( + expect.objectContaining({ + data: { + bankAccount: { countryCode: 'DE', iban: 'DE87 1234 5678 1234 5678 90', ownerName: 'A. Schneider' }, + billingAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '100000', + postalCode: '10179', + stateOrProvince: 'N/A', + street: 'Lichtenberger Str' + }, + clientStateDataIndicator: true, + dateOfBirth: '1990-01-01', + deliveryAddress: { + city: 'Berlin', + country: 'DE', + houseNumberOrName: '62813', + postalCode: '00089', + stateOrProvince: 'N/A', + street: 'Carmilgestraat' + }, + paymentMethod: { checkoutAttemptId: 'fetch-checkoutAttemptId-failed', type: 'ratepay_directdebit' }, + shopperEmail: 'jose@adyen.com', + shopperName: { firstName: 'Jose', gender: 'MALE', lastName: 'Fernandez' }, + telephoneNumber: '612345678' + }, + isValid: true + }), + expect.anything(), + expect.anything() + ); + }); + + test('should not submit the payment if form is not valid', async () => { + const user = userEvent.setup(); + const onSubmitMock = jest.fn(); + + const ratepay = new RatePayDirectDebit(global.core, { + countryCode: 'DE', + modules: { analytics: global.analytics, resources: global.resources, srPanel: global.srPanel }, + i18n: global.i18n, + onSubmit: onSubmitMock, + loadingContext: 'https://checkoutshopper-live.adyen.com/checkoutshopper/' + }); + + render(ratepay.render()); + + const payButton = await screen.findByRole('button', { name: 'Confirm purchase' }); + await user.click(payButton); + + expect(onSubmitMock).toHaveBeenCalledTimes(0); + + expect(screen.getByText('Enter your first name')).toBeInTheDocument(); + expect(screen.getByText('Enter your last name')).toBeInTheDocument(); + expect(screen.getByText('Select your gender')).toBeInTheDocument(); + expect(screen.getByText('Enter the date of birth')).toBeInTheDocument(); + expect(screen.getByText('Enter the email address')).toBeInTheDocument(); + expect(screen.getByText('Enter the telephone number')).toBeInTheDocument(); + expect(screen.getByText('Invalid account holder name')).toBeInTheDocument(); + expect(screen.getByText('Invalid account number')).toBeInTheDocument(); + expect(screen.getByText('Enter the street')).toBeInTheDocument(); + expect(screen.getByText('Enter the house number')).toBeInTheDocument(); + expect(screen.getByText('Enter the postal code')).toBeInTheDocument(); + expect(screen.getByText('Enter the city')).toBeInTheDocument(); + }); +}); diff --git a/packages/lib/storybook/stories/open-invoice/RatePayDirectDebit.stories.tsx b/packages/lib/storybook/stories/open-invoice/RatePayDirectDebit.stories.tsx new file mode 100644 index 0000000000..e329a726ed --- /dev/null +++ b/packages/lib/storybook/stories/open-invoice/RatePayDirectDebit.stories.tsx @@ -0,0 +1,24 @@ +import { MetaConfiguration, StoryConfiguration } from '../types'; +import { OpenInvoiceConfiguration } from '../../../src/components/types'; +import { ComponentContainer } from '../ComponentContainer'; +import RatePayDirectDebit from '../../../src/components/RatePay/RatePayDirectDebit'; +import { Checkout } from '../Checkout'; + +type RatePayDirectDebitStory = StoryConfiguration; + +const meta: MetaConfiguration = { + title: 'OpenInvoice/RatePayDirectDebit' +}; + +export const Default: RatePayDirectDebitStory = { + render: ({ componentConfiguration, ...checkoutConfig }) => ( + + {checkout => } + + ), + args: { + countryCode: 'NL' + } +}; + +export default meta;