Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
siarhei-epam committed Sep 11, 2024
2 parents 6fd3dca + f3d4123 commit e5de9d7
Showing 1 changed file with 218 additions and 1 deletion.
219 changes: 218 additions & 1 deletion uui/components/pickers/__tests__/PickerInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,76 @@ async function setupPickerInputForTest<TItem = TestItemType, TId = number>(param
};
}

async function setupPickerInputForTestWithFirstValueChangeRewriting<TItem = TestItemType, TId = number>(
params: Partial<PickerInputComponentProps<TItem, TId> & { valueForFirstUpdate: TItem | TId | TItem[] | TId[] }>,
) {
const { result, mocks, setProps } = await setupComponentForTest<PickerInputComponentProps<TItem, TId>>(
(context): PickerInputComponentProps<TItem, TId> => {
if (params.selectionMode === 'single') {
let updatesCounter = 0;
return Object.assign({
onValueChange: jest.fn().mockImplementation((newValue) => {
if (updatesCounter === 0) {
updatesCounter++;
return context.current?.setProperty('value', params.valueForFirstUpdate);
}

if (typeof newValue === 'function') {
const v = newValue(params.value);
context.current?.setProperty('value', v);
}
context.current?.setProperty('value', newValue);
}),
dataSource: mockDataSourceAsync,
disableClear: false,
searchPosition: 'input',
getName: (item: TestItemType) => item.level,
value: params.value as TId,
searchDebounceDelay: 0,
}, params) as PickerInputComponentProps<TItem, TId>;
}

let updatesCounter = 0;
return Object.assign({
onValueChange: jest.fn().mockImplementation((newValue) => {
if (updatesCounter === 0) {
updatesCounter++;
return context.current?.setProperty('value', params.valueForFirstUpdate);
}

if (typeof newValue === 'function') {
const v = newValue(params.value);
context.current?.setProperty('value', v);
return;
}
context.current?.setProperty('value', newValue);
}),
dataSource: mockDataSourceAsync,
disableClear: false,
searchPosition: 'input',
getName: (item: TestItemType) => item.level,
value: params.value as number[],
selectionMode: 'multi',
searchDebounceDelay: 0,
}, params) as PickerInputComponentProps<TItem, TId>;
},
(props) => (
<>
<PickerInput { ...props } />
<Modals />
</>
),
);
const input = screen.queryByRole('textbox') as HTMLElement;

return {
setProps,
result,
mocks,
dom: { input, container: result.container, target: result.container.firstElementChild as HTMLElement },
};
}

describe('PickerInput', () => {
beforeEach(() => {
jest.spyOn(HTMLElement.prototype, 'getBoundingClientRect').mockImplementation(() => {
Expand Down Expand Up @@ -172,6 +242,39 @@ describe('PickerInput', () => {
expect(screen.queryByText('C2')).not.toBeInTheDocument();
});

it('[valueType id] should listen to value change', async () => {
const { dom, mocks } = await setupPickerInputForTestWithFirstValueChangeRewriting({
selectionMode: 'single',
});
expect(PickerInputTestObject.getPlaceholderText(dom.input)).toEqual('Please select');
fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();
const optionC2 = await screen.findByText('C2');
fireEvent.click(optionC2);
await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith(12);
});

fireEvent.click(window.document.body);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();

await waitFor(() => {
expect(screen.queryByText('C2')).not.toBeInTheDocument();
});

fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();
const option2C2 = await screen.findByText('C2');
fireEvent.click(option2C2);

await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith(12);
});
await waitFor(() => {
expect(screen.getByPlaceholderText('C2')).toBeInTheDocument();
});
});

it('should close body on click outside', async () => {
const { dom } = await setupPickerInputForTest({
value: undefined,
Expand Down Expand Up @@ -251,6 +354,41 @@ describe('PickerInput', () => {
});
});

it('[valueType entity] should listen to value change', async () => {
const { dom, mocks } = await setupPickerInputForTestWithFirstValueChangeRewriting({
value: undefined,
selectionMode: 'single',
valueType: 'entity',
});
expect(PickerInputTestObject.getPlaceholderText(dom.input)).toEqual('Please select');
fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();
const optionC2 = await screen.findByText('C2');
fireEvent.click(optionC2);
await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith({ id: 12, level: 'C2', name: 'Proficiency' });
});

fireEvent.click(window.document.body);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();

await waitFor(() => {
expect(screen.queryByText('C2')).not.toBeInTheDocument();
});

fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();
const option2C2 = await screen.findByText('C2');
fireEvent.click(option2C2);

await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith({ id: 12, level: 'C2', name: 'Proficiency' });
});
await waitFor(() => {
expect(screen.getByPlaceholderText('C2')).toBeInTheDocument();
});
});

