Update tests to use vi instead of jest

This commit is contained in:
Alejandro Celaya
2023-05-27 11:57:26 +02:00
parent e2cbb2713a
commit 07fcb4e016
117 changed files with 3699 additions and 325 deletions

View File

@@ -5,17 +5,20 @@ import { CreateServer as createCreateServer } from '../../src/servers/CreateServ
import type { ServerWithId } from '../../src/servers/data';
import { renderWithEvents } from '../__helpers__/setUpTest';
jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: jest.fn() }));
vi.mock('react-router-dom', async () => ({
...(await vi.importActual<any>('react-router-dom')),
useNavigate: vi.fn(),
}));
describe('<CreateServer />', () => {
const createServersMock = jest.fn();
const navigate = jest.fn();
const createServersMock = vi.fn();
const navigate = vi.fn();
const servers = { foo: fromPartial<ServerWithId>({ url: 'https://existing_url.com', apiKey: 'existing_api_key' }) };
const setUp = (serversImported = false, importFailed = false) => {
(useNavigate as any).mockReturnValue(navigate);
let callCount = 0;
const useTimeoutToggle = jest.fn().mockImplementation(() => {
const useTimeoutToggle = vi.fn().mockImplementation(() => {
const result = [callCount % 2 === 0 ? serversImported : importFailed, () => null];
callCount += 1;
return result;
@@ -25,7 +28,7 @@ describe('<CreateServer />', () => {
return renderWithEvents(<CreateServer createServers={createServersMock} servers={servers} />);
};
beforeEach(jest.clearAllMocks);
beforeEach(vi.clearAllMocks);
it('shows success message when imported is true', () => {
setUp(true);

View File

@@ -5,11 +5,14 @@ import { DeleteServerModal } from '../../src/servers/DeleteServerModal';
import { renderWithEvents } from '../__helpers__/setUpTest';
import { TestModalWrapper } from '../__helpers__/TestModalWrapper';
jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: jest.fn() }));
vi.mock('react-router-dom', async () => ({
...(await vi.importActual<any>('react-router-dom')),
useNavigate: vi.fn(),
}));
describe('<DeleteServerModal />', () => {
const deleteServerMock = jest.fn();
const navigate = jest.fn();
const deleteServerMock = vi.fn();
const navigate = vi.fn();
const serverName = 'the_server_name';
const setUp = () => {
(useNavigate as any).mockReturnValue(navigate);
@@ -27,7 +30,7 @@ describe('<DeleteServerModal />', () => {
);
};
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
it('renders a modal window', () => {
setUp();

View File

@@ -5,12 +5,15 @@ import type { ReachableServer, SelectedServer } from '../../src/servers/data';
import { EditServer as editServerConstruct } from '../../src/servers/EditServer';
import { renderWithEvents } from '../__helpers__/setUpTest';
jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: jest.fn() }));
vi.mock('react-router-dom', async () => ({
...(await vi.importActual<any>('react-router-dom')),
useNavigate: vi.fn(),
}));
describe('<EditServer />', () => {
const ServerError = jest.fn();
const editServerMock = jest.fn();
const navigate = jest.fn();
const ServerError = vi.fn();
const editServerMock = vi.fn();
const navigate = vi.fn();
const defaultSelectedServer = fromPartial<ReachableServer>({
id: 'abc123',
name: 'the_name',
@@ -20,7 +23,7 @@ describe('<EditServer />', () => {
const EditServer = editServerConstruct(ServerError);
const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => renderWithEvents(
<MemoryRouter>
<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={jest.fn()} />
<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={vi.fn()} />
</MemoryRouter>,
);
@@ -28,7 +31,7 @@ describe('<EditServer />', () => {
(useNavigate as any).mockReturnValue(navigate);
});
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
it('renders nothing if selected server is not reachable', () => {
setUp(fromPartial<SelectedServer>({}));

View File

@@ -7,9 +7,9 @@ import type { ServersExporter } from '../../src/servers/services/ServersExporter
import { renderWithEvents } from '../__helpers__/setUpTest';
describe('<ManageServers />', () => {
const exportServers = jest.fn();
const exportServers = vi.fn();
const serversExporter = fromPartial<ServersExporter>({ exportServers });
const useTimeoutToggle = jest.fn().mockReturnValue([false, jest.fn()]);
const useTimeoutToggle = vi.fn().mockReturnValue([false, vi.fn()]);
const ManageServers = createManageServers(
serversExporter,
() => <span>ImportServersBtn</span>,
@@ -23,7 +23,7 @@ describe('<ManageServers />', () => {
<MemoryRouter><ManageServers servers={servers} /></MemoryRouter>,
);
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
it('shows search field which allows searching servers, affecting te amount of rendered rows', async () => {
const { user } = setUp({
@@ -85,7 +85,7 @@ describe('<ManageServers />', () => {
});
it.each([[true], [false]])('shows an error message if an error occurs while importing servers', (hasError) => {
useTimeoutToggle.mockReturnValue([hasError, jest.fn()]);
useTimeoutToggle.mockReturnValue([hasError, vi.fn()]);
setUp({ foo: createServerMock('foo') });

View File

@@ -9,7 +9,7 @@ describe('<ManageServersRowDropdown />', () => {
const ManageServersRowDropdown = createManageServersRowDropdown(
({ isOpen }) => <span>DeleteServerModal {isOpen ? '[OPEN]' : '[CLOSED]'}</span>,
);
const setAutoConnect = jest.fn();
const setAutoConnect = vi.fn();
const setUp = (autoConnect = false) => {
const server = fromPartial<ServerWithId>({ id: 'abc123', autoConnect });
return renderWithEvents(
@@ -19,7 +19,7 @@ describe('<ManageServersRowDropdown />', () => {
);
};
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
it('renders expected amount of dropdown items', async () => {
const { user } = setUp();

View File

@@ -9,9 +9,9 @@ import { renderWithEvents } from '../__helpers__/setUpTest';
describe('<Overview />', () => {
const ShortUrlsTable = () => <>ShortUrlsTable</>;
const CreateShortUrl = () => <>CreateShortUrl</>;
const listShortUrls = jest.fn();
const listTags = jest.fn();
const loadVisitsOverview = jest.fn();
const listShortUrls = vi.fn();
const listTags = vi.fn();
const loadVisitsOverview = vi.fn();
const Overview = overviewCreator(ShortUrlsTable, CreateShortUrl);
const shortUrls = {
pagination: { totalItems: 83710 },
@@ -31,8 +31,8 @@ describe('<Overview />', () => {
orphanVisits: { total: 28, bots: 15, nonBots: 13 },
})}
selectedServer={fromPartial({ id: serverId })}
createNewVisits={jest.fn()}
loadMercureInfo={jest.fn()}
createNewVisits={vi.fn()}
loadMercureInfo={vi.fn()}
mercureInfo={fromPartial<MercureInfo>({})}
settings={fromPartial({ visits: { excludeBots } })}
/>

View File

@@ -1,4 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<DeleteServerButton /> > renders expected content 1`] = `
<span>
<span
class="button"
>
Foo bar
</span>
</span>
`;
exports[`<DeleteServerButton /> > renders expected content 2`] = `
<span>
<span
class="button"
>
baz
</span>
</span>
`;
exports[`<DeleteServerButton /> > renders expected content 3`] = `
<span>
<span
class="button"
>
something
</span>
</span>
`;
exports[`<DeleteServerButton /> > renders expected content 4`] = `
<span>
<svg
aria-hidden="true"
class="svg-inline--fa fa-circle-minus fa-fw "
data-icon="circle-minus"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM184 232H328c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z"
fill="currentColor"
/>
</svg>
<span
class="button"
>
Remove this server
</span>
</span>
`;
exports[`<DeleteServerButton /> renders expected content 1`] = `
<span>

View File

@@ -1,4 +1,101 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<ManageServersRow /> > renders auto-connect icon only if server is autoConnect 1`] = `
<div>
<table>
<tbody>
<tr
class="responsive-table__row"
>
<td
class="responsive-table__cell"
data-th="Auto-connect"
>
<svg
aria-hidden="true"
class="svg-inline--fa fa-check text-primary"
data-icon="check"
data-prefix="fas"
focusable="false"
id="autoConnectIcon"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"
fill="currentColor"
/>
</svg>
</td>
<th
class="responsive-table__cell"
data-th="Name"
>
<a
href="/server/abc"
>
My server
</a>
</th>
<td
class="responsive-table__cell"
data-th="Base URL"
>
https://example.com
</td>
<td
class="responsive-table__cell text-end"
>
<span>
ManageServersRowDropdown
</span>
</td>
</tr>
</tbody>
</table>
</div>
`;
exports[`<ManageServersRow /> > renders auto-connect icon only if server is autoConnect 2`] = `
<div>
<table>
<tbody>
<tr
class="responsive-table__row"
>
<td
class="responsive-table__cell"
data-th="Auto-connect"
/>
<th
class="responsive-table__cell"
data-th="Name"
>
<a
href="/server/abc"
>
My server
</a>
</th>
<td
class="responsive-table__cell"
data-th="Base URL"
>
https://example.com
</td>
<td
class="responsive-table__cell text-end"
>
<span>
ManageServersRowDropdown
</span>
</td>
</tr>
</tbody>
</table>
</div>
`;
exports[`<ManageServersRow /> renders auto-connect icon only if server is autoConnect 1`] = `
<div>

View File

@@ -5,14 +5,14 @@ import { DuplicatedServersModal } from '../../../src/servers/helpers/DuplicatedS
import { renderWithEvents } from '../../__helpers__/setUpTest';
describe('<DuplicatedServersModal />', () => {
const onDiscard = jest.fn();
const onSave = jest.fn();
const onDiscard = vi.fn();
const onSave = vi.fn();
const setUp = (duplicatedServers: ServerData[] = []) => renderWithEvents(
<DuplicatedServersModal isOpen duplicatedServers={duplicatedServers} onDiscard={onDiscard} onSave={onSave} />,
);
const mockServer = (data: Partial<ServerData> = {}) => fromPartial<ServerData>(data);
beforeEach(jest.clearAllMocks);
beforeEach(vi.clearAllMocks);
it.each([
[[], 0],

View File

@@ -10,9 +10,9 @@ import type { ServersImporter } from '../../../src/servers/services/ServersImpor
import { renderWithEvents } from '../../__helpers__/setUpTest';
describe('<ImportServersBtn />', () => {
const onImportMock = jest.fn();
const createServersMock = jest.fn();
const importServersFromFile = jest.fn().mockResolvedValue([]);
const onImportMock = vi.fn();
const createServersMock = vi.fn();
const importServersFromFile = vi.fn().mockResolvedValue([]);
const serversImporterMock = fromPartial<ServersImporter>({ importServersFromFile });
const ImportServersBtn = createImportServersBtn(serversImporterMock);
const setUp = (props: Partial<ImportServersBtnProps> = {}, servers: ServersMap = {}) => renderWithEvents(
@@ -24,7 +24,7 @@ describe('<ImportServersBtn />', () => {
/>,
);
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
it('shows tooltip on button hover', async () => {
const { user } = setUp();

View File

@@ -2,10 +2,10 @@ import { fireEvent, render, screen } from '@testing-library/react';
import { ServerForm } from '../../../src/servers/helpers/ServerForm';
describe('<ServerForm />', () => {
const onSubmit = jest.fn();
const onSubmit = vi.fn();
const setUp = () => render(<ServerForm onSubmit={onSubmit}>Something</ServerForm>);
afterEach(jest.resetAllMocks);
afterEach(vi.resetAllMocks);
it('renders components', () => {
setUp();
@@ -18,7 +18,7 @@ describe('<ServerForm />', () => {
setUp();
expect(onSubmit).not.toHaveBeenCalled();
fireEvent.submit(screen.getByRole('form'), { preventDefault: jest.fn() });
fireEvent.submit(screen.getByRole('form'), { preventDefault: vi.fn() });
expect(onSubmit).toHaveBeenCalled();
});
});

View File

@@ -3,11 +3,11 @@ import type { HttpClient } from '../../../src/common/services/HttpClient';
import { fetchServers } from '../../../src/servers/reducers/remoteServers';
describe('remoteServersReducer', () => {
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
describe('fetchServers', () => {
const dispatch = jest.fn();
const fetchJson = jest.fn();
const dispatch = vi.fn();
const fetchJson = vi.fn();
const httpClient = fromPartial<HttpClient>({ fetchJson });
it.each([
@@ -81,7 +81,7 @@ describe('remoteServersReducer', () => {
fetchJson.mockResolvedValue(mockedValue);
const doFetchServers = fetchServers(httpClient);
await doFetchServers()(dispatch, jest.fn(), {});
await doFetchServers()(dispatch, vi.fn(), {});
expect(dispatch).toHaveBeenCalledTimes(3);
expect(dispatch).toHaveBeenNthCalledWith(2, expect.objectContaining({ payload: expectedNewServers }));

View File

@@ -13,13 +13,13 @@ import {
} from '../../../src/servers/reducers/selectedServer';
describe('selectedServerReducer', () => {
const dispatch = jest.fn();
const health = jest.fn();
const buildApiClient = jest.fn().mockReturnValue(fromPartial<ShlinkApiClient>({ health }));
const dispatch = vi.fn();
const health = vi.fn();
const buildApiClient = vi.fn().mockReturnValue(fromPartial<ShlinkApiClient>({ health }));
const selectServer = selectServerCreator(buildApiClient);
const { reducer } = selectedServerReducerCreator(selectServer);
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
describe('reducer', () => {
it('returns default when action is RESET_SELECTED_SERVER', () =>
@@ -33,7 +33,7 @@ describe('selectedServerReducer', () => {
describe('selectServer', () => {
const version = '1.19.0';
const createGetStateMock = (id: string) => jest.fn().mockReturnValue({
const createGetStateMock = (id: string) => vi.fn().mockReturnValue({
servers: {
[id]: { id },
},
@@ -77,7 +77,7 @@ describe('selectedServerReducer', () => {
it('dispatches error when server is not found', async () => {
const id = uuid();
const getState = jest.fn(() => fromPartial<ShlinkState>({ servers: {} }));
const getState = vi.fn(() => fromPartial<ShlinkState>({ servers: {} }));
const expectedSelectedServer: NotFoundServer = { serverNotFound: true };
await selectServer(id)(dispatch, getState, {});
@@ -89,8 +89,8 @@ describe('selectedServerReducer', () => {
});
describe('selectServerListener', () => {
const getState = jest.fn(() => ({}));
const loadMercureInfo = jest.fn();
const getState = vi.fn(() => ({}));
const loadMercureInfo = vi.fn();
const { middleware } = selectServerListener(selectServer, loadMercureInfo);
it.each([
@@ -98,7 +98,7 @@ describe('selectedServerReducer', () => {
[fromPartial<NotFoundServer>({ serverNotFound: true }), 0],
[fromPartial<NonReachableServer>({ serverNotReachable: true }), 0],
])('dispatches loadMercureInfo when provided server is reachable', (payload, expectedCalls) => {
middleware({ dispatch, getState })(jest.fn())({
middleware({ dispatch, getState })(vi.fn())({
payload,
type: selectServer.fulfilled.toString(),
});
@@ -108,7 +108,7 @@ describe('selectedServerReducer', () => {
});
it('does not dispatch loadMercureInfo when action is not of the proper type', () => {
middleware({ dispatch, getState })(jest.fn())({
middleware({ dispatch, getState })(vi.fn())({
payload: fromPartial<ReachableServer>({ version: '1.2.3' }),
type: 'something_else',
});

View File

@@ -15,7 +15,7 @@ describe('serversReducer', () => {
def456: fromPartial({ id: 'def456' }),
};
afterEach(jest.clearAllMocks);
afterEach(vi.clearAllMocks);
describe('reducer', () => {
it('returns edited server when action is EDIT_SERVER', () =>

View File

@@ -5,7 +5,7 @@ import { appendChild, removeChild, windowMock } from '../../__mocks__/Window.moc
describe('ServersExporter', () => {
const storageMock = fromPartial<LocalStorage>({
get: jest.fn(() => ({
get: vi.fn(() => ({
abc123: {
id: 'abc123',
name: 'foo',
@@ -18,16 +18,16 @@ describe('ServersExporter', () => {
},
} as any)),
});
const erroneousToCsv = jest.fn(() => {
const erroneousToCsv = vi.fn(() => {
throw new Error('');
});
const createCsvjsonMock = (throwError = false) => (throwError ? erroneousToCsv : jest.fn(() => ''));
const createCsvjsonMock = (throwError = false) => (throwError ? erroneousToCsv : vi.fn(() => ''));
beforeEach(jest.clearAllMocks);
beforeEach(vi.clearAllMocks);
describe('exportServers', () => {
let originalConsole: Console;
const error = jest.fn();
const error = vi.fn();
beforeEach(() => {
originalConsole = global.console;

View File

@@ -4,8 +4,8 @@ import { ServersImporter } from '../../../src/servers/services/ServersImporter';
describe('ServersImporter', () => {
const servers: RegularServer[] = [fromPartial<RegularServer>({}), fromPartial<RegularServer>({})];
const csvjsonMock = jest.fn().mockResolvedValue(servers);
const readAsText = jest.fn();
const csvjsonMock = vi.fn().mockResolvedValue(servers);
const readAsText = vi.fn();
const fileReaderMock = fromPartial<FileReader>({
readAsText,
addEventListener: ((_eventName: string, listener: (e: ProgressEvent<FileReader>) => void) => listener(
@@ -14,7 +14,7 @@ describe('ServersImporter', () => {
});
const importer = new ServersImporter(csvjsonMock, () => fileReaderMock);
beforeEach(jest.clearAllMocks);
beforeEach(vi.clearAllMocks);
describe('importServersFromFile', () => {
it('rejects with error if no file was provided', async () => {