Fix tests and upgrade node_modules (#1227)
* Fix tests * Fix tests * Fix 0 in SortandFilterBar
This commit is contained in:
@ -25,11 +25,11 @@ module.exports = {
|
||||
},
|
||||
jest: {
|
||||
configure: {
|
||||
"moduleNameMapper": {
|
||||
moduleNameMapper: {
|
||||
'~/(.+)': "<rootDir>/src/$1",
|
||||
'@/(.+)': "<rootDir>/src/modules/$1",
|
||||
'@testing/(.+)': "<rootDir>/src/testing/$1",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,834 +0,0 @@
|
||||
import selectEvent from 'react-select-event';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { ModalWrapper } from '@/spreadsheet-import/components/core/ModalWrapper';
|
||||
import { Providers } from '@/spreadsheet-import/components/core/Providers';
|
||||
import { SpreadsheetImport } from '@/spreadsheet-import/components/SpreadsheetImport';
|
||||
import { MatchColumnsStep } from '@/spreadsheet-import/components/steps/MatchColumnsStep/MatchColumnsStep';
|
||||
import { StepType } from '@/spreadsheet-import/components/steps/UploadFlow';
|
||||
import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues';
|
||||
import type { Fields } from '@/spreadsheet-import/types';
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
// TODO: fix this test
|
||||
const SELECT_DROPDOWN_ID = 'select-dropdown';
|
||||
|
||||
const fields: Fields<any> = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
example: 'Stephanie',
|
||||
},
|
||||
{
|
||||
icon: null,
|
||||
label: 'Mobile Phone',
|
||||
key: 'mobile',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
example: '+12323423',
|
||||
},
|
||||
{
|
||||
icon: null,
|
||||
label: 'Is cool',
|
||||
key: 'is_cool',
|
||||
fieldType: {
|
||||
type: 'checkbox',
|
||||
},
|
||||
example: 'No',
|
||||
},
|
||||
];
|
||||
|
||||
const CONTINUE_BUTTON = 'Next';
|
||||
const MUTATED_ENTRY = 'mutated entry';
|
||||
const ERROR_MESSAGE = 'Something happened';
|
||||
|
||||
describe('Match Columns automatic matching', () => {
|
||||
test('AutoMatch column and click next', async () => {
|
||||
const header = ['namezz', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
// finds only names with automatic matching
|
||||
const result = [
|
||||
{ name: data[0][0] },
|
||||
{ name: data[1][0] },
|
||||
{ name: data[2][0] },
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test('AutoMatching disabled does not match any columns', async () => {
|
||||
const header = ['Name', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
// finds only names with automatic matching
|
||||
const result = [{}, {}, {}];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers
|
||||
rsiValues={{ ...mockRsiValues, fields, autoMapHeaders: false }}
|
||||
>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test('AutoMatching exact values', async () => {
|
||||
const header = ['Name', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
// finds only names with automatic matching
|
||||
const result = [
|
||||
{ name: data[0][0] },
|
||||
{ name: data[1][0] },
|
||||
{ name: data[2][0] },
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields, autoMapDistance: 1 }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test('AutoMatches only one value', async () => {
|
||||
const header = ['first name', 'name', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
// finds only names with automatic matching
|
||||
const result = [
|
||||
{ name: data[0][1] },
|
||||
{ name: data[1][1] },
|
||||
{ name: data[2][1] },
|
||||
];
|
||||
|
||||
const alternativeFields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
alternateMatches: ['first name'],
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
example: 'Stephanie',
|
||||
},
|
||||
] as const;
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields: alternativeFields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test('Boolean-like values are returned as Booleans', async () => {
|
||||
const header = ['namezz', 'is_cool', 'Email'];
|
||||
const data = [
|
||||
['John', 'yes', 'j@j.com'],
|
||||
['Dane', 'TRUE', 'dane@bane.com'],
|
||||
['Kane', 'false', 'kane@linch.com'],
|
||||
['Kaney', 'no', 'kane@linch.com'],
|
||||
['Kanye', 'maybe', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const result = [
|
||||
{ name: data[0][0], is_cool: true },
|
||||
{ name: data[1][0], is_cool: true },
|
||||
{ name: data[2][0], is_cool: false },
|
||||
{ name: data[3][0], is_cool: false },
|
||||
{ name: data[4][0], is_cool: false },
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test("Boolean-like values are returned as Booleans for 'booleanMatches' props", async () => {
|
||||
const BOOLEAN_MATCHES_VALUE = 'definitely';
|
||||
const header = ['is_cool'];
|
||||
const data = [['true'], ['false'], [BOOLEAN_MATCHES_VALUE]];
|
||||
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Is cool',
|
||||
key: 'is_cool',
|
||||
fieldType: {
|
||||
type: 'checkbox',
|
||||
booleanMatches: { [BOOLEAN_MATCHES_VALUE]: true },
|
||||
},
|
||||
example: 'No',
|
||||
},
|
||||
] as const;
|
||||
|
||||
const result = [{ is_cool: true }, { is_cool: false }, { is_cool: true }];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Match Columns general tests', () => {
|
||||
test('Displays all user header columns', async () => {
|
||||
const header = ['namezz', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(header[0])).toBeInTheDocument();
|
||||
expect(screen.getByText(header[1])).toBeInTheDocument();
|
||||
expect(screen.getByText(header[2])).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Displays two rows of example data', async () => {
|
||||
const header = ['namezz', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
// only displays two rows
|
||||
expect(screen.queryByText(data[0][0])).toBeInTheDocument();
|
||||
expect(screen.queryByText(data[0][1])).toBeInTheDocument();
|
||||
expect(screen.queryByText(data[0][2])).toBeInTheDocument();
|
||||
expect(screen.queryByText(data[1][0])).toBeInTheDocument();
|
||||
expect(screen.queryByText(data[1][1])).toBeInTheDocument();
|
||||
expect(screen.queryByText(data[1][2])).toBeInTheDocument();
|
||||
expect(screen.queryByText(data[2][0])).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(data[2][1])).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(data[2][2])).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Displays all fields in selects dropdown', async () => {
|
||||
const header = ['Something random', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const firstSelect = screen.getByLabelText(header[0]);
|
||||
|
||||
await userEvent.click(firstSelect);
|
||||
|
||||
fields.forEach((field) => {
|
||||
expect(screen.queryByText(field.label)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('Manually matches first column', async () => {
|
||||
const header = ['Something random', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
const result = [
|
||||
{ name: data[0][0] },
|
||||
{ name: data[1][0] },
|
||||
{ name: data[2][0] },
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
<div id={SELECT_DROPDOWN_ID} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const container = document.getElementById(SELECT_DROPDOWN_ID);
|
||||
|
||||
if (!container) {
|
||||
throw new Error('Container not found');
|
||||
}
|
||||
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(header[0]),
|
||||
fields[0].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test('Checkmark changes when field is matched', async () => {
|
||||
const header = ['Something random', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
<div id={SELECT_DROPDOWN_ID} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const checkmark = screen.getAllByTestId('column-checkmark')[0];
|
||||
// kinda dumb way to check if it has checkmark or not
|
||||
expect(checkmark).toBeEmptyDOMElement();
|
||||
|
||||
const container = document.getElementById(SELECT_DROPDOWN_ID);
|
||||
|
||||
if (!container) {
|
||||
throw new Error('Container not found');
|
||||
}
|
||||
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(header[0]),
|
||||
fields[0].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
|
||||
expect(checkmark).not.toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
test('Selecting select field adds more selects', async () => {
|
||||
const OPTION_ONE = 'one';
|
||||
const OPTION_TWO = 'two';
|
||||
const OPTION_RESULT_ONE = 'uno';
|
||||
const OPTION_RESULT_TWO = 'dos';
|
||||
const options = [
|
||||
{ label: 'One', value: OPTION_RESULT_ONE },
|
||||
{ label: 'Two', value: OPTION_RESULT_TWO },
|
||||
];
|
||||
const header = ['Something random'];
|
||||
const data = [[OPTION_ONE], [OPTION_TWO], [OPTION_ONE]];
|
||||
|
||||
const result = [
|
||||
{
|
||||
team: OPTION_RESULT_ONE,
|
||||
},
|
||||
{
|
||||
team: OPTION_RESULT_TWO,
|
||||
},
|
||||
{
|
||||
team: OPTION_RESULT_ONE,
|
||||
},
|
||||
];
|
||||
|
||||
const enumFields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Team',
|
||||
key: 'team',
|
||||
fieldType: {
|
||||
type: 'select',
|
||||
options: options,
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields: enumFields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
<div id={SELECT_DROPDOWN_ID} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
expect(screen.queryByTestId('accordion-button')).not.toBeInTheDocument();
|
||||
|
||||
const container = document.getElementById(SELECT_DROPDOWN_ID);
|
||||
|
||||
if (!container) {
|
||||
throw new Error('Container not found');
|
||||
}
|
||||
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(header[0]),
|
||||
enumFields[0].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
|
||||
expect(screen.queryByTestId('accordion-button')).toBeInTheDocument();
|
||||
|
||||
await userEvent.click(screen.getByTestId('accordion-button'));
|
||||
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(data[0][0]),
|
||||
options[0].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(data[1][0]),
|
||||
options[1].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(result);
|
||||
});
|
||||
|
||||
test('Can ignore columns', async () => {
|
||||
const header = ['Something random', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const ignoreButton = screen.getAllByLabelText('Ignore column')[0];
|
||||
|
||||
expect(screen.queryByText('Column ignored')).not.toBeInTheDocument();
|
||||
|
||||
await userEvent.click(ignoreButton);
|
||||
|
||||
expect(screen.queryByText('Column ignored')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Required unselected fields show warning alert on submit', async () => {
|
||||
const header = ['Something random', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const requiredFields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
example: 'Stephanie',
|
||||
validations: [
|
||||
{
|
||||
rule: 'required',
|
||||
errorMessage: 'Hello',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields: requiredFields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
expect(onContinue).not.toBeCalled();
|
||||
expect(
|
||||
screen.queryByText(
|
||||
'There are required columns that are not matched or ignored. Do you want to continue?',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
|
||||
const continueButton = screen.getByRole('button', {
|
||||
name: 'Continue',
|
||||
});
|
||||
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test('Selecting the same field twice shows toast', async () => {
|
||||
const header = ['Something random', 'Phone', 'Email'];
|
||||
const data = [
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
['Kane', '534', 'kane@linch.com'],
|
||||
];
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockRsiValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<MatchColumnsStep
|
||||
headerValues={header}
|
||||
data={data}
|
||||
onContinue={onContinue}
|
||||
/>
|
||||
<div id={SELECT_DROPDOWN_ID} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
const container = document.getElementById(SELECT_DROPDOWN_ID);
|
||||
|
||||
if (!container) {
|
||||
throw new Error('Container not found');
|
||||
}
|
||||
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(header[0]),
|
||||
fields[0].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
await selectEvent.select(
|
||||
screen.getByLabelText(header[1]),
|
||||
fields[0].label,
|
||||
{
|
||||
container,
|
||||
},
|
||||
);
|
||||
|
||||
const toasts = await screen.queryAllByText('Columns cannot duplicate');
|
||||
|
||||
expect(toasts?.[0]).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('matchColumnsStepHook should be called after columns are matched', async () => {
|
||||
const matchColumnsStepHook = jest.fn(async (values) => values);
|
||||
const mockValues = {
|
||||
...mockRsiValues,
|
||||
fields: mockRsiValues.fields.filter(
|
||||
(field) => field.key === 'name' || field.key === 'age',
|
||||
),
|
||||
};
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockValues}
|
||||
matchColumnsStepHook={matchColumnsStepHook}
|
||||
initialStepState={{
|
||||
type: StepType.matchColumns,
|
||||
data: [
|
||||
['Josh', '2'],
|
||||
['Charlie', '3'],
|
||||
['Lena', '50'],
|
||||
],
|
||||
headerValues: ['name', 'age'],
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
const continueButton = screen.getByText(CONTINUE_BUTTON);
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(matchColumnsStepHook).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test('matchColumnsStepHook mutations to rawData should show up in ValidationStep', async () => {
|
||||
const matchColumnsStepHook = jest.fn(async ([firstEntry, ...values]) => {
|
||||
return [{ ...firstEntry, name: MUTATED_ENTRY }, ...values];
|
||||
});
|
||||
const mockValues = {
|
||||
...mockRsiValues,
|
||||
fields: mockRsiValues.fields.filter(
|
||||
(field) => field.key === 'name' || field.key === 'age',
|
||||
),
|
||||
};
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockValues}
|
||||
matchColumnsStepHook={matchColumnsStepHook}
|
||||
initialStepState={{
|
||||
type: StepType.matchColumns,
|
||||
data: [
|
||||
['Josh', '2'],
|
||||
['Charlie', '3'],
|
||||
['Lena', '50'],
|
||||
],
|
||||
headerValues: ['name', 'age'],
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
const continueButton = screen.getByText(CONTINUE_BUTTON);
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
const mutatedEntry = await screen.findByText(MUTATED_ENTRY);
|
||||
expect(mutatedEntry).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Should show error toast if error is thrown in matchColumnsStepHook', async () => {
|
||||
const matchColumnsStepHook = jest.fn(async () => {
|
||||
throw new Error(ERROR_MESSAGE);
|
||||
});
|
||||
|
||||
const mockValues = {
|
||||
...mockRsiValues,
|
||||
fields: mockRsiValues.fields.filter(
|
||||
(field) => field.key === 'name' || field.key === 'age',
|
||||
),
|
||||
};
|
||||
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockValues}
|
||||
matchColumnsStepHook={matchColumnsStepHook}
|
||||
initialStepState={{
|
||||
type: StepType.matchColumns,
|
||||
data: [
|
||||
['Josh', '2'],
|
||||
['Charlie', '3'],
|
||||
['Lena', '50'],
|
||||
],
|
||||
headerValues: ['name', 'age'],
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
const continueButton = screen.getByText(CONTINUE_BUTTON);
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
const errorToast = await screen.findAllByText(ERROR_MESSAGE, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
expect(errorToast?.[0]).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@ -1,257 +0,0 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
import { ModalWrapper } from '@/spreadsheet-import/components/core/ModalWrapper';
|
||||
import { Providers } from '@/spreadsheet-import/components/core/Providers';
|
||||
import { SpreadsheetImport } from '@/spreadsheet-import/components/SpreadsheetImport';
|
||||
import { SelectHeaderStep } from '@/spreadsheet-import/components/steps/SelectHeaderStep/SelectHeaderStep';
|
||||
import { StepType } from '@/spreadsheet-import/components/steps/UploadFlow';
|
||||
import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues';
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
const MUTATED_HEADER = 'mutated header';
|
||||
const CONTINUE_BUTTON = 'Next';
|
||||
const ERROR_MESSAGE = 'Something happened';
|
||||
const RAW_DATE = '2020-03-03';
|
||||
const FORMATTED_DATE = '2020/03/03';
|
||||
const TRAILING_CELL = 'trailingcell';
|
||||
|
||||
describe('Select header step tests', () => {
|
||||
test('Select header row and click next', async () => {
|
||||
const data = [
|
||||
['Some random header'],
|
||||
['2030'],
|
||||
['Name', 'Phone', 'Email'],
|
||||
['John', '123', 'j@j.com'],
|
||||
['Dane', '333', 'dane@bane.com'],
|
||||
];
|
||||
const selectRowIndex = 2;
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={mockRsiValues}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<SelectHeaderStep data={data} onContinue={onContinue} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const radioButtons = screen.getAllByRole('radio');
|
||||
|
||||
await userEvent.click(radioButtons[selectRowIndex]);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(data[selectRowIndex]);
|
||||
expect(onContinue.mock.calls[0][1]).toEqual(data.slice(selectRowIndex + 1));
|
||||
});
|
||||
|
||||
test('selectHeaderStepHook should be called after header is selected', async () => {
|
||||
const selectHeaderStepHook = jest.fn(async (headerValues, data) => {
|
||||
return { headerValues, data };
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockRsiValues}
|
||||
selectHeaderStepHook={selectHeaderStepHook}
|
||||
/>,
|
||||
);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
const data = readFileSync(__dirname + '/../../../../static/Workbook2.xlsx');
|
||||
fireEvent.drop(uploader, {
|
||||
target: {
|
||||
files: [
|
||||
new File([data], 'testFile.xlsx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
const continueButton = await screen.findByText(CONTINUE_BUTTON, undefined, {
|
||||
timeout: 10000,
|
||||
});
|
||||
fireEvent.click(continueButton);
|
||||
await waitFor(() => {
|
||||
expect(selectHeaderStepHook).toBeCalledWith(
|
||||
['name', 'age', 'date'],
|
||||
[
|
||||
['Josh', '2', '2020-03-03'],
|
||||
['Charlie', '3', '2010-04-04'],
|
||||
['Lena', '50', '1994-02-27'],
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
test('selectHeaderStepHook should be able to modify raw data', async () => {
|
||||
const selectHeaderStepHook = jest.fn(
|
||||
async ([_val, ...headerValues], data) => {
|
||||
return { headerValues: [MUTATED_HEADER, ...headerValues], data };
|
||||
},
|
||||
);
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockRsiValues}
|
||||
selectHeaderStepHook={selectHeaderStepHook}
|
||||
initialStepState={{
|
||||
type: StepType.selectHeader,
|
||||
data: [
|
||||
['name', 'age'],
|
||||
['Josh', '2'],
|
||||
['Charlie', '3'],
|
||||
['Lena', '50'],
|
||||
],
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
const continueButton = screen.getByText(CONTINUE_BUTTON);
|
||||
fireEvent.click(continueButton);
|
||||
const mutatedHeader = await screen.findByText(MUTATED_HEADER);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mutatedHeader).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('Should show error toast if error is thrown in selectHeaderStepHook', async () => {
|
||||
const selectHeaderStepHook = jest.fn(async () => {
|
||||
throw new Error(ERROR_MESSAGE);
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockRsiValues}
|
||||
selectHeaderStepHook={selectHeaderStepHook}
|
||||
initialStepState={{
|
||||
type: StepType.selectHeader,
|
||||
data: [
|
||||
['name', 'age'],
|
||||
['Josh', '2'],
|
||||
['Charlie', '3'],
|
||||
['Lena', '50'],
|
||||
],
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
const continueButton = screen.getByText(CONTINUE_BUTTON);
|
||||
await userEvent.click(continueButton);
|
||||
|
||||
const errorToast = await screen.findAllByText(ERROR_MESSAGE, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
expect(errorToast?.[0]).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('dateFormat property should NOT be applied to dates read from csv files IF parseRaw=true', async () => {
|
||||
const file = new File([RAW_DATE], 'test.csv', {
|
||||
type: 'text/csv',
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockRsiValues}
|
||||
dateFormat="yyyy/mm/dd"
|
||||
parseRaw={true}
|
||||
/>,
|
||||
);
|
||||
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
fireEvent.drop(uploader, {
|
||||
target: { files: [file] },
|
||||
});
|
||||
|
||||
const el = await screen.findByText(RAW_DATE, undefined, { timeout: 5000 });
|
||||
expect(el).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('dateFormat property should be applied to dates read from csv files IF parseRaw=false', async () => {
|
||||
const file = new File([RAW_DATE], 'test.csv', {
|
||||
type: 'text/csv',
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockRsiValues}
|
||||
dateFormat="yyyy/mm/dd"
|
||||
parseRaw={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
fireEvent.drop(uploader, {
|
||||
target: { files: [file] },
|
||||
});
|
||||
|
||||
const el = await screen.findByText(FORMATTED_DATE, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
expect(el).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('dateFormat property should be applied to dates read from xlsx files', async () => {
|
||||
render(<SpreadsheetImport {...mockRsiValues} dateFormat="yyyy/mm/dd" />);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
const data = readFileSync(__dirname + '/../../../../static/Workbook2.xlsx');
|
||||
fireEvent.drop(uploader, {
|
||||
target: {
|
||||
files: [
|
||||
new File([data], 'testFile.xlsx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
const el = await screen.findByText(FORMATTED_DATE, undefined, {
|
||||
timeout: 10000,
|
||||
});
|
||||
expect(el).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test.skip(
|
||||
'trailing (not under a header) cells should be rendered in SelectHeaderStep table, ' +
|
||||
'but not in MatchColumnStep if a shorter row is selected as a header',
|
||||
async () => {
|
||||
const selectHeaderStepHook = jest.fn(async (headerValues, data) => {
|
||||
return { headerValues, data };
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport
|
||||
{...mockRsiValues}
|
||||
selectHeaderStepHook={selectHeaderStepHook}
|
||||
/>,
|
||||
);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
const data = readFileSync(
|
||||
__dirname + '/../../../../static/TrailingCellsWorkbook.xlsx',
|
||||
);
|
||||
fireEvent.drop(uploader, {
|
||||
target: {
|
||||
files: [
|
||||
new File([data], 'testFile.xlsx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
const trailingCell = await screen.findByText(TRAILING_CELL, undefined, {
|
||||
timeout: 10000,
|
||||
});
|
||||
expect(trailingCell).toBeInTheDocument();
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
await userEvent.click(nextButton);
|
||||
const trailingCellNextPage = await screen.findByText(
|
||||
TRAILING_CELL,
|
||||
undefined,
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
expect(trailingCellNextPage).not.toBeInTheDocument();
|
||||
},
|
||||
);
|
||||
});
|
||||
@ -1,134 +0,0 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
import { ModalWrapper } from '@/spreadsheet-import/components/core/ModalWrapper';
|
||||
import { Providers } from '@/spreadsheet-import/components/core/Providers';
|
||||
import { SpreadsheetImport } from '@/spreadsheet-import/components/SpreadsheetImport';
|
||||
import { SelectSheetStep } from '@/spreadsheet-import/components/steps/SelectSheetStep/SelectSheetStep';
|
||||
import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues';
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
const SHEET_TITLE_1 = 'Sheet1';
|
||||
const SHEET_TITLE_2 = 'Sheet2';
|
||||
const SELECT_HEADER_TABLE_ENTRY_1 = 'Charlie';
|
||||
const SELECT_HEADER_TABLE_ENTRY_2 = 'Josh';
|
||||
const SELECT_HEADER_TABLE_ENTRY_3 = '50';
|
||||
const ERROR_MESSAGE = 'Something happened';
|
||||
|
||||
test('Should render select sheet screen if multi-sheet excel file was uploaded', async () => {
|
||||
render(<SpreadsheetImport {...mockRsiValues} />);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
const data = readFileSync(__dirname + '/../../../../static/Workbook1.xlsx');
|
||||
fireEvent.drop(uploader, {
|
||||
target: {
|
||||
files: [
|
||||
new File([data], 'testFile.xlsx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const sheetTitle = await screen.findByText(SHEET_TITLE_1, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
const sheetTitle2 = screen.getByRole('radio', { name: SHEET_TITLE_2 });
|
||||
expect(sheetTitle).toBeInTheDocument();
|
||||
expect(sheetTitle2).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Should render select header screen with relevant data if single-sheet excel file was uploaded', async () => {
|
||||
render(<SpreadsheetImport {...mockRsiValues} />);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
const data = readFileSync(__dirname + '/../../../../static/Workbook2.xlsx');
|
||||
fireEvent.drop(uploader, {
|
||||
target: {
|
||||
files: [
|
||||
new File([data], 'testFile.xlsx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
const tableEntry1 = await screen.findByText(
|
||||
SELECT_HEADER_TABLE_ENTRY_1,
|
||||
undefined,
|
||||
{ timeout: 5000 },
|
||||
);
|
||||
const tableEntry2 = screen.getByRole('gridcell', {
|
||||
name: SELECT_HEADER_TABLE_ENTRY_2,
|
||||
});
|
||||
const tableEntry3 = screen.getByRole('gridcell', {
|
||||
name: SELECT_HEADER_TABLE_ENTRY_3,
|
||||
});
|
||||
|
||||
expect(tableEntry1).toBeInTheDocument();
|
||||
expect(tableEntry2).toBeInTheDocument();
|
||||
expect(tableEntry3).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Select sheet and click next', async () => {
|
||||
const sheetNames = ['Sheet1', 'Sheet2'];
|
||||
const selectSheetIndex = 1;
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={mockRsiValues}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<SelectSheetStep sheetNames={sheetNames} onContinue={onContinue} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const firstRadio = screen.getByLabelText(sheetNames[selectSheetIndex]);
|
||||
|
||||
await userEvent.click(firstRadio);
|
||||
|
||||
const nextButton = screen.getByRole('button', {
|
||||
name: 'Next',
|
||||
});
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
});
|
||||
expect(onContinue.mock.calls[0][0]).toEqual(sheetNames[selectSheetIndex]);
|
||||
});
|
||||
|
||||
test('Should show error toast if error is thrown in uploadStepHook', async () => {
|
||||
const uploadStepHook = jest.fn(async () => {
|
||||
throw new Error(ERROR_MESSAGE);
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport {...mockRsiValues} uploadStepHook={uploadStepHook} />,
|
||||
);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
const data = readFileSync(__dirname + '/../../../../static/Workbook1.xlsx');
|
||||
fireEvent.drop(uploader, {
|
||||
target: {
|
||||
files: [
|
||||
new File([data], 'testFile.xlsx', {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const nextButton = await screen.findByRole(
|
||||
'button',
|
||||
{
|
||||
name: 'Next',
|
||||
},
|
||||
{ timeout: 5000 },
|
||||
);
|
||||
|
||||
await userEvent.click(nextButton);
|
||||
|
||||
const errorToast = await screen.findAllByText(ERROR_MESSAGE, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
expect(errorToast?.[0]).toBeInTheDocument();
|
||||
});
|
||||
@ -1,105 +0,0 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
|
||||
import { ModalWrapper } from '@/spreadsheet-import/components/core/ModalWrapper';
|
||||
import { Providers } from '@/spreadsheet-import/components/core/Providers';
|
||||
import { SpreadsheetImport } from '@/spreadsheet-import/components/SpreadsheetImport';
|
||||
import { UploadStep } from '@/spreadsheet-import/components/steps/UploadStep/UploadStep';
|
||||
import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues';
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
const MUTATED_RAW_DATA = 'Bye';
|
||||
const ERROR_MESSAGE = 'Something happened while uploading';
|
||||
|
||||
test('Upload a file', async () => {
|
||||
const file = new File(['Hello, Hello, Hello, Hello'], 'test.csv', {
|
||||
type: 'text/csv',
|
||||
});
|
||||
|
||||
const onContinue = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={mockRsiValues}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<UploadStep onContinue={onContinue} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
fireEvent.drop(uploader, {
|
||||
target: { files: [file] },
|
||||
});
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(onContinue).toBeCalled();
|
||||
},
|
||||
{ timeout: 5000 },
|
||||
);
|
||||
});
|
||||
|
||||
test('Should call uploadStepHook on file upload', async () => {
|
||||
const file = new File(['Hello, Hello, Hello, Hello'], 'test.csv', {
|
||||
type: 'text/csv',
|
||||
});
|
||||
const uploadStepHook = jest.fn(async (values) => {
|
||||
return values;
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport {...mockRsiValues} uploadStepHook={uploadStepHook} />,
|
||||
);
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
fireEvent.drop(uploader, {
|
||||
target: { files: [file] },
|
||||
});
|
||||
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(uploadStepHook).toBeCalled();
|
||||
},
|
||||
{ timeout: 5000 },
|
||||
);
|
||||
});
|
||||
|
||||
test('uploadStepHook should be able to mutate raw upload data', async () => {
|
||||
const file = new File(['Hello, Hello, Hello, Hello'], 'test.csv', {
|
||||
type: 'text/csv',
|
||||
});
|
||||
const uploadStepHook = jest.fn(async ([[, ...values]]) => {
|
||||
return [[MUTATED_RAW_DATA, ...values]];
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport {...mockRsiValues} uploadStepHook={uploadStepHook} />,
|
||||
);
|
||||
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
fireEvent.drop(uploader, {
|
||||
target: { files: [file] },
|
||||
});
|
||||
|
||||
const el = await screen.findByText(MUTATED_RAW_DATA, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
expect(el).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Should show error toast if error is thrown in uploadStepHook', async () => {
|
||||
const file = new File(['Hello, Hello, Hello, Hello'], 'test.csv', {
|
||||
type: 'text/csv',
|
||||
});
|
||||
const uploadStepHook = jest.fn(async () => {
|
||||
throw new Error(ERROR_MESSAGE);
|
||||
});
|
||||
render(
|
||||
<SpreadsheetImport {...mockRsiValues} uploadStepHook={uploadStepHook} />,
|
||||
);
|
||||
|
||||
const uploader = screen.getByTestId('rsi-dropzone');
|
||||
fireEvent.drop(uploader, {
|
||||
target: { files: [file] },
|
||||
});
|
||||
|
||||
const errorToast = await screen.findAllByText(ERROR_MESSAGE, undefined, {
|
||||
timeout: 5000,
|
||||
});
|
||||
expect(errorToast?.[0]).toBeInTheDocument();
|
||||
});
|
||||
@ -1,763 +0,0 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { ModalWrapper } from '@/spreadsheet-import/components/core/ModalWrapper';
|
||||
import { Providers } from '@/spreadsheet-import/components/core/Providers';
|
||||
import { defaultRSIProps } from '@/spreadsheet-import/components/SpreadsheetImport';
|
||||
import { ValidationStep } from '@/spreadsheet-import/components/steps/ValidationStep/ValidationStep';
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
const mockValues = {
|
||||
...defaultRSIProps,
|
||||
fields: [],
|
||||
onSubmit: jest.fn(),
|
||||
isOpen: true,
|
||||
onClose: jest.fn(),
|
||||
} as const;
|
||||
|
||||
const getFilterSwitch = () =>
|
||||
screen.getByRole('checkbox', {
|
||||
name: 'Show only rows with errors',
|
||||
});
|
||||
|
||||
const file = new File([''], 'file.csv');
|
||||
|
||||
describe('Validation step tests', () => {
|
||||
test('Submit data', async () => {
|
||||
const onSubmit = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, onSubmit: onSubmit }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={[]} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const finishButton = screen.getByRole('button', {
|
||||
name: 'Confirm',
|
||||
});
|
||||
|
||||
await userEvent.click(finishButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onSubmit).toBeCalledWith(
|
||||
{ all: [], invalidData: [], validData: [] },
|
||||
file,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Filters rows with required errors', async () => {
|
||||
const UNIQUE_NAME = 'very unique name';
|
||||
const initialData = [
|
||||
{
|
||||
name: UNIQUE_NAME,
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
validations: [
|
||||
{
|
||||
rule: 'required',
|
||||
errorMessage: 'Name is required',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const allRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsWithHeader).toHaveLength(3);
|
||||
|
||||
const validRow = screen.getByText(UNIQUE_NAME);
|
||||
expect(validRow).toBeInTheDocument();
|
||||
|
||||
const switchFilter = getFilterSwitch();
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
const filteredRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsWithHeader).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('Filters rows with errors, fixes row, removes filter', async () => {
|
||||
const UNIQUE_NAME = 'very unique name';
|
||||
const SECOND_UNIQUE_NAME = 'another unique name';
|
||||
const FINAL_NAME = 'just name';
|
||||
const initialData = [
|
||||
{
|
||||
name: UNIQUE_NAME,
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
},
|
||||
{
|
||||
name: SECOND_UNIQUE_NAME,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
validations: [
|
||||
{
|
||||
rule: 'required',
|
||||
errorMessage: 'Name is required',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
|
||||
const onSubmit = jest.fn();
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, fields, onSubmit }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const allRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsWithHeader).toHaveLength(4);
|
||||
|
||||
const validRow = screen.getByText(UNIQUE_NAME);
|
||||
expect(validRow).toBeInTheDocument();
|
||||
|
||||
const switchFilter = getFilterSwitch();
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
const filteredRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsWithHeader).toHaveLength(2);
|
||||
|
||||
// don't really know another way to select an empty cell
|
||||
const emptyCell = screen.getAllByRole('gridcell', { name: undefined })[1];
|
||||
await userEvent.click(emptyCell);
|
||||
|
||||
await userEvent.keyboard(FINAL_NAME + '{enter}');
|
||||
|
||||
const filteredRowsNoErrorsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsNoErrorsWithHeader).toHaveLength(1);
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
const allRowsFixedWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsFixedWithHeader).toHaveLength(4);
|
||||
|
||||
const finishButton = screen.getByRole('button', {
|
||||
name: 'Confirm',
|
||||
});
|
||||
|
||||
await userEvent.click(finishButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onSubmit).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test('Filters rows with unique errors', async () => {
|
||||
const NON_UNIQUE_NAME = 'very unique name';
|
||||
const initialData = [
|
||||
{
|
||||
name: NON_UNIQUE_NAME,
|
||||
},
|
||||
{
|
||||
name: NON_UNIQUE_NAME,
|
||||
},
|
||||
{
|
||||
name: 'I am fine',
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
validations: [
|
||||
{
|
||||
rule: 'unique',
|
||||
errorMessage: 'Name must be unique',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const allRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsWithHeader).toHaveLength(4);
|
||||
|
||||
const switchFilter = getFilterSwitch();
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
const filteredRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsWithHeader).toHaveLength(3);
|
||||
});
|
||||
test('Filters rows with regex errors', async () => {
|
||||
const NOT_A_NUMBER = 'not a number';
|
||||
const initialData = [
|
||||
{
|
||||
name: NOT_A_NUMBER,
|
||||
},
|
||||
{
|
||||
name: '1234',
|
||||
},
|
||||
{
|
||||
name: '9999999',
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
validations: [
|
||||
{
|
||||
rule: 'regex',
|
||||
errorMessage: 'Name must be unique',
|
||||
value: '^[0-9]*$',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const allRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsWithHeader).toHaveLength(4);
|
||||
|
||||
const switchFilter = getFilterSwitch();
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
const filteredRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsWithHeader).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('Deletes selected rows', async () => {
|
||||
const FIRST_DELETE = 'first';
|
||||
const SECOND_DELETE = 'second';
|
||||
const THIRD = 'third';
|
||||
|
||||
const initialData = [
|
||||
{
|
||||
name: FIRST_DELETE,
|
||||
},
|
||||
{
|
||||
name: SECOND_DELETE,
|
||||
},
|
||||
{
|
||||
name: THIRD,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const allRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsWithHeader).toHaveLength(4);
|
||||
|
||||
const switchFilters = screen.getAllByRole('checkbox', {
|
||||
name: 'Select',
|
||||
});
|
||||
|
||||
await userEvent.click(switchFilters[0]);
|
||||
await userEvent.click(switchFilters[1]);
|
||||
|
||||
const discardButton = screen.getByRole('button', {
|
||||
name: 'Discard selected rows',
|
||||
});
|
||||
|
||||
await userEvent.click(discardButton);
|
||||
|
||||
const filteredRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsWithHeader).toHaveLength(2);
|
||||
|
||||
const validRow = screen.getByText(THIRD);
|
||||
expect(validRow).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Deletes selected rows, changes the last one', async () => {
|
||||
const FIRST_DELETE = 'first';
|
||||
const SECOND_DELETE = 'second';
|
||||
const THIRD = 'third';
|
||||
const THIRD_CHANGED = 'third_changed';
|
||||
|
||||
const initialData = [
|
||||
{
|
||||
name: FIRST_DELETE,
|
||||
},
|
||||
{
|
||||
name: SECOND_DELETE,
|
||||
},
|
||||
{
|
||||
name: THIRD,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
render(
|
||||
<Providers rsiValues={{ ...mockValues, fields }}>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const allRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(allRowsWithHeader).toHaveLength(4);
|
||||
|
||||
const switchFilters = screen.getAllByRole('checkbox', {
|
||||
name: 'Select',
|
||||
});
|
||||
|
||||
await userEvent.click(switchFilters[0]);
|
||||
await userEvent.click(switchFilters[1]);
|
||||
|
||||
const discardButton = screen.getByRole('button', {
|
||||
name: 'Discard selected rows',
|
||||
});
|
||||
|
||||
await userEvent.click(discardButton);
|
||||
|
||||
const filteredRowsWithHeader = await screen.findAllByRole('row');
|
||||
expect(filteredRowsWithHeader).toHaveLength(2);
|
||||
|
||||
const nameCell = screen.getByRole('gridcell', {
|
||||
name: THIRD,
|
||||
});
|
||||
|
||||
await userEvent.click(nameCell);
|
||||
|
||||
screen.getByRole<HTMLInputElement>('textbox');
|
||||
await userEvent.keyboard(THIRD_CHANGED + '{enter}');
|
||||
|
||||
const validRow = screen.getByText(THIRD_CHANGED);
|
||||
expect(validRow).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('All inputs change values', async () => {
|
||||
const NAME = 'John';
|
||||
const NEW_NAME = 'Johnny';
|
||||
const OPTIONS = [
|
||||
{ value: 'one', label: 'ONE' },
|
||||
{ value: 'two', label: 'TWO' },
|
||||
] as const;
|
||||
const initialData = [
|
||||
{
|
||||
name: NAME,
|
||||
lastName: OPTIONS[0].value,
|
||||
is_cool: false,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: null,
|
||||
label: 'lastName',
|
||||
key: 'lastName',
|
||||
fieldType: {
|
||||
type: 'select',
|
||||
options: OPTIONS,
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: null,
|
||||
label: 'is cool',
|
||||
key: 'is_cool',
|
||||
fieldType: {
|
||||
type: 'checkbox',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
render(
|
||||
<Providers
|
||||
rsiValues={{
|
||||
...mockValues,
|
||||
fields,
|
||||
}}
|
||||
>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
// input
|
||||
const nameCell = screen.getByRole('gridcell', {
|
||||
name: NAME,
|
||||
});
|
||||
|
||||
await userEvent.click(nameCell);
|
||||
|
||||
const input: HTMLInputElement | null =
|
||||
screen.getByRole<HTMLInputElement>('textbox');
|
||||
|
||||
expect(input).toHaveValue(NAME);
|
||||
expect(input).toHaveFocus();
|
||||
expect(input.selectionStart).toBe(0);
|
||||
expect(input.selectionEnd).toBe(NAME.length);
|
||||
|
||||
await userEvent.keyboard(NEW_NAME + '{enter}');
|
||||
expect(input).not.toBeInTheDocument();
|
||||
|
||||
const newNameCell = screen.getByRole('gridcell', {
|
||||
name: NEW_NAME,
|
||||
});
|
||||
expect(newNameCell).toBeInTheDocument();
|
||||
|
||||
// select
|
||||
const lastNameCell = screen.getByRole('gridcell', {
|
||||
name: OPTIONS[0].label,
|
||||
});
|
||||
await userEvent.click(lastNameCell);
|
||||
|
||||
const newOption = screen.getByRole('button', {
|
||||
name: OPTIONS[1].label,
|
||||
});
|
||||
await userEvent.click(newOption);
|
||||
expect(newOption).not.toBeInTheDocument();
|
||||
|
||||
const newLastName = screen.getByRole('gridcell', {
|
||||
name: OPTIONS[1].label,
|
||||
});
|
||||
expect(newLastName).toBeInTheDocument();
|
||||
|
||||
// Boolean
|
||||
const checkbox = screen.getByRole('checkbox', {
|
||||
name: '',
|
||||
});
|
||||
|
||||
expect(checkbox).not.toBeChecked();
|
||||
|
||||
await userEvent.click(checkbox);
|
||||
|
||||
expect(checkbox).toBeChecked();
|
||||
});
|
||||
|
||||
test('Row hook transforms data', async () => {
|
||||
const NAME = 'John';
|
||||
const LASTNAME = 'Doe';
|
||||
const NEW_NAME = 'Johnny';
|
||||
const NEW_LASTNAME = 'CENA';
|
||||
const initialData = [
|
||||
{
|
||||
name: NAME + ' ' + LASTNAME,
|
||||
lastName: undefined,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: null,
|
||||
label: 'lastName',
|
||||
key: 'lastName',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
render(
|
||||
<Providers
|
||||
rsiValues={{
|
||||
...mockValues,
|
||||
fields,
|
||||
rowHook: (value) => ({
|
||||
name: value.name?.toString()?.split(/(\s+)/)[0],
|
||||
lastName: value.name?.toString()?.split(/(\s+)/)[2],
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nameCell = screen.getByRole('gridcell', {
|
||||
name: NAME,
|
||||
});
|
||||
expect(nameCell).toBeInTheDocument();
|
||||
const lastNameCell = screen.getByRole('gridcell', {
|
||||
name: LASTNAME,
|
||||
});
|
||||
expect(lastNameCell).toBeInTheDocument();
|
||||
|
||||
// activate input
|
||||
await userEvent.click(nameCell);
|
||||
|
||||
await userEvent.keyboard(NEW_NAME + ' ' + NEW_LASTNAME + '{enter}');
|
||||
|
||||
const newNameCell = screen.getByRole('gridcell', {
|
||||
name: NEW_NAME,
|
||||
});
|
||||
expect(newNameCell).toBeInTheDocument();
|
||||
const newLastNameCell = screen.getByRole('gridcell', {
|
||||
name: NEW_LASTNAME,
|
||||
});
|
||||
expect(newLastNameCell).toBeInTheDocument();
|
||||
});
|
||||
test('Row hook raises error', async () => {
|
||||
const WRONG_NAME = 'Johnny';
|
||||
const RIGHT_NAME = 'Jonathan';
|
||||
const initialData = [
|
||||
{
|
||||
name: WRONG_NAME,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
render(
|
||||
<Providers
|
||||
rsiValues={{
|
||||
...mockValues,
|
||||
fields,
|
||||
rowHook: (value, setError) => {
|
||||
if (value.name === WRONG_NAME) {
|
||||
setError(fields[0].key, {
|
||||
message: 'Wrong name',
|
||||
level: 'error',
|
||||
});
|
||||
}
|
||||
return value;
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const switchFilter = getFilterSwitch();
|
||||
|
||||
await expect(await screen.findAllByRole('row')).toHaveLength(2);
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
await expect(await screen.findAllByRole('row')).toHaveLength(2);
|
||||
|
||||
const nameCell = screen.getByRole('gridcell', {
|
||||
name: WRONG_NAME,
|
||||
});
|
||||
expect(nameCell).toBeInTheDocument();
|
||||
|
||||
await userEvent.click(nameCell);
|
||||
screen.getByRole<HTMLInputElement>('textbox');
|
||||
|
||||
await userEvent.keyboard(RIGHT_NAME + '{enter}');
|
||||
|
||||
await expect(await screen.findAllByRole('row')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('Table hook transforms data', async () => {
|
||||
const NAME = 'John';
|
||||
const SECOND_NAME = 'Doe';
|
||||
const NEW_NAME = 'Jakee';
|
||||
const ADDITION = 'last';
|
||||
const initialData = [
|
||||
{
|
||||
name: NAME,
|
||||
},
|
||||
{
|
||||
name: SECOND_NAME,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
render(
|
||||
<Providers
|
||||
rsiValues={{
|
||||
...mockValues,
|
||||
fields,
|
||||
tableHook: (data) =>
|
||||
data.map((value) => ({
|
||||
name: value.name + ADDITION,
|
||||
})),
|
||||
}}
|
||||
>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const nameCell = screen.getByRole('gridcell', {
|
||||
name: NAME + ADDITION,
|
||||
});
|
||||
expect(nameCell).toBeInTheDocument();
|
||||
const lastNameCell = screen.getByRole('gridcell', {
|
||||
name: SECOND_NAME + ADDITION,
|
||||
});
|
||||
expect(lastNameCell).toBeInTheDocument();
|
||||
|
||||
// activate input
|
||||
await userEvent.click(nameCell);
|
||||
|
||||
await userEvent.keyboard(NEW_NAME + '{enter}');
|
||||
|
||||
const newNameCell = screen.getByRole('gridcell', {
|
||||
name: NEW_NAME + ADDITION,
|
||||
});
|
||||
expect(newNameCell).toBeInTheDocument();
|
||||
});
|
||||
test('Table hook raises error', async () => {
|
||||
const WRONG_NAME = 'Johnny';
|
||||
const RIGHT_NAME = 'Jonathan';
|
||||
const initialData = [
|
||||
{
|
||||
name: WRONG_NAME,
|
||||
},
|
||||
{
|
||||
name: WRONG_NAME,
|
||||
},
|
||||
];
|
||||
const fields = [
|
||||
{
|
||||
icon: null,
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
fieldType: {
|
||||
type: 'input',
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
render(
|
||||
<Providers
|
||||
rsiValues={{
|
||||
...mockValues,
|
||||
fields,
|
||||
tableHook: (data, setError) => {
|
||||
data.forEach((value, index) => {
|
||||
if (value.name === WRONG_NAME) {
|
||||
setError(index, fields[0].key, {
|
||||
message: 'Wrong name',
|
||||
level: 'error',
|
||||
});
|
||||
}
|
||||
return value;
|
||||
});
|
||||
return data;
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ModalWrapper isOpen={true} onClose={jest.fn()}>
|
||||
<ValidationStep initialData={initialData} file={file} />
|
||||
</ModalWrapper>
|
||||
</Providers>,
|
||||
);
|
||||
|
||||
const switchFilter = getFilterSwitch();
|
||||
|
||||
await expect(await screen.findAllByRole('row')).toHaveLength(3);
|
||||
|
||||
await userEvent.click(switchFilter);
|
||||
|
||||
await expect(await screen.findAllByRole('row')).toHaveLength(3);
|
||||
|
||||
const nameCell = await screen.getAllByRole('gridcell', {
|
||||
name: WRONG_NAME,
|
||||
})[0];
|
||||
|
||||
await userEvent.click(nameCell);
|
||||
screen.getByRole<HTMLInputElement>('textbox');
|
||||
|
||||
await userEvent.keyboard(RIGHT_NAME + '{enter}');
|
||||
|
||||
await expect(await screen.findAllByRole('row')).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
@ -30,7 +30,7 @@ export const SelectHeaderStep = ({ data, onContinue }: SelectHeaderProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const handleContinue = useCallback(async () => {
|
||||
const [selectedRowIndex] = selectedRows;
|
||||
const [selectedRowIndex] = Array.from(new Set(selectedRows));
|
||||
// We consider data above header to be redundant
|
||||
const trimmedData = data.slice(selectedRowIndex + 1);
|
||||
setIsLoading(true);
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { SpreadsheetImport } from '@/spreadsheet-import/components/SpreadsheetImport';
|
||||
import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues';
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
test('Close modal', async () => {
|
||||
let isOpen = true;
|
||||
const onClose = jest.fn(() => {
|
||||
isOpen = !isOpen;
|
||||
});
|
||||
const { getByText, getByLabelText } = render(
|
||||
<SpreadsheetImport {...mockRsiValues} onClose={onClose} isOpen={isOpen} />,
|
||||
);
|
||||
|
||||
const closeButton = getByLabelText('Close modal');
|
||||
|
||||
await userEvent.click(closeButton);
|
||||
|
||||
const confirmButton = getByText('Exit flow');
|
||||
|
||||
await userEvent.click(confirmButton);
|
||||
expect(onClose).toBeCalled();
|
||||
});
|
||||
|
||||
test('Should throw error if no fields are provided', async () => {
|
||||
const errorRender = () =>
|
||||
render(<SpreadsheetImport {...mockRsiValues} fields={undefined} />);
|
||||
|
||||
expect(errorRender).toThrow();
|
||||
});
|
||||
@ -3,7 +3,7 @@ import { BlockNoteView } from '@blocknote/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
interface BlockEditorProps {
|
||||
editor: BlockNoteEditor | null;
|
||||
editor: BlockNoteEditor;
|
||||
}
|
||||
|
||||
const StyledEditor = styled.div`
|
||||
|
||||
@ -162,7 +162,7 @@ function SortAndFilterBar<SortField>({
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{sorts.length && filtersWithDefinition.length && (
|
||||
{!!sorts.length && !!filtersWithDefinition.length && (
|
||||
<StyledSeperatorContainer>
|
||||
<StyledSeperator />
|
||||
</StyledSeperatorContainer>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
||||
4048
front/yarn.lock
4048
front/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user