mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-10 17:43:51 +00:00
Move shlink-web-component tests to their own folder
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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>
|
||||
`;
|
||||
@@ -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>
|
||||
`;
|
||||
@@ -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>
|
||||
`;
|
||||
Reference in New Issue
Block a user