Move shlink-web-component tests to their own folder

This commit is contained in:
Alejandro Celaya
2023-08-02 09:01:44 +02:00
parent c48facc863
commit c794ff8b58
124 changed files with 455 additions and 371 deletions

View File

@@ -0,0 +1,24 @@
import { CopyToClipboardIcon } from '../../../src/utils/components/CopyToClipboardIcon';
import { renderWithEvents } from '../../__helpers__/setUpTest';
describe('<CopyToClipboardIcon />', () => {
const onCopy = vi.fn();
const setUp = (text = 'foo') => renderWithEvents(<CopyToClipboardIcon text={text} onCopy={onCopy} />);
it('wraps expected components', () => {
const { container } = setUp();
expect(container).toMatchSnapshot();
});
it.each([
['text'],
['bar'],
['baz'],
])('copies content to clipboard when clicked', async (text) => {
const { user, container } = setUp(text);
expect(onCopy).not.toHaveBeenCalled();
container.firstElementChild && await user.click(container.firstElementChild);
expect(onCopy).toHaveBeenCalledWith(text, false);
});
});

View File

@@ -0,0 +1,36 @@
import { render, screen } from '@testing-library/react';
import { ExportBtn } from '../../../src/utils/components/ExportBtn';
describe('<ExportBtn />', () => {
const setUp = (amount?: number, loading = false) => render(<ExportBtn amount={amount} loading={loading} />);
it.each([
[true, 'Exporting...'],
[false, 'Export (0)'],
])('renders loading state when expected', async (loading, text) => {
setUp(undefined, loading);
const btn = await screen.findByRole('button');
expect(btn).toHaveTextContent(text);
if (loading) {
expect(btn).toHaveAttribute('disabled');
} else {
expect(btn).not.toHaveAttribute('disabled');
}
});
it.each([
[undefined, '0'],
[10, '10'],
[10_000, '10,000'],
[10_000_000, '10,000,000'],
])('renders expected amount', async (amount, expectedRenderedAmount) => {
setUp(amount);
expect(await screen.findByRole('button')).toHaveTextContent(`Export (${expectedRenderedAmount})`);
});
it('renders expected icon', () => {
setUp();
expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,24 @@
import type { IconProp } from '@fortawesome/fontawesome-svg-core';
import { faAppleAlt, faCalendar, faTable } from '@fortawesome/free-solid-svg-icons';
import { screen } from '@testing-library/react';
import { IconInput } from '../../../src/utils/components/IconInput';
import { renderWithEvents } from '../../__helpers__/setUpTest';
describe('<IconInput />', () => {
const setUp = (icon: IconProp, placeholder?: string) => renderWithEvents(
<IconInput icon={icon} placeholder={placeholder} />,
);
it.each([faCalendar, faAppleAlt, faTable])('displays provided icon', (icon) => {
const { container } = setUp(icon);
expect(container).toMatchSnapshot();
});
it('focuses input on icon click', async () => {
const { user } = setUp(faCalendar, 'foo');
expect(screen.getByPlaceholderText('foo')).not.toHaveFocus();
await user.click(screen.getByRole('img', { hidden: true }));
expect(screen.getByPlaceholderText('foo')).toHaveFocus();
});
});

View File

@@ -0,0 +1,51 @@
import type { Placement } from '@popperjs/core';
import { screen, waitFor } from '@testing-library/react';
import type { InfoTooltipProps } from '../../../src/utils/components/InfoTooltip';
import { InfoTooltip } from '../../../src/utils/components/InfoTooltip';
import { renderWithEvents } from '../../__helpers__/setUpTest';
describe('<InfoTooltip />', () => {
const setUp = (props: Partial<InfoTooltipProps> = {}) => renderWithEvents(
<InfoTooltip placement="right" {...props} />,
);
it.each([
[undefined],
['foo'],
['bar'],
])('renders expected className on span', (className) => {
const { container } = setUp({ className });
if (className) {
expect(container.firstChild).toHaveClass(className);
} else {
expect(container.firstChild).toHaveAttribute('class', '');
}
});
it.each([
[<span key={1}>foo</span>, 'foo'],
['Foo', 'Foo'],
['Hello', 'Hello'],
[['One', 'Two', <span key={3} />], 'OneTwo'],
])('passes children down to the nested tooltip component', async (children, expectedContent) => {
const { container, user } = setUp({ children });
container.firstElementChild && await user.hover(container.firstElementChild);
await waitFor(() => expect(screen.getByRole('tooltip')).toBeInTheDocument());
expect(screen.getByRole('tooltip')).toHaveTextContent(expectedContent);
});
it.each([
['right' as Placement],
['left' as Placement],
['top' as Placement],
['bottom' as Placement],
])('places tooltip where requested', async (placement) => {
const { container, user } = setUp({ placement });
container.firstElementChild && await user.hover(container.firstElementChild);
await waitFor(() => expect(screen.getByRole('tooltip')).toBeInTheDocument());
expect(screen.getByRole('tooltip').parentNode).toHaveAttribute('data-popper-placement', placement);
});
});

View File

@@ -0,0 +1,33 @@
import { screen } from '@testing-library/react';
import { PaginationDropdown } from '../../../src/utils/components/PaginationDropdown';
import { renderWithEvents } from '../../__helpers__/setUpTest';
describe('<PaginationDropdown />', () => {
const setValue = vi.fn();
const setUp = async () => {
const result = renderWithEvents(<PaginationDropdown ranges={[10, 50, 100, 200]} value={50} setValue={setValue} />);
const { user } = result;
await user.click(screen.getByRole('button'));
return result;
};
it('renders expected amount of items', async () => {
await setUp();
expect(screen.getAllByRole('menuitem')).toHaveLength(5);
});
it.each([
[0, 10],
[1, 50],
[2, 100],
[3, 200],
])('sets expected value when an item is clicked', async (index, expectedValue) => {
const { user } = await setUp();
expect(setValue).not.toHaveBeenCalled();
await user.click(screen.getAllByRole('menuitem')[index]);
expect(setValue).toHaveBeenCalledWith(expectedValue);
});
});

View File

@@ -0,0 +1,21 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<CopyToClipboardIcon /> > wraps expected components 1`] = `
<div>
<svg
aria-hidden="true"
class="svg-inline--fa fa-clone ms-2 copy-to-clipboard-icon"
data-icon="clone"
data-prefix="far"
focusable="false"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M64 464H288c8.8 0 16-7.2 16-16V384h48v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h64v48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16zM224 304H448c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H224c-8.8 0-16 7.2-16 16V288c0 8.8 7.2 16 16 16zm-64-16V64c0-35.3 28.7-64 64-64H448c35.3 0 64 28.7 64 64V288c0 35.3-28.7 64-64 64H224c-35.3 0-64-28.7-64-64z"
fill="currentColor"
/>
</svg>
</div>
`;

View File

@@ -0,0 +1,19 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<ExportBtn /> > renders expected icon 1`] = `
<svg
aria-hidden="true"
class="svg-inline--fa fa-file-csv "
data-icon="file-csv"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM80 224H96c22.1 0 40 17.9 40 40v8c0 8.8-7.2 16-16 16s-16-7.2-16-16v-8c0-4.4-3.6-8-8-8H80c-4.4 0-8 3.6-8 8v80c0 4.4 3.6 8 8 8H96c4.4 0 8-3.6 8-8v-8c0-8.8 7.2-16 16-16s16 7.2 16 16v8c0 22.1-17.9 40-40 40H80c-22.1 0-40-17.9-40-40V264c0-22.1 17.9-40 40-40zm72 46.4c0-25.6 20.8-46.4 46.4-46.4H216c8.8 0 16 7.2 16 16s-7.2 16-16 16H198.4c-7.9 0-14.4 6.4-14.4 14.4c0 5.2 2.8 9.9 7.2 12.5l25.4 14.5c14.4 8.3 23.4 23.6 23.4 40.3c0 25.6-20.8 46.4-46.4 46.4H168c-8.8 0-16-7.2-16-16s7.2-16 16-16h25.6c7.9 0 14.4-6.4 14.4-14.4c0-5.2-2.8-9.9-7.2-12.5l-25.4-14.5C160.9 302.4 152 287 152 270.4zM280 240v31.6c0 23 5.5 45.6 16 66c10.5-20.3 16-42.9 16-66V240c0-8.8 7.2-16 16-16s16 7.2 16 16v31.6c0 34.7-10.3 68.7-29.6 97.6l-5.1 7.7c-3 4.5-8 7.1-13.3 7.1s-10.3-2.7-13.3-7.1l-5.1-7.7c-19.3-28.9-29.6-62.9-29.6-97.6V240c0-8.8 7.2-16 16-16s16 7.2 16 16z"
fill="currentColor"
/>
</svg>
`;

View File

@@ -0,0 +1,85 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<IconInput /> > displays provided icon 1`] = `
<div>
<div
class="icon-input-container"
>
<input
class="icon-input-container__input form-control"
type="text"
/>
<svg
aria-hidden="true"
class="svg-inline--fa fa-calendar fa-fw icon-input-container__icon"
data-icon="calendar"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M96 32V64H48C21.5 64 0 85.5 0 112v48H448V112c0-26.5-21.5-48-48-48H352V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V64H160V32c0-17.7-14.3-32-32-32S96 14.3 96 32zM448 192H0V464c0 26.5 21.5 48 48 48H400c26.5 0 48-21.5 48-48V192z"
fill="currentColor"
/>
</svg>
</div>
</div>
`;
exports[`<IconInput /> > displays provided icon 2`] = `
<div>
<div
class="icon-input-container"
>
<input
class="icon-input-container__input form-control"
type="text"
/>
<svg
aria-hidden="true"
class="svg-inline--fa fa-apple-whole fa-fw icon-input-container__icon"
data-icon="apple-whole"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 448 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M224 112c-8.8 0-16-7.2-16-16V80c0-44.2 35.8-80 80-80h16c8.8 0 16 7.2 16 16V32c0 44.2-35.8 80-80 80H224zM0 288c0-76.3 35.7-160 112-160c27.3 0 59.7 10.3 82.7 19.3c18.8 7.3 39.9 7.3 58.7 0c22.9-8.9 55.4-19.3 82.7-19.3c76.3 0 112 83.7 112 160c0 128-80 224-160 224c-16.5 0-38.1-6.6-51.5-11.3c-8.1-2.8-16.9-2.8-25 0c-13.4 4.7-35 11.3-51.5 11.3C80 512 0 416 0 288z"
fill="currentColor"
/>
</svg>
</div>
</div>
`;
exports[`<IconInput /> > displays provided icon 3`] = `
<div>
<div
class="icon-input-container"
>
<input
class="icon-input-container__input form-control"
type="text"
/>
<svg
aria-hidden="true"
class="svg-inline--fa fa-table fa-fw icon-input-container__icon"
data-icon="table"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M64 256V160H224v96H64zm0 64H224v96H64V320zm224 96V320H448v96H288zM448 256H288V160H448v96zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z"
fill="currentColor"
/>
</svg>
</div>
</div>
`;