Skip to content

Commit

Permalink
test: wrapped user input events into act
Browse files Browse the repository at this point in the history
Signed-off-by: Ihor Aleksandrychiev <ihor.aleksandrychiev@northern.tech>
  • Loading branch information
aleksandrychev committed Jan 24, 2024
1 parent 0372b03 commit a131e55
Show file tree
Hide file tree
Showing 22 changed files with 220 additions and 102 deletions.
6 changes: 4 additions & 2 deletions src/js/components/auditlogs/auditlogs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';

import { prettyDOM } from '@testing-library/dom';
import { screen, render as testingLibRender } from '@testing-library/react';
import { act, screen, render as testingLibRender } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { light as lightTheme } from '../../../../src/js/themes/Mender';
Expand Down Expand Up @@ -82,7 +82,9 @@ describe('Auditlogs Component', () => {
{ preloadedState }
);
const input = screen.getByPlaceholderText(/type/i);
await user.type(input, 'art');
await act(async () => {
await user.type(input, 'art');
});
await selectMaterialUiSelectOption(input, /artifact/i, user);
await user.click(screen.getByText(/clear filter/i));
await user.click(screen.getByRole('button', { name: /Download results as csv/i }));
Expand Down
6 changes: 4 additions & 2 deletions src/js/components/common/devicenameinput.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ describe('DeviceNameInput Component', () => {
expect(screen.queryByDisplayValue(/testname/i)).toBeInTheDocument();
await user.click(screen.getByRole('button'));
await waitFor(() => rerender(ui));
await user.type(screen.getByDisplayValue(/testname/i), 'something');
await user.click(screen.getAllByRole('button')[0]);
await act(async () => {
await user.type(screen.getByDisplayValue(/testname/i), 'something');
await user.click(screen.getAllByRole('button')[0]);
});
await act(async () => jest.runAllTicks());
await waitFor(() => expect(snackbarSpy).toHaveBeenCalledWith('Device name changed'));
expect(deviceTagsSpy).toHaveBeenCalledWith(defaultState.devices.byId.a1.id, { name: 'testnamesomething' });
Expand Down
38 changes: 26 additions & 12 deletions src/js/components/common/forms/keyvalueeditor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ describe('KeyValueEditor Component', () => {

const ui = <KeyValueEditor onInputChange={submitMock} />;
const { rerender } = render(ui);
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
});
expect(document.querySelector(fabSelector)).not.toBeDisabled();
await user.click(document.querySelector(fabSelector));
expect(submitMock).toHaveBeenLastCalledWith({ testKey: 'testValue' });
Expand All @@ -47,29 +49,37 @@ describe('KeyValueEditor Component', () => {
jest.runAllTimers();
jest.runAllTicks();
});
await user.type(screen.getByDisplayValue('testValue'), 's');
await act(async () => {
await user.type(screen.getByDisplayValue('testValue'), 's');
});
expect(submitMock).toHaveBeenLastCalledWith({ testKey: 'testValues' });
});

it('warns of duplicate keys', async () => {
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
const ui = <KeyValueEditor onInputChange={jest.fn} />;
const { rerender } = render(ui);
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
await user.click(document.querySelector(fabSelector));
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
await user.click(document.querySelector(fabSelector));
});
await waitFor(() => rerender(ui));
await user.type(screen.getAllByPlaceholderText(/key/i)[1], 'testKey');
await user.type(screen.getAllByPlaceholderText(/value/i)[1], 'testValue2');
await act(async () => {
await user.type(screen.getAllByPlaceholderText(/key/i)[1], 'testKey');
await user.type(screen.getAllByPlaceholderText(/value/i)[1], 'testValue2');
});
expect(screen.getByText(/Duplicate keys exist/i)).toBeInTheDocument();
});

it('forwards a warning', async () => {
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
const ui = <KeyValueEditor errortext="I should be rendered" onInputChange={jest.fn} />;
render(ui);
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
});
expect(screen.getByText(/I should be rendered/i)).toBeInTheDocument();
});

Expand All @@ -84,9 +94,13 @@ describe('KeyValueEditor Component', () => {

const ui = <KeyValueEditor inputHelpTipsMap={helptipsMap} onInputChange={jest.fn} />;
render(ui);
await user.type(screen.getByPlaceholderText(/key/i), 'timezon');
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'timezon');
});
expect(screen.queryByText(/testthing/i)).not.toBeInTheDocument();
await user.type(screen.getByPlaceholderText(/key/i), 'e');
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'e');
});
expect(screen.getByText(/testthing/i)).toBeInTheDocument();
});
});
5 changes: 3 additions & 2 deletions src/js/components/dashboard/dashboard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import React from 'react';
import { Route, Routes } from 'react-router-dom';

import { screen, waitFor } from '@testing-library/react';
import { act, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { defaultState, undefineds } from '../../../../tests/mockData';
Expand All @@ -29,8 +29,9 @@ describe('Dashboard Component', () => {
it('renders correctly', async () => {
const ui = <Dashboard />;
const { baseElement, rerender } = render(ui);
await waitFor(() => expect(reportsSpy).toHaveBeenCalled());
await act(async () => {});
await waitFor(() => rerender(ui));
await waitFor(() => expect(reportsSpy).toHaveBeenCalled());
const view = baseElement.firstChild;
expect(view).toMatchSnapshot();
expect(view).toEqual(expect.not.stringMatching(undefineds));
Expand Down
9 changes: 6 additions & 3 deletions src/js/components/deployments/deployments.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ describe('Deployments Component', () => {
const view = asFragment();
expect(view).toMatchSnapshot();
expect(view).toEqual(expect.not.stringMatching(undefineds));
await act(async () => {});
await waitFor(() => expect(get).toHaveBeenCalledWith('/api/management/v2/inventory/filters?per_page=500'));
expect(get).toHaveBeenCalledWith('/api/management/v2/inventory/filters?per_page=500');
});
Expand Down Expand Up @@ -175,7 +174,9 @@ describe('Deployments Component', () => {
await waitFor(() => expect(screen.queryByPlaceholderText(/Select a Release/i)).toBeInTheDocument(), { timeout: 3000 });
const releaseSelect = screen.getByPlaceholderText(/Select a Release/i);
expect(within(releaseSelect).queryByDisplayValue(releaseId)).not.toBeInTheDocument();
await user.click(releaseSelect);
await act(async () => {
await user.click(releaseSelect);
});
await user.keyboard(specialKeys.ArrowDown);
await user.keyboard(specialKeys.Enter);
act(() => jest.advanceTimersByTime(2000));
Expand Down Expand Up @@ -266,7 +267,9 @@ describe('Deployments Component', () => {
expect(groupSelect).toHaveValue(ALL_DEVICES);
await waitFor(() => expect(screen.queryByPlaceholderText(/Select a Release/i)).toBeInTheDocument(), { timeout: 3000 });
const releaseSelect = screen.getByPlaceholderText(/Select a Release/i);
await user.click(releaseSelect);
await act(async () => {
await user.click(releaseSelect);
});
await user.keyboard(specialKeys.ArrowDown);
await user.keyboard(specialKeys.Enter);
act(() => jest.advanceTimersByTime(2000));
Expand Down
6 changes: 4 additions & 2 deletions src/js/components/devices/authorized-devices.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,10 @@ describe('AuthorizedDevices Component', () => {
await waitFor(() => rerender(ui));
expect(screen.getByText(/Customize Columns/i)).toBeVisible();
const attributeSelect = screen.getByLabelText(/add a column/i);
await user.type(attributeSelect, testKey);
await user.keyboard('{Enter}');
await act(async () => {
await user.type(attributeSelect, testKey);
await user.keyboard('{Enter}');
});
act(() => jest.advanceTimersByTime(5000));
await waitFor(() => expect(screen.getByLabelText(/add a column/i)).toBeVisible());
const button = screen.getByRole('button', { name: /Save/i });
Expand Down
20 changes: 13 additions & 7 deletions src/js/components/devices/device-details/configuration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,15 @@ describe('Configuration Component', () => {
expect(screen.getByRole('button', { name: /import configuration/i })).toBeInTheDocument();
const fabButton = document.querySelector('.MuiFab-root');
expect(fabButton).toBeDisabled();
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'evilValue');
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'evilValue');
});
expect(fabButton).not.toBeDisabled();
await user.click(screen.getByRole('checkbox', { name: /save/i }));
await user.click(screen.getByRole('button', { name: /save/i }));
await act(async () => {
await user.click(screen.getByRole('checkbox', {name: /save/i}));
await user.click(screen.getByRole('button', {name: /save/i}));
});
await waitFor(() => rerender(ui));

expect(screen.getByText(/Configuration could not be updated on device/i)).toBeInTheDocument();
Expand All @@ -148,9 +152,11 @@ describe('Configuration Component', () => {
await waitFor(() => rerender(ui));
await waitFor(() => expect(document.querySelector('.loaderContainer')).not.toBeInTheDocument());
const valueInput = screen.getByDisplayValue('evilValue');
await user.clear(valueInput);
await user.type(valueInput, 'testValue');
await user.click(screen.getByRole('button', { name: /Retry/i }));
await act(async () => {
await user.clear(valueInput);
await user.type(valueInput, 'testValue');
await user.click(screen.getByRole('button', {name: /Retry/i}));
});
await waitFor(() => expect(screen.queryByText(/Updating configuration/i)).toBeInTheDocument());
});
});
14 changes: 10 additions & 4 deletions src/js/components/devices/dialogs/preauth-dialog.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,13 @@ describe('PreauthDialog Component', () => {
});
await waitFor(() => rerender(ui));
await waitFor(() => expect(screen.queryByText(errorText)).toBeTruthy());
await user.type(screen.getByDisplayValue('testValue'), 'testValues');
await act(async () => {
await user.type(screen.getByDisplayValue('testValue'), 'testValues');
});
await waitFor(() => expect(screen.queryByText(errorText)).not.toBeInTheDocument());
await user.click(screen.getByRole('button', { name: 'Save and add another' }));
await act(async () => {
await user.click(screen.getByRole('button', {name: 'Save and add another'}));
});
await waitFor(() => rerender(ui));
expect(screen.queryByText('reached your limit')).toBeFalsy();
expect(preAuthSpy).toHaveBeenCalled();
Expand All @@ -111,8 +115,10 @@ describe('PreauthDialog Component', () => {
await user.upload(uploadInput, menderFile);
});
await waitFor(() => rerender(ui));
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
await act(async () => {
await user.type(screen.getByPlaceholderText(/key/i), 'testKey');
await user.type(screen.getByPlaceholderText(/value/i), 'testValue');
});
await waitFor(() => rerender(ui));
expect(screen.getByText(/You have reached your limit/i)).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Save' })).toBeDisabled();
Expand Down
10 changes: 7 additions & 3 deletions src/js/components/header/header.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.
import React from 'react';

import { screen, waitFor, within } from '@testing-library/react';
import { act, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { defaultState, undefineds } from '../../../../tests/mockData';
Expand Down Expand Up @@ -58,10 +58,14 @@ describe('Header Component', () => {
const { rerender } = render(view, { preloadedState });
expect(screen.queryByText(defaultState.users.byId[defaultState.users.currentUser].email)).toBeInTheDocument();
const selectButton = screen.getByRole('button', { name: defaultState.users.byId[defaultState.users.currentUser].email });
await user.click(selectButton);
await act(async () => {
await user.click(selectButton);
});
const listbox = document.body.querySelector('ul[role=menu]');
const listItem = within(listbox).getByText(/log out/i);
await user.click(listItem);
await act(async () => {
await user.click(listItem);
});
await waitFor(() => rerender(view));
expect(screen.queryByText(defaultState.users.byId[defaultState.users.currentUser].email)).not.toBeInTheDocument();
});
Expand Down
1 change: 1 addition & 0 deletions src/js/components/helptips/onboardingcompletetip.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ describe('OnboardingCompleteTip Component', () => {
const view = baseElement;
expect(view).toMatchSnapshot();
expect(view).toEqual(expect.not.stringMatching(undefineds));
await act(async () => {});
});
});
20 changes: 13 additions & 7 deletions src/js/components/login/login.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.
import React from 'react';

import { screen, waitFor } from '@testing-library/react';
import { act, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { defaultState, undefineds } from '../../../../tests/mockData';
Expand Down Expand Up @@ -45,17 +45,23 @@ describe('Login Component', () => {
const loginSpy = jest.spyOn(UserActions, 'loginUser');
const ui = <Login />;
const { rerender } = render(ui, { preloadedState });
await user.type(screen.getByLabelText(/your email/i), 'something-2fa@example.com');
await user.type(screen.getByLabelText(/password/i), 'mysecretpassword!123');
await act(async () => {
await user.type(screen.getByLabelText(/your email/i), 'something-2fa@example.com');
await user.type(screen.getByLabelText(/password/i), 'mysecretpassword!123');
});
expect(await screen.findByLabelText(/Two Factor Authentication Code/i)).not.toBeVisible();
await user.click(screen.getByRole('button', { name: /Log in/i }));
await act(async () => {
await user.click(screen.getByRole('button', { name: /Log in/i }));
});
expect(loginSpy).toHaveBeenCalled();
await waitFor(() => rerender(ui));
expect(await screen.findByLabelText(/Two Factor Authentication Code/i)).toBeVisible();
const input = screen.getByDisplayValue('something-2fa@example.com');
await user.clear(input);
await user.type(input, 'something@example.com');
await user.type(screen.getByLabelText(/Two Factor Authentication Code/i), '123456');
await act(async () => {
await user.clear(input);
await user.type(input, 'something@example.com');
await user.type(screen.getByLabelText(/Two Factor Authentication Code/i), '123456');
});
await user.click(screen.getByRole('button', { name: /Log in/i }));
expect(loginSpy).toHaveBeenCalledWith({ email: 'something@example.com', password: 'mysecretpassword!123', token2fa: '123456' }, false);
}, 10000);
Expand Down
2 changes: 1 addition & 1 deletion src/js/components/login/password.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('Password Component', () => {
const ui = <Password />;
const { rerender } = render(ui);
await user.type(screen.queryByLabelText(/your email/i), 'something@example.com');
await user.click(screen.getByRole('button', { name: /Send password reset link/i }));
await user.click(screen.getByRole('button', {name: /Send password reset link/i}));
await waitFor(() => expect(startSpy).toHaveBeenCalledWith('something@example.com'));
await waitFor(() => rerender(ui));
await waitFor(() => expect(screen.queryByText(/sending you an email/i)).toBeInTheDocument(), { timeout: 5000 });
Expand Down
20 changes: 14 additions & 6 deletions src/js/components/login/passwordreset.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,25 @@ describe('PasswordReset Component', () => {
const { rerender } = testingLibRender(ui);

const passwordInput = screen.getByLabelText('Password *');
await user.type(passwordInput, badPassword);
await act(async () => {
await user.type(passwordInput, badPassword);
});
await waitFor(() => rerender(ui));
await user.type(passwordInput, badPassword);
await user.type(screen.getByLabelText(/confirm password \*/i), goodPassword);
await act(async () => {
await user.type(passwordInput, badPassword);
await user.type(screen.getByLabelText(/confirm password \*/i), goodPassword);
});
await waitFor(() => rerender(ui));
expect(screen.getByRole('button', { name: /Save password/i })).toBeDisabled();
expect(screen.getByText('The passwords you provided do not match, please check again.')).toBeVisible();
await user.clear(passwordInput);
await user.type(passwordInput, goodPassword);
await act(async () => {
await user.clear(passwordInput);
await user.type(passwordInput, goodPassword);
});
await waitFor(() => rerender(ui));
await user.click(screen.getByRole('button', { name: /Save password/i }));
await act(async () => {
await user.click(screen.getByRole('button', {name: /Save password/i}));
});
await waitFor(() => expect(completeSpy).toHaveBeenCalledWith(secretHash, goodPassword));
await act(async () => {
jest.runAllTimers();
Expand Down
26 changes: 19 additions & 7 deletions src/js/components/login/signup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,36 @@ describe('Signup Component', () => {
);
const { container, rerender } = render(ui);
expect(screen.getByText('Sign up with:')).toBeInTheDocument();
await user.type(screen.getByLabelText(/Email/i), 'test@example.com');
await user.type(screen.getByLabelText('Password *'), 'mysecretpassword!123');
await act(async () => {
await user.type(screen.getByLabelText(/Email/i), 'test@example.com');
await user.type(screen.getByLabelText('Password *'), 'mysecretpassword!123');
});
expect(screen.getByRole('button', { name: /sign up/i })).toBeDisabled();
await user.type(screen.getByLabelText(/Confirm password/i), 'mysecretpassword!123');
await act(async () => {
await user.type(screen.getByLabelText(/Confirm password/i), 'mysecretpassword!123');
});
expect(container.querySelector('#pass-strength > meter')).toBeVisible();
await waitFor(() => rerender(ui));
expect(screen.getByRole('button', { name: /sign up/i })).toBeEnabled();
await user.click(screen.getByRole('button', { name: /sign up/i }));
await act(async () => {
await user.click(screen.getByRole('button', {name: /sign up/i}));
});
await waitFor(() => screen.queryByText('Company or organization name *'));
await user.type(screen.getByRole('textbox', { name: /company or organization name \*/i }), 'test');
await act(async () => {
await user.type(screen.getByRole('textbox', {name: /company or organization name \*/i}), 'test');
});
expect(screen.getByRole('button', { name: /complete signup/i })).toBeDisabled();
await user.click(screen.getByRole('checkbox', { name: /by checking this you agree to our/i }));
await act(async () => {
await user.click(screen.getByRole('checkbox', {name: /by checking this you agree to our/i}));
});
await waitFor(() => rerender(ui));
expect(screen.getByRole('button', { name: /complete signup/i })).toBeEnabled();

const cookies = new Cookies();
cookies.set.mockReturnValue();
await user.click(screen.getByRole('button', { name: /complete signup/i }));
await act(async () => {
await user.click(screen.getByRole('button', {name: /complete signup/i}));
});
await waitFor(() => expect(container.querySelector('.loaderContainer')).toBeVisible());
await act(async () => jest.advanceTimersByTime(5000));
await waitFor(() => rerender(ui));
Expand Down
Loading

0 comments on commit a131e55

Please sign in to comment.