diff --git a/packages/lib/src/components/internal/PhoneInputNew/PhoneInput.test.tsx b/packages/lib/src/components/internal/PhoneInputNew/PhoneInput.test.tsx new file mode 100644 index 0000000000..fce227c591 --- /dev/null +++ b/packages/lib/src/components/internal/PhoneInputNew/PhoneInput.test.tsx @@ -0,0 +1,69 @@ +import { h } from 'preact'; +import { fireEvent, render, screen } from '@testing-library/preact'; +import PhoneInput from './PhoneInput'; +import CoreProvider from '../../../core/Context/CoreProvider'; +import { Resources } from '../../../core/Context/Resources'; +import { PhoneInputProps } from './types'; +import userEvent from '@testing-library/user-event'; +import { resolveCDNEnvironment } from '../../../core/Environment'; + +const items = [{ id: '+44', name: 'United Kingdom', code: 'GB', selectedOptionName: 'United Kingdom' }]; + +describe('PhoneInput', () => { + const defaultProps: PhoneInputProps = { + items, + data: { phonePrefix: items[0].id }, + onChange: jest.fn(), + phoneNumberErrorKey: 'mobileNumber.invalid', + placeholders: {} + }; + + const renderPhoneInput = (props: PhoneInputProps = defaultProps) => { + return render( + // @ts-ignore ignore + + + + ); + }; + + test('should show phone prefix and phone number', async () => { + renderPhoneInput(); + expect(await screen.findByRole('combobox')).toBeTruthy(); + expect(await screen.findByRole('textbox')).toBeTruthy(); + }); + + test('should show an error message for the invalid input', async () => { + const user = userEvent.setup({ delay: 100 }); + renderPhoneInput(); + const phoneNumberEle = await screen.findByRole('textbox'); + await user.type(phoneNumberEle, '1'); + fireEvent.blur(phoneNumberEle); + expect(await screen.findByText(/invalid mobile number/i)).toBeInTheDocument(); + }); + + test('should show a success icon for the valid input', async () => { + const user = userEvent.setup({ delay: 100 }); + renderPhoneInput(); + const phoneNumberEle = await screen.findByRole('textbox'); + await user.type(phoneNumberEle, '123456'); + fireEvent.blur(phoneNumberEle); + const successIcons = await screen.findAllByRole('img'); + expect(successIcons.length).toBe(2); + }); + + test('should call onChange when the data has been changed', async () => { + const user = userEvent.setup({ delay: 100 }); + renderPhoneInput(); + const phoneNumberEle = await screen.findByRole('textbox'); + await user.type(phoneNumberEle, '123456'); + expect(defaultProps.onChange).toHaveBeenCalledWith( + expect.objectContaining({ + data: { phoneNumber: '123456', phonePrefix: '+44' }, + errors: expect.any(Object), + valid: expect.any(Object), + isValid: expect.any(Boolean) + }) + ); + }); +}); diff --git a/packages/lib/src/components/internal/PhoneInputNew/usePhonePrefixes.test.tsx b/packages/lib/src/components/internal/PhoneInputNew/usePhonePrefixes.test.tsx new file mode 100644 index 0000000000..d6fe785ce9 --- /dev/null +++ b/packages/lib/src/components/internal/PhoneInputNew/usePhonePrefixes.test.tsx @@ -0,0 +1,63 @@ +import usePhonePrefixes from './usePhonePrefixes'; +import getDataset from '../../../core/Services/get-dataset'; +import { renderHook } from '@testing-library/preact-hooks'; +import { waitFor } from '@testing-library/preact'; +import AdyenCheckoutError from '../../../core/Errors/AdyenCheckoutError'; + +jest.mock('../../../core/Services/get-dataset'); + +const getFlagEmoji = ({ id }) => { + const codePoints: number[] = id + .toUpperCase() + .split('') + .map(char => 127397 + char.charCodeAt(0)); + + return String.fromCodePoint ? String.fromCodePoint(...codePoints) + '\u00A0\u00A0' : ''; +}; + +describe('usePhonePrefixes', () => { + const props = { allowedCountries: [], loadingContext: 'test', handleError: jest.fn() }; + + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('should return a list of phone prefixes', async () => { + const datasetMock = [{ id: 'AF', prefix: '+93' }]; + (getDataset as jest.Mock).mockResolvedValue(datasetMock); + + const { result } = renderHook(() => usePhonePrefixes(props)); + const expectedPrefixes = datasetMock.map(item => ({ + id: item.prefix, + name: `${getFlagEmoji(item)} ${item.prefix} (${item.id})`, + selectedOptionName: `${getFlagEmoji(item)} ${item.prefix}` + })); + await waitFor(() => expect(result.current).toEqual({ loadingStatus: 'ready', phonePrefixes: expectedPrefixes })); + }); + + test('should return a list of phone prefixes for allowedCountries', async () => { + const datasetMock = [ + { id: 'AF', prefix: '+93' }, + { id: 'TEST', prefix: '+00' } + ]; + (getDataset as jest.Mock).mockResolvedValue(datasetMock); + + const { result } = renderHook(() => usePhonePrefixes({ ...props, allowedCountries: ['AF'] })); + const expectedPrefixes = [ + { + id: datasetMock[0].prefix, + name: `${getFlagEmoji(datasetMock[0])} ${datasetMock[0].prefix} (${datasetMock[0].id})`, + selectedOptionName: `${getFlagEmoji(datasetMock[0])} ${datasetMock[0].prefix}` + } + ]; + await waitFor(() => expect(result.current).toEqual({ loadingStatus: 'ready', phonePrefixes: expectedPrefixes })); + }); + + test('should return an empty array when getDataset failed', async () => { + (getDataset as jest.Mock).mockRejectedValue([]); + + const { result } = renderHook(() => usePhonePrefixes(props)); + await waitFor(() => expect(result.current).toEqual({ loadingStatus: 'ready', phonePrefixes: [] })); + expect(props.handleError).toHaveBeenCalledWith(new AdyenCheckoutError('ERROR')); + }); +});