it('should render names of items by getName', async () => {
const { mocks, dom } = await setupPickerInputForTest<TestItemType, number>({
value: 3,
Expand Down Expand Up @@ -534,6 +672,85 @@ describe('PickerInput', () => {
expect(await PickerInputTestObject.getSelectedTagsText(dom.target)).toEqual(['A1', 'A1+']);
});

it('[valueType id] should listen to value change', async () => {
const { dom, mocks } = await setupPickerInputForTestWithFirstValueChangeRewriting({
valueForFirstUpdate: [4],
value: undefined,
selectionMode: 'multi',
valueType: 'id',
});

expect(PickerInputTestObject.getPlaceholderText(dom.input)).toEqual('Please select');
fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();

await PickerInputTestObject.clickOptionCheckbox('A1');

await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith([2]);
});
expect(await PickerInputTestObject.getSelectedTagsText(dom.target)).toEqual(['A2']);

fireEvent.click(window.document.body);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();

fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();
await PickerInputTestObject.clickOptionCheckbox('A1');

await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith([4, 2]);
});
expect(await PickerInputTestObject.getSelectedTagsText(dom.target)).toEqual(['A2', 'A1']);
});

it('[valueType entity] should listen to value change', async () => {
const { dom, mocks } = await setupPickerInputForTestWithFirstValueChangeRewriting({
valueForFirstUpdate: [{ id: 4, level: 'A2', name: 'Pre-Intermediate' }],
value: undefined,
selectionMode: 'multi',
valueType: 'entity',
});

expect(PickerInputTestObject.getPlaceholderText(dom.input)).toEqual('Please select');
fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();

await PickerInputTestObject.clickOptionCheckbox('A1');

await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith([{
id: 2,
level: 'A1',
name: 'Elementary',
}]);
});
expect(await PickerInputTestObject.getSelectedTagsText(dom.target)).toEqual(['A2']);

fireEvent.click(window.document.body);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();

fireEvent.click(dom.input);
expect(screen.getByRole('dialog')).toBeInTheDocument();
await act(async () => {
await PickerInputTestObject.clickOptionCheckbox('A1');
});

await waitFor(() => {
expect(mocks.onValueChange).toHaveBeenLastCalledWith([{
id: 4,
level: 'A2',
name: 'Pre-Intermediate',
},
{
id: 2,
level: 'A1',
name: 'Elementary',
}]);
});
expect(await PickerInputTestObject.getSelectedTagsText(dom.target)).toEqual(['A2', 'A1']);
});

it('[valueType entity] should select & clear several options', async () => {
const { dom, mocks } = await setupPickerInputForTest({
value: undefined,
Expand Down Expand Up @@ -1429,7 +1646,7 @@ describe('PickerInput', () => {
('should not call onValueChange on edit search with emptyValue = %s; and return emptyValue = %s on check -> uncheck', async (emptyValue) => {
const { dom, mocks } = await setupPickerInputForTest<TestItemType, number>({
emptyValue: emptyValue,
value: emptyValue,
value: emptyValue as (undefined | []),
selectionMode: 'multi',
searchPosition: 'body',
});
Expand Down

0 comments on commit e5de9d7

Please sign in to comment.