Replaced firEvent with userEvent as much as possible

This commit is contained in:
Alejandro Celaya 2022-05-11 19:18:43 +02:00
parent 7f059c3f3b
commit 3870752bba
9 changed files with 121 additions and 93 deletions

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { ErrorHandler as createErrorHandler } from '../../src/common/ErrorHandler'; import { ErrorHandler as createErrorHandler } from '../../src/common/ErrorHandler';
@ -34,11 +35,12 @@ describe('<ErrorHandler />', () => {
expect(screen.getByRole('button')).toBeInTheDocument(); expect(screen.getByRole('button')).toBeInTheDocument();
}); });
it('reloads page on button click', () => { it('reloads page on button click', async () => {
const user = userEvent.setup();
render(<ErrorHandler children={<ComponentWithError />} />); render(<ErrorHandler children={<ComponentWithError />} />);
expect(reload).not.toHaveBeenCalled(); expect(reload).not.toHaveBeenCalled();
fireEvent.click(screen.getByRole('button')); await user.click(screen.getByRole('button'));
expect(reload).toHaveBeenCalled(); expect(reload).toHaveBeenCalled();
}); });
}); });

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Router } from 'react-router-dom'; import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { MainHeader as createMainHeader } from '../../src/common/MainHeader'; import { MainHeader as createMainHeader } from '../../src/common/MainHeader';
@ -9,11 +10,14 @@ describe('<MainHeader />', () => {
const history = createMemoryHistory(); const history = createMemoryHistory();
history.push(pathname); history.push(pathname);
return render( const user = userEvent.setup();
const renderResult = render(
<Router location={history.location} navigator={history}> <Router location={history.location} navigator={history}>
<MainHeader /> <MainHeader />
</Router>, </Router>,
); );
return { user, ...renderResult };
}; };
it('renders ServersDropdown', () => { it('renders ServersDropdown', () => {
@ -37,29 +41,29 @@ describe('<MainHeader />', () => {
} }
}); });
it('renders expected class based on the nav bar state', () => { it('renders expected class based on the nav bar state', async () => {
setUp(); const { user } = setUp();
const toggle = screen.getByLabelText('Toggle navigation'); const toggle = screen.getByLabelText('Toggle navigation');
const icon = toggle.firstChild; const icon = toggle.firstChild;
expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/)); expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/));
fireEvent.click(toggle); await user.click(toggle);
expect(icon).toHaveAttribute( expect(icon).toHaveAttribute(
'class', 'class',
expect.stringMatching(/main-header__toggle-icon main-header__toggle-icon--opened$/), expect.stringMatching(/main-header__toggle-icon main-header__toggle-icon--opened$/),
); );
fireEvent.click(toggle); await user.click(toggle);
expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/)); expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/));
}); });
it('opens Collapse when clicking toggle', async () => { it('opens Collapse when clicking toggle', async () => {
const { container } = setUp(); const { container, user } = setUp();
const collapse = container.querySelector('.collapse'); const collapse = container.querySelector('.collapse');
const toggle = screen.getByLabelText('Toggle navigation'); const toggle = screen.getByLabelText('Toggle navigation');
expect(collapse).not.toHaveAttribute('class', expect.stringContaining('show')); expect(collapse).not.toHaveAttribute('class', expect.stringContaining('show'));
fireEvent.click(toggle); await user.click(toggle);
await waitFor(() => expect(collapse).toHaveAttribute('class', expect.stringContaining('show'))); await waitFor(() => expect(collapse).toHaveAttribute('class', expect.stringContaining('show')));
}); });
}); });

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { DomainSelector } from '../../src/domains/DomainSelector'; import { DomainSelector } from '../../src/domains/DomainSelector';
import { DomainsList } from '../../src/domains/reducers/domainsList'; import { DomainsList } from '../../src/domains/reducers/domainsList';
@ -12,9 +13,10 @@ describe('<DomainSelector />', () => {
Mock.of<ShlinkDomain>({ domain: 'bar.com' }), Mock.of<ShlinkDomain>({ domain: 'bar.com' }),
], ],
}); });
const setUp = (value = '') => render( const setUp = (value = '') => ({
<DomainSelector value={value} domainsList={domainsList} listDomains={jest.fn()} onChange={jest.fn()} />, user: userEvent.setup(),
); ...render(<DomainSelector value={value} domainsList={domainsList} listDomains={jest.fn()} onChange={jest.fn()} />),
});
afterEach(jest.clearAllMocks); afterEach(jest.clearAllMocks);
@ -22,8 +24,7 @@ describe('<DomainSelector />', () => {
['', 'Domain', 'domains-dropdown__toggle-btn'], ['', 'Domain', 'domains-dropdown__toggle-btn'],
['my-domain.com', 'Domain: my-domain.com', 'domains-dropdown__toggle-btn--active'], ['my-domain.com', 'Domain: my-domain.com', 'domains-dropdown__toggle-btn--active'],
])('shows dropdown by default', async (value, expectedText, expectedClassName) => { ])('shows dropdown by default', async (value, expectedText, expectedClassName) => {
setUp(value); const { user } = setUp(value);
const btn = screen.getByRole('button', { name: expectedText }); const btn = screen.getByRole('button', { name: expectedText });
expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument(); expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument();
@ -31,25 +32,25 @@ describe('<DomainSelector />', () => {
'class', 'class',
`dropdown-btn__toggle btn-block ${expectedClassName} dropdown-toggle btn btn-primary`, `dropdown-btn__toggle btn-block ${expectedClassName} dropdown-toggle btn btn-primary`,
); );
fireEvent.click(btn); await user.click(btn);
await waitFor(() => expect(screen.getByRole('menu')).toBeInTheDocument()); await waitFor(() => expect(screen.getByRole('menu')).toBeInTheDocument());
expect(screen.getAllByRole('menuitem')).toHaveLength(4); expect(screen.getAllByRole('menuitem')).toHaveLength(4);
}); });
it('allows toggling between dropdown and input', async () => { it('allows toggling between dropdown and input', async () => {
setUp(); const { user } = setUp();
expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument(); expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Domain' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Domain' })).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'Domain' })); await user.click(screen.getByRole('button', { name: 'Domain' }));
fireEvent.click(await screen.findByText('New domain')); await user.click(await screen.findByText('New domain'));
expect(screen.getByPlaceholderText('Domain')).toBeInTheDocument(); expect(screen.getByPlaceholderText('Domain')).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Domain' })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Domain' })).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'Back to domains list' })); await user.click(screen.getByRole('button', { name: 'Back to domains list' }));
expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument(); expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Domain' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Domain' })).toBeInTheDocument();
@ -60,9 +61,9 @@ describe('<DomainSelector />', () => {
[1, 'foo.com'], [1, 'foo.com'],
[2, 'bar.com'], [2, 'bar.com'],
])('shows expected content on every item', async (index, expectedContent) => { ])('shows expected content on every item', async (index, expectedContent) => {
setUp(); const { user } = setUp();
fireEvent.click(screen.getByRole('button', { name: 'Domain' })); await user.click(screen.getByRole('button', { name: 'Domain' }));
const items = await screen.findAllByRole('menuitem'); const items = await screen.findAllByRole('menuitem');
expect(items[index]).toHaveTextContent(expectedContent); expect(items[index]).toHaveTextContent(expectedContent);

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen, waitForElementToBeRemoved } from '@testing-library/react'; import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { DomainDropdown } from '../../../src/domains/helpers/DomainDropdown'; import { DomainDropdown } from '../../../src/domains/helpers/DomainDropdown';
@ -8,7 +9,9 @@ import { SemVer } from '../../../src/utils/helpers/version';
describe('<DomainDropdown />', () => { describe('<DomainDropdown />', () => {
const editDomainRedirects = jest.fn().mockResolvedValue(undefined); const editDomainRedirects = jest.fn().mockResolvedValue(undefined);
const setUp = (domain?: Domain, selectedServer?: SelectedServer) => render( const setUp = (domain?: Domain, selectedServer?: SelectedServer) => ({
user: userEvent.setup(),
...render(
<MemoryRouter> <MemoryRouter>
<DomainDropdown <DomainDropdown
domain={domain ?? Mock.all<Domain>()} domain={domain ?? Mock.all<Domain>()}
@ -16,7 +19,8 @@ describe('<DomainDropdown />', () => {
editDomainRedirects={editDomainRedirects} editDomainRedirects={editDomainRedirects}
/> />
</MemoryRouter>, </MemoryRouter>,
); ),
});
afterEach(jest.clearAllMocks); afterEach(jest.clearAllMocks);
@ -61,25 +65,25 @@ describe('<DomainDropdown />', () => {
['bar.org'], ['bar.org'],
['baz.net'], ['baz.net'],
])('displays modal when editing redirects', async (domain) => { ])('displays modal when editing redirects', async (domain) => {
setUp(Mock.of<Domain>({ domain, isDefault: false })); const { user } = setUp(Mock.of<Domain>({ domain, isDefault: false }));
expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
expect(screen.queryByRole('form')).not.toBeInTheDocument(); expect(screen.queryByRole('form')).not.toBeInTheDocument();
fireEvent.click(screen.getByText('Edit redirects')); await user.click(screen.getByText('Edit redirects'));
expect(await screen.findByRole('dialog')).toBeInTheDocument(); expect(await screen.findByRole('dialog')).toBeInTheDocument();
expect(editDomainRedirects).not.toHaveBeenCalled(); expect(editDomainRedirects).not.toHaveBeenCalled();
fireEvent.click(screen.getByText('Save')); await user.click(screen.getByText('Save'));
expect(editDomainRedirects).toHaveBeenCalledWith(domain, expect.anything()); expect(editDomainRedirects).toHaveBeenCalledWith(domain, expect.anything());
await waitForElementToBeRemoved(() => screen.queryByRole('dialog')); await waitForElementToBeRemoved(() => screen.queryByRole('dialog'));
}); });
it('displays dropdown when clicked', async () => { it('displays dropdown when clicked', async () => {
setUp(); const { user } = setUp();
expect(screen.queryByRole('menu')).not.toBeInTheDocument(); expect(screen.queryByRole('menu')).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { expanded: false })); await user.click(screen.getByRole('button', { expanded: false }));
expect(await screen.findByRole('menu')).toBeInTheDocument(); expect(await screen.findByRole('menu')).toBeInTheDocument();
}); });
}); });

View file

@ -1,16 +1,20 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { ShortUrlCreationSettings as ShortUrlsSettings, Settings } from '../../src/settings/reducers/settings'; import { ShortUrlCreationSettings as ShortUrlsSettings, Settings } from '../../src/settings/reducers/settings';
import { ShortUrlCreationSettings } from '../../src/settings/ShortUrlCreationSettings'; import { ShortUrlCreationSettings } from '../../src/settings/ShortUrlCreationSettings';
describe('<ShortUrlCreationSettings />', () => { describe('<ShortUrlCreationSettings />', () => {
const setShortUrlCreationSettings = jest.fn(); const setShortUrlCreationSettings = jest.fn();
const setUp = (shortUrlCreation?: ShortUrlsSettings) => render( const setUp = (shortUrlCreation?: ShortUrlsSettings) => ({
user: userEvent.setup(),
...render(
<ShortUrlCreationSettings <ShortUrlCreationSettings
settings={Mock.of<Settings>({ shortUrlCreation })} settings={Mock.of<Settings>({ shortUrlCreation })}
setShortUrlCreationSettings={setShortUrlCreationSettings} setShortUrlCreationSettings={setShortUrlCreationSettings}
/>, />,
); ),
});
afterEach(jest.clearAllMocks); afterEach(jest.clearAllMocks);
@ -75,28 +79,27 @@ describe('<ShortUrlCreationSettings />', () => {
expect(screen.getByText(/^The list of suggested tags will contain those/)).toHaveTextContent(expectedHint); expect(screen.getByText(/^The list of suggested tags will contain those/)).toHaveTextContent(expectedHint);
}); });
it.each([[true], [false]])('invokes setShortUrlCreationSettings when URL validation toggle value changes', (validateUrls) => { it.each([[true], [false]])('invokes setShortUrlCreationSettings when URL validation toggle value changes', async (validateUrls) => {
setUp({ validateUrls }); const { user } = setUp({ validateUrls });
expect(setShortUrlCreationSettings).not.toHaveBeenCalled(); expect(setShortUrlCreationSettings).not.toHaveBeenCalled();
fireEvent.click(screen.getByLabelText(/^Request validation on long URLs when creating new short URLs/)); await user.click(screen.getByLabelText(/^Request validation on long URLs when creating new short URLs/));
expect(setShortUrlCreationSettings).toHaveBeenCalledWith({ validateUrls: !validateUrls }); expect(setShortUrlCreationSettings).toHaveBeenCalledWith({ validateUrls: !validateUrls });
}); });
it.each([[true], [false]])('invokes setShortUrlCreationSettings when forward query toggle value changes', (forwardQuery) => { it.each([[true], [false]])('invokes setShortUrlCreationSettings when forward query toggle value changes', async (forwardQuery) => {
setUp({ validateUrls: true, forwardQuery }); const { user } = setUp({ validateUrls: true, forwardQuery });
expect(setShortUrlCreationSettings).not.toHaveBeenCalled(); expect(setShortUrlCreationSettings).not.toHaveBeenCalled();
fireEvent.click(screen.getByLabelText(/^Make all new short URLs forward their query params to the long URL/)); await user.click(screen.getByLabelText(/^Make all new short URLs forward their query params to the long URL/));
expect(setShortUrlCreationSettings).toHaveBeenCalledWith(expect.objectContaining({ forwardQuery: !forwardQuery })); expect(setShortUrlCreationSettings).toHaveBeenCalledWith(expect.objectContaining({ forwardQuery: !forwardQuery }));
}); });
it('invokes setShortUrlCreationSettings when dropdown value changes', async () => { it('invokes setShortUrlCreationSettings when dropdown value changes', async () => {
setUp(); const { user } = setUp();
const clickItem = async (name: string) => { const clickItem = async (name: string) => {
fireEvent.click(screen.getByRole('button', { name: 'Suggest tags starting with input' })); await user.click(screen.getByRole('button', { name: 'Suggest tags starting with input' }));
fireEvent.click(await screen.findByRole('menuitem', { name })); await user.click(await screen.findByRole('menuitem', { name }));
}; };
expect(setShortUrlCreationSettings).not.toHaveBeenCalled(); expect(setShortUrlCreationSettings).not.toHaveBeenCalled();

View file

@ -1,12 +1,14 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { UseExistingIfFoundInfoIcon } from '../../src/short-urls/UseExistingIfFoundInfoIcon'; import { UseExistingIfFoundInfoIcon } from '../../src/short-urls/UseExistingIfFoundInfoIcon';
describe('<UseExistingIfFoundInfoIcon />', () => { describe('<UseExistingIfFoundInfoIcon />', () => {
it('shows modal when icon is clicked', async () => { it('shows modal when icon is clicked', async () => {
const user = userEvent.setup();
render(<UseExistingIfFoundInfoIcon />); render(<UseExistingIfFoundInfoIcon />);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
fireEvent.click(screen.getByTitle('What does this mean?').firstChild as Node); await user.click(screen.getByTitle('What does this mean?').firstElementChild as Element);
expect(await screen.findByRole('dialog')).toBeInTheDocument(); expect(await screen.findByRole('dialog')).toBeInTheDocument();
}); });
}); });

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Checkbox from '../../src/utils/Checkbox'; import Checkbox from '../../src/utils/Checkbox';
describe('<Checkbox />', () => { describe('<Checkbox />', () => {
@ -22,12 +23,13 @@ describe('<Checkbox />', () => {
expect(screen.getByText(children)).toHaveAttribute('class', 'form-check-label'); expect(screen.getByText(children)).toHaveAttribute('class', 'form-check-label');
}); });
it.each([[true], [false]])('changes checked status on input change', (checked) => { it.each([[true], [false]])('changes checked status on input change', async (checked) => {
const user = userEvent.setup();
const onChange = jest.fn(); const onChange = jest.fn();
render(<Checkbox onChange={onChange} checked={checked}>Foo</Checkbox>); render(<Checkbox onChange={onChange} checked={checked}>Foo</Checkbox>);
expect(onChange).not.toHaveBeenCalled(); expect(onChange).not.toHaveBeenCalled();
fireEvent.click(screen.getByLabelText('Foo')); await user.click(screen.getByLabelText('Foo'));
expect(onChange).toHaveBeenCalledWith(!checked, expect.anything()); expect(onChange).toHaveBeenCalledWith(!checked, expect.anything());
}); });

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { formatISO } from 'date-fns'; import { formatISO } from 'date-fns';
@ -21,8 +22,9 @@ describe('<DomainVisits />', () => {
const cancelGetDomainVisits = jest.fn(); const cancelGetDomainVisits = jest.fn();
const domainVisits = Mock.of<DomainVisits>({ visits: [Mock.of<Visit>({ date: formatISO(new Date()) })] }); const domainVisits = Mock.of<DomainVisits>({ visits: [Mock.of<Visit>({ date: formatISO(new Date()) })] });
const DomainVisits = createDomainVisits(Mock.of<ReportExporter>({ exportVisits })); const DomainVisits = createDomainVisits(Mock.of<ReportExporter>({ exportVisits }));
const setUp = () => ({
beforeEach(() => render( user: userEvent.setup(),
...render(
<MemoryRouter> <MemoryRouter>
<DomainVisits <DomainVisits
{...Mock.of<MercureBoundProps>({ mercureInfo: {} })} {...Mock.of<MercureBoundProps>({ mercureInfo: {} })}
@ -33,20 +35,23 @@ describe('<DomainVisits />', () => {
selectedServer={Mock.all<SelectedServer>()} selectedServer={Mock.all<SelectedServer>()}
/> />
</MemoryRouter>, </MemoryRouter>,
)); ),
});
it('wraps visits stats and header', () => { it('wraps visits stats and header', () => {
setUp();
expect(screen.getByRole('heading', { name: '"foo.com" visits' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: '"foo.com" visits' })).toBeInTheDocument();
expect(getDomainVisits).toHaveBeenCalledWith('DEFAULT', expect.anything(), expect.anything()); expect(getDomainVisits).toHaveBeenCalledWith('DEFAULT', expect.anything(), expect.anything());
}); });
it('exports visits when clicking the button', () => { it('exports visits when clicking the button', async () => {
const { user } = setUp();
const btn = screen.getByRole('button', { name: 'Export (1)' }); const btn = screen.getByRole('button', { name: 'Export (1)' });
expect(exportVisits).not.toHaveBeenCalled(); expect(exportVisits).not.toHaveBeenCalled();
expect(btn).toBeInTheDocument(); expect(btn).toBeInTheDocument();
fireEvent.click(btn); await user.click(btn);
expect(exportVisits).toHaveBeenCalledWith('domain_foo.com_visits.csv', expect.anything()); expect(exportVisits).toHaveBeenCalledWith('domain_foo.com_visits.csv', expect.anything());
}); });
}); });

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { formatISO } from 'date-fns'; import { formatISO } from 'date-fns';
@ -15,8 +16,9 @@ describe('<NonOrphanVisits />', () => {
const cancelGetNonOrphanVisits = jest.fn(); const cancelGetNonOrphanVisits = jest.fn();
const nonOrphanVisits = Mock.of<VisitsInfo>({ visits: [Mock.of<Visit>({ date: formatISO(new Date()) })] }); const nonOrphanVisits = Mock.of<VisitsInfo>({ visits: [Mock.of<Visit>({ date: formatISO(new Date()) })] });
const NonOrphanVisits = createNonOrphanVisits(Mock.of<ReportExporter>({ exportVisits })); const NonOrphanVisits = createNonOrphanVisits(Mock.of<ReportExporter>({ exportVisits }));
const setUp = () => ({
beforeEach(() => render( user: userEvent.setup(),
...render(
<MemoryRouter> <MemoryRouter>
<NonOrphanVisits <NonOrphanVisits
{...Mock.of<MercureBoundProps>({ mercureInfo: {} })} {...Mock.of<MercureBoundProps>({ mercureInfo: {} })}
@ -27,20 +29,23 @@ describe('<NonOrphanVisits />', () => {
selectedServer={Mock.all<SelectedServer>()} selectedServer={Mock.all<SelectedServer>()}
/> />
</MemoryRouter>, </MemoryRouter>,
)); ),
});
it('wraps visits stats and header', () => { it('wraps visits stats and header', () => {
setUp();
expect(screen.getByRole('heading', { name: 'Non-orphan visits' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'Non-orphan visits' })).toBeInTheDocument();
expect(getNonOrphanVisits).toHaveBeenCalled(); expect(getNonOrphanVisits).toHaveBeenCalled();
}); });
it('exports visits when clicking the button', () => { it('exports visits when clicking the button', async () => {
const { user } = setUp();
const btn = screen.getByRole('button', { name: 'Export (1)' }); const btn = screen.getByRole('button', { name: 'Export (1)' });
expect(exportVisits).not.toHaveBeenCalled(); expect(exportVisits).not.toHaveBeenCalled();
expect(btn).toBeInTheDocument(); expect(btn).toBeInTheDocument();
fireEvent.click(btn); await user.click(btn);
expect(exportVisits).toHaveBeenCalledWith('non_orphan_visits.csv', expect.anything()); expect(exportVisits).toHaveBeenCalledWith('non_orphan_visits.csv', expect.anything());
}); });
}); });