Skip to content

Commit

Permalink
add search and state tests to address component
Browse files Browse the repository at this point in the history
  • Loading branch information
m1aw committed Nov 4, 2024
1 parent 552f652 commit 305d424
Showing 1 changed file with 219 additions and 2 deletions.
221 changes: 219 additions & 2 deletions packages/lib/src/components/internal/Address/Address.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,31 @@ import { AddressData } from '../../../types';
import { FALLBACK_VALUE } from './constants';
import { render, screen } from '@testing-library/preact';
import { CoreProvider } from '../../../core/Context/CoreProvider';
import userEvent from '@testing-library/user-event';

jest.mock('../../../core/Services/get-dataset');
(getDataset as jest.Mock).mockImplementation(jest.fn(() => Promise.resolve([{ id: 'NL', name: 'Netherlands' }])));
(getDataset as jest.Mock).mockImplementation(
jest.fn(dataset => {
switch (dataset) {
case 'countries':
return Promise.resolve([
{ id: 'US', name: 'United States' },
{ id: 'CA', name: 'Canada' },
{ id: 'NL', name: 'Netherlands' }
]);
case 'states/US':
return Promise.resolve([
{ id: 'AR', name: 'Arkansas' },
{ id: 'CA', name: 'California' }
]);
case 'states/CA':
return Promise.resolve([
{ id: 'AB', name: 'Alberta' },
{ id: 'BC', name: 'British Columbia' }
]);
}
})
);

describe('Address', () => {
const addressSpecificationsMock: AddressSpecifications = {
Expand Down Expand Up @@ -165,7 +187,7 @@ describe('Address', () => {
expect(receivedData.country).toBe(data.country);
});

test('should not include fields without a value in the data object', () => {
test('should not include fields without a value in the data object', () => {
const data: AddressData = { country: 'NL' };
const onChangeMock = jest.fn();

Expand Down Expand Up @@ -203,4 +225,199 @@ describe('Address', () => {
const receivedData = lastOnChangeCall[0].data;
expect(receivedData.stateOrProvince).toBe(undefined);
});

describe('Country and State or Province', () => {
const user = userEvent.setup();
const onChangeMock = jest.fn();
test('should set the stateOrProvince value to empty and show options when country changes', async () => {
const data: AddressData = { country: 'US' };

customRender(<Address countryCode={'US'} data={data} onChange={onChangeMock} />);

const countrySearch = await screen.findByLabelText('Country/Region');
await user.click(countrySearch);
// write in the searchbar
await user.keyboard('Canada');
// select one option
await user.keyboard('[ArrowDown][Enter]');
const stateSearch = await screen.findByLabelText('Province or Territory');
expect(stateSearch).toBeInTheDocument();
// open the state selector
await user.click(stateSearch);
// check if options are avaliable
expect(screen.getByText('Alberta')).toBeVisible();
});

test('should reset the stateOrProvince value when country changes', async () => {
const data: AddressData = { country: 'US', stateOrProvince: 'CA' };

customRender(<Address countryCode={'US'} data={data} onChange={onChangeMock} />);

// check if US values for state or province are set
expect(await screen.findByDisplayValue('United States')).toBeVisible();
expect(await screen.findByDisplayValue('California')).toBeVisible();

// search for CountryLabel and region, choose Canada
const countrySearch = await screen.findByLabelText('Country/Region');
await user.click(countrySearch);
// write in the searchbar
await user.keyboard('Canada');
// select one option
await user.keyboard('[ArrowDown][Enter]');

// Check if the state has reset to empty value
const stateSearch = await screen.findByLabelText('Province or Territory');
expect(stateSearch).toBeInTheDocument();
expect(stateSearch).toHaveValue('');
});

test('should trigger postal code validation on country change and show error message', async () => {
const data: AddressData = { country: 'US', stateOrProvince: 'CA', postalCode: '90000' };

customRender(<Address countryCode={'US'} data={data} onChange={onChangeMock} />);

// search for CountryLabel and region, choose Canada
const countrySearch = await screen.findByLabelText('Country/Region');
await user.click(countrySearch);
// write in the searchbar
await user.keyboard('Canada');
// select one option
await user.keyboard('[ArrowDown][Enter]');

// Check if the state has reset to empty value
const postalCodeField = await screen.findByRole('textbox', { name: 'Postal code' });
expect(postalCodeField).toBeInTheDocument();
expect(postalCodeField).toHaveValue('90000');
expect(screen.getByText('Invalid format. Expected format: A9A 9A9 or A9A9A9')).toBeVisible();
});
});

describe('AddressSearch in Address', () => {
// 0. delay the test since it rellies on user input
// there's probably a performance optimisation here, but delay was the simples and most reliable way to fix it
const user = userEvent.setup({ delay: 100 });
const onChangeMock = jest.fn();

test('should fill the stateOrProvince field for countries who support state', async () => {
const data: AddressData = {};

// 1. setup the test
// 1a. create mock for this tests
const addressMock = {
id: 1,
name: '1000 Test Road, California',
street: '1000 Test Road',
city: 'Los Santos',
//houseNumberOrName: '',
postalCode: '90000',
country: 'US',
stateOrProvince: 'CA'
};

// 1b. pass the mock to the the mock functions so we get it as the search result
const onAdressSearchMock = jest.fn(async (value, { resolve }) => {
await resolve([addressMock]);
});
const onAddressSelectedMock = jest.fn(async (value, { resolve }) => {
await resolve(addressMock);
});

// 2. render and intereact
customRender(
<Address data={data} onChange={onChangeMock} onAddressLookup={onAdressSearchMock} onAddressSelected={onAddressSelectedMock} />
);
const searchBar = screen.getByRole('combobox');
await user.click(searchBar);
// write in the searchbar
await user.keyboard('mock');
// select one option
await user.keyboard('[ArrowDown][Enter]');

// 3. check filled values are correct
expect(screen.getByDisplayValue('1000 Test Road')).toBeInTheDocument();
expect(screen.getByDisplayValue('90000')).toBeInTheDocument();
expect(screen.getByDisplayValue('California')).toBeInTheDocument();
});

test('should fill the stateOrProvince field for countries who support state', async () => {
const data: AddressData = { country: 'CA' };

// 1. setup the test
// 1a. create mock for this tests
const addressMock = {
id: 1,
name: '1000 Test Road, California',
street: '1000 Test Road',
city: 'Los Santos',
//houseNumberOrName: '',
postalCode: '90000',
country: 'US',
stateOrProvince: 'CA'
};

// 1b. pass the mock to the the mock functions so we get it as the search result
const onAdressSearchMock = jest.fn(async (value, { resolve }) => {
await resolve([addressMock]);
});
const onAddressSelectedMock = jest.fn(async (value, { resolve }) => {
await resolve(addressMock);
});

// 2. render and intereact
customRender(
<Address data={data} onChange={onChangeMock} onAddressLookup={onAdressSearchMock} onAddressSelected={onAddressSelectedMock} />
);
const searchBar = screen.getByRole('combobox');
await user.click(searchBar);
// write in the searchbar
await user.keyboard('mock');
// select one option
await user.keyboard('[ArrowDown][Enter]');

// 3. check filled values are correct
expect(screen.getByDisplayValue('1000 Test Road')).toBeInTheDocument();
expect(screen.getByDisplayValue('90000')).toBeInTheDocument();
expect(screen.getByDisplayValue('California')).toBeInTheDocument();
});

test('should trigger field validation after address is selected', async () => {
const data: AddressData = {};

// 1. setup the test
// 1a. create mock for this tests
const incorrectPostalCodeAddressMock = {
id: 1,
name: '1000 Test Road, California',
street: '1000 Test Road',
city: 'Los Santos',
//houseNumberOrName: '',
postalCode: '9000 AA',
country: 'US',
stateOrProvince: 'CA'
};

// 1b. pass the mock to the the mock functions so we get it as the search result
const onAdressSearchMock = jest.fn(async (value, { resolve }) => {
await resolve([incorrectPostalCodeAddressMock]);
});
const onAddressSelectedMock = jest.fn(async (value, { resolve }) => {
await resolve(incorrectPostalCodeAddressMock);
});

// 2. render and intereact
customRender(
<Address data={data} onChange={onChangeMock} onAddressLookup={onAdressSearchMock} onAddressSelected={onAddressSelectedMock} />
);
const searchBar = screen.getByRole('combobox');
await user.click(searchBar);
// write in the searchbar
await user.keyboard('mock');
// select one option
await user.keyboard('[ArrowDown][Enter]');

// 3. check filled values are correct and error state is triggered
expect(screen.getByRole('textbox', { name: 'Zip code' })).toHaveValue('9000 AA');
expect(screen.getByText('Invalid format. Expected format: 99999 or 99999-9999')).toBeVisible();
});
});
});

0 comments on commit 305d424

Please sign in to comment.