Updated to airbnb coding styles

This commit is contained in:
Alejandro Celaya
2022-03-26 12:17:42 +01:00
parent 4e9b19afd1
commit a2df486280
239 changed files with 2210 additions and 3549 deletions

View File

@@ -4,19 +4,19 @@ import { ShlinkApiError, ShlinkApiErrorProps } from '../../src/api/ShlinkApiErro
import { InvalidArgumentError, ProblemDetailsError } from '../../src/api/types';
describe('<ShlinkApiError />', () => {
let wrapper: ShallowWrapper;
let commonWrapper: ShallowWrapper;
const createWrapper = (props: ShlinkApiErrorProps) => {
wrapper = shallow(<ShlinkApiError {...props} />);
commonWrapper = shallow(<ShlinkApiError {...props} />);
return wrapper;
return commonWrapper;
};
afterEach(() => wrapper?.unmount());
afterEach(() => commonWrapper?.unmount());
it.each([
[ undefined, 'the fallback', 'the fallback' ],
[ Mock.all<ProblemDetailsError>(), 'the fallback', 'the fallback' ],
[ Mock.of<ProblemDetailsError>({ detail: 'the detail' }), 'the fallback', 'the detail' ],
[undefined, 'the fallback', 'the fallback'],
[Mock.all<ProblemDetailsError>(), 'the fallback', 'the fallback'],
[Mock.of<ProblemDetailsError>({ detail: 'the detail' }), 'the fallback', 'the detail'],
])('renders proper message', (errorData, fallbackMessage, expectedMessage) => {
const wrapper = createWrapper({ errorData, fallbackMessage });
@@ -24,9 +24,9 @@ describe('<ShlinkApiError />', () => {
});
it.each([
[ undefined, 0 ],
[ Mock.all<ProblemDetailsError>(), 0 ],
[ Mock.of<InvalidArgumentError>({ type: 'INVALID_ARGUMENT', invalidElements: [] }), 1 ],
[undefined, 0],
[Mock.all<ProblemDetailsError>(), 0],
[Mock.of<InvalidArgumentError>({ type: 'INVALID_ARGUMENT', invalidElements: [] }), 1],
])('renders list of invalid elements when provided error is an InvalidError', (errorData, expectedElementsCount) => {
const wrapper = createWrapper({ errorData });
const p = wrapper.find('p');

View File

@@ -11,13 +11,13 @@ describe('ShlinkApiClient', () => {
const createAxiosMock = (data: AxiosRequestConfig = {}) => jest.fn(createAxios(data)) as unknown as AxiosInstance;
const createApiClient = (data: AxiosRequestConfig) => new ShlinkApiClient(createAxios(data), '', '');
const shortCodesWithDomainCombinations: [ string, OptionalString ][] = [
[ 'abc123', null ],
[ 'abc123', undefined ],
[ 'abc123', 'example.com' ],
['abc123', null],
['abc123', undefined],
['abc123', 'example.com'],
];
describe('listShortUrls', () => {
const expectedList = [ 'foo', 'bar' ];
const expectedList = ['foo', 'bar'];
it('properly returns short URLs list', async () => {
const { listShortUrls } = createApiClient({
@@ -32,9 +32,9 @@ describe('ShlinkApiClient', () => {
});
it.each([
[ { field: 'visits', dir: 'DESC' } as ShortUrlsOrder, 'visits-DESC' ],
[ { field: 'longUrl', dir: 'ASC' } as ShortUrlsOrder, 'longUrl-ASC' ],
[ { field: 'longUrl', dir: undefined } as ShortUrlsOrder, undefined ],
[{ field: 'visits', dir: 'DESC' } as ShortUrlsOrder, 'visits-DESC'],
[{ field: 'longUrl', dir: 'ASC' } as ShortUrlsOrder, 'longUrl-ASC'],
[{ field: 'longUrl', dir: undefined } as ShortUrlsOrder, undefined],
])('parses orderBy in params', async (orderBy, expectedOrderBy) => {
const axiosSpy = createAxiosMock({
data: expectedList,
@@ -73,7 +73,7 @@ describe('ShlinkApiClient', () => {
describe('getShortUrlVisits', () => {
it('properly returns short URL visits', async () => {
const expectedVisits = [ 'foo', 'bar' ];
const expectedVisits = ['foo', 'bar'];
const axiosSpy = createAxiosMock({
data: {
visits: {
@@ -95,7 +95,7 @@ describe('ShlinkApiClient', () => {
describe('getTagVisits', () => {
it('properly returns tag visits', async () => {
const expectedVisits = [ 'foo', 'bar' ];
const expectedVisits = ['foo', 'bar'];
const axiosSpy = createAxiosMock({
data: {
visits: {
@@ -136,7 +136,7 @@ describe('ShlinkApiClient', () => {
describe('updateShortUrlTags', () => {
it.each(shortCodesWithDomainCombinations)('properly updates short URL tags', async (shortCode, domain) => {
const expectedTags = [ 'foo', 'bar' ];
const expectedTags = ['foo', 'bar'];
const axiosSpy = createAxiosMock({
data: { tags: expectedTags },
});
@@ -176,7 +176,7 @@ describe('ShlinkApiClient', () => {
describe('listTags', () => {
it('properly returns list of tags', async () => {
const expectedTags = [ 'foo', 'bar' ];
const expectedTags = ['foo', 'bar'];
const axiosSpy = createAxiosMock({
data: {
tags: { data: expectedTags },
@@ -193,7 +193,7 @@ describe('ShlinkApiClient', () => {
describe('deleteTags', () => {
it('properly deletes provided tags', async () => {
const tags = [ 'foo', 'bar' ];
const tags = ['foo', 'bar'];
const axiosSpy = createAxiosMock();
const { deleteTags } = new ShlinkApiClient(axiosSpy, '', '');
@@ -273,7 +273,7 @@ describe('ShlinkApiClient', () => {
describe('listDomains', () => {
it('returns domains', async () => {
const expectedData = { data: [ Mock.all<ShlinkDomain>(), Mock.all<ShlinkDomain>() ] };
const expectedData = { data: [Mock.all<ShlinkDomain>(), Mock.all<ShlinkDomain>()] };
const resp = { domains: expectedData };
const axiosSpy = createAxiosMock({ data: resp });
const { listDomains } = new ShlinkApiClient(axiosSpy, '', '');

View File

@@ -16,7 +16,7 @@ describe('ShlinkApiClientBuilder', () => {
it('creates new instances when provided params are different', async () => {
const builder = createBuilder();
const [ firstApiClient, secondApiClient, thirdApiClient ] = await Promise.all([
const [firstApiClient, secondApiClient, thirdApiClient] = await Promise.all([
builder(server({ url: 'foo', apiKey: 'bar' })),
builder(server({ url: 'bar', apiKey: 'bar' })),
builder(server({ url: 'bar', apiKey: 'foo' })),
@@ -30,7 +30,7 @@ describe('ShlinkApiClientBuilder', () => {
it('returns existing instances when provided params are the same', async () => {
const builder = createBuilder();
const selectedServer = server({ url: 'foo', apiKey: 'bar' });
const [ firstApiClient, secondApiClient, thirdApiClient ] = await Promise.all([
const [firstApiClient, secondApiClient, thirdApiClient] = await Promise.all([
builder(selectedServer),
builder(selectedServer),
builder(selectedServer),

View File

@@ -69,9 +69,9 @@ describe('<App />', () => {
});
it.each([
[ '/foo', 'shlink-wrapper' ],
[ '/bar', 'shlink-wrapper' ],
[ '/', 'shlink-wrapper d-flex d-md-block align-items-center' ],
['/foo', 'shlink-wrapper'],
['/bar', 'shlink-wrapper'],
['/', 'shlink-wrapper d-flex d-md-block align-items-center'],
])('renders expected classes on shlink-wrapper based on current pathname', (pathname, expectedClasses) => {
(useLocation as any).mockReturnValue({ pathname }); // eslint-disable-line @typescript-eslint/no-unsafe-call

View File

@@ -9,7 +9,7 @@ describe('<AppUpdateBanner />', () => {
let wrapper: ShallowWrapper;
beforeEach(() => {
wrapper = shallow(<AppUpdateBanner isOpen={true} toggle={toggle} forceUpdate={forceUpdate} />);
wrapper = shallow(<AppUpdateBanner isOpen toggle={toggle} forceUpdate={forceUpdate} />);
});
afterEach(jest.clearAllMocks);

View File

@@ -36,7 +36,7 @@ describe('<Home />', () => {
},
0,
],
[{}, 3 ],
[{}, 3],
])('shows link to create or set-up server only when no servers exist', (servers, expectedParagraphs) => {
const wrapped = createComponent({ servers });
const p = wrapped.find('p');

View File

@@ -32,11 +32,11 @@ describe('<MainHeader />', () => {
});
it.each([
[ '/foo', false ],
[ '/bar', false ],
[ '/settings', true ],
[ '/settings/foo', true ],
[ '/settings/bar', true ],
['/foo', false],
['/bar', false],
['/settings', true],
['/settings/foo', true],
['/settings/bar', true],
])('sets link to settings as active only when current path is settings', (currentPath, isActive) => {
const wrapper = createWrapper(currentPath);
const settingsLink = wrapper.find(NavLink);

View File

@@ -36,8 +36,8 @@ describe('<MenuLayout />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ null, NoMenuLayout ],
[ Mock.of<NotFoundServer>({ serverNotFound: true }), ServerError ],
[null, NoMenuLayout],
[Mock.of<NotFoundServer>({ serverNotFound: true }), ServerError],
])('returns error when server is not found', (selectedServer, ExpectedComp) => {
const wrapper = createWrapper(selectedServer);
const comp = wrapper.find(ExpectedComp);
@@ -53,12 +53,12 @@ describe('<MenuLayout />', () => {
});
it.each([
[ '2.5.0' as SemVer, 9 ],
[ '2.6.0' as SemVer, 10 ],
[ '2.7.0' as SemVer, 10 ],
[ '2.8.0' as SemVer, 11 ],
[ '2.10.0' as SemVer, 11 ],
[ '3.0.0' as SemVer, 12 ],
['2.5.0' as SemVer, 9],
['2.6.0' as SemVer, 10],
['2.7.0' as SemVer, 10],
['2.8.0' as SemVer, 11],
['2.10.0' as SemVer, 11],
['3.0.0' as SemVer, 12],
])('has expected amount of routes based on selected server\'s version', (version, expectedAmountOfRoutes) => {
const selectedServer = Mock.of<ReachableServer>({ version });
const wrapper = createWrapper(selectedServer).dive();

View File

@@ -14,11 +14,11 @@ describe('<ShlinkVersions />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ '1.2.3', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: 'foo' }), 'v1.2.3', 'foo' ],
[ 'foo', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: '1.2.3' }), 'latest', '1.2.3' ],
[ 'latest', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: 'latest' }), 'latest', 'latest' ],
[ '5.5.0', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: '0.2.8' }), 'v5.5.0', '0.2.8' ],
[ 'not-semver', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: 'some' }), 'latest', 'some' ],
['1.2.3', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: 'foo' }), 'v1.2.3', 'foo'],
['foo', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: '1.2.3' }), 'latest', '1.2.3'],
['latest', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: 'latest' }), 'latest', 'latest'],
['5.5.0', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: '0.2.8' }), 'v5.5.0', '0.2.8'],
['not-semver', Mock.of<ReachableServer>({ version: '1.0.0', printableVersion: 'some' }), 'latest', 'some'],
])(
'displays expected versions when selected server is reachable',
(clientVersion, selectedServer, expectedClientVersion, expectedServerVersion) => {
@@ -35,9 +35,9 @@ describe('<ShlinkVersions />', () => {
);
it.each([
[ '1.2.3', null ],
[ '1.2.3', Mock.of<NotFoundServer>({ serverNotFound: true }) ],
[ '1.2.3', Mock.of<NonReachableServer>({ serverNotReachable: true }) ],
['1.2.3', null],
['1.2.3', Mock.of<NotFoundServer>({ serverNotFound: true })],
['1.2.3', Mock.of<NonReachableServer>({ serverNotReachable: true })],
])('displays only client version when selected server is not reachable', (clientVersion, selectedServer) => {
const wrapper = createWrapper({ clientVersion, selectedServer });
const links = wrapper.find('VersionLink');

View File

@@ -16,8 +16,8 @@ describe('<ShlinkVersionsContainer />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[{ sidebarPresent: false }, 'text-center' ],
[{ sidebarPresent: true }, 'text-center shlink-versions-container--with-sidebar' ],
[{ sidebarPresent: false }, 'text-center'],
[{ sidebarPresent: true }, 'text-center shlink-versions-container--with-sidebar'],
])('renders proper col classes based on sidebar status', (sidebar, expectedClasses) => {
const wrapper = createWrapper(sidebar);

View File

@@ -14,7 +14,7 @@ describe('<SimplePaginator />', () => {
afterEach(() => wrapper?.unmount());
it.each([ -3, -2, 0, 1 ])('renders empty when the amount of pages is smaller than 2', (pagesCount) => {
it.each([-3, -2, 0, 1])('renders empty when the amount of pages is smaller than 2', (pagesCount) => {
expect(createWrapper(pagesCount).text()).toEqual('');
});

View File

@@ -13,9 +13,9 @@ describe('<ShlinkLogo />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined, MAIN_COLOR ],
[ 'red', 'red' ],
[ 'white', 'white' ],
[undefined, MAIN_COLOR],
['red', 'red'],
['white', 'white'],
])('renders expected color', (color, expectedColor) => {
const wrapper = createWrapper({ color });
@@ -23,9 +23,9 @@ describe('<ShlinkLogo />', () => {
});
it.each([
[ undefined, undefined ],
[ 'foo', 'foo' ],
[ 'bar', 'bar' ],
[undefined, undefined],
['foo', 'foo'],
['bar', 'bar'],
])('renders expected class', (className, expectedClassName) => {
const wrapper = createWrapper({ className });

View File

@@ -10,8 +10,8 @@ import reducer, {
describe('sidebarReducer', () => {
describe('reducer', () => {
it.each([
[ SIDEBAR_PRESENT, { sidebarPresent: true }],
[ SIDEBAR_NOT_PRESENT, { sidebarPresent: false }],
[SIDEBAR_PRESENT, { sidebarPresent: true }],
[SIDEBAR_NOT_PRESENT, { sidebarPresent: false }],
])('returns expected on %s', (type, expected) => {
expect(reducer(Mock.all<Sidebar>(), { type })).toEqual(expected);
});

View File

@@ -26,11 +26,11 @@ describe('<DomainRow />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ Mock.of<Domain>({ domain: '', isDefault: true }), undefined, 1, 1, 'defaultDomainBtn' ],
[ Mock.of<Domain>({ domain: '', isDefault: false }), undefined, 0, 0, undefined ],
[ Mock.of<Domain>({ domain: 'foo.com', isDefault: true }), undefined, 1, 1, 'defaultDomainBtn' ],
[ Mock.of<Domain>({ domain: 'foo.bar.com', isDefault: true }), undefined, 1, 1, 'defaultDomainBtn' ],
[ Mock.of<Domain>({ domain: 'foo.baz', isDefault: false }), undefined, 0, 0, undefined ],
[Mock.of<Domain>({ domain: '', isDefault: true }), undefined, 1, 1, 'defaultDomainBtn'],
[Mock.of<Domain>({ domain: '', isDefault: false }), undefined, 0, 0, undefined],
[Mock.of<Domain>({ domain: 'foo.com', isDefault: true }), undefined, 1, 1, 'defaultDomainBtn'],
[Mock.of<Domain>({ domain: 'foo.bar.com', isDefault: true }), undefined, 1, 1, 'defaultDomainBtn'],
[Mock.of<Domain>({ domain: 'foo.baz', isDefault: false }), undefined, 0, 0, undefined],
[
Mock.of<Domain>({ domain: 'foo.baz', isDefault: true }),
Mock.of<ReachableServer>({ version: '2.10.0' }),
@@ -85,11 +85,11 @@ describe('<DomainRow />', () => {
});
it.each([
[ undefined, 3 ],
[ Mock.of<ShlinkDomainRedirects>(), 3 ],
[ Mock.of<ShlinkDomainRedirects>({ baseUrlRedirect: 'foo' }), 2 ],
[ Mock.of<ShlinkDomainRedirects>({ invalidShortUrlRedirect: 'foo' }), 2 ],
[ Mock.of<ShlinkDomainRedirects>({ baseUrlRedirect: 'foo', regular404Redirect: 'foo' }), 1 ],
[undefined, 3],
[Mock.of<ShlinkDomainRedirects>(), 3],
[Mock.of<ShlinkDomainRedirects>({ baseUrlRedirect: 'foo' }), 2],
[Mock.of<ShlinkDomainRedirects>({ invalidShortUrlRedirect: 'foo' }), 2],
[Mock.of<ShlinkDomainRedirects>({ baseUrlRedirect: 'foo', regular404Redirect: 'foo' }), 1],
[
Mock.of<ShlinkDomainRedirects>(
{ baseUrlRedirect: 'foo', regular404Redirect: 'foo', invalidShortUrlRedirect: 'foo' },

View File

@@ -27,8 +27,8 @@ describe('<DomainSelector />', () => {
afterEach(() => wrapper.unmount());
it.each([
[ '', 'Domain', 'domains-dropdown__toggle-btn' ],
[ 'my-domain.com', 'Domain: my-domain.com', 'domains-dropdown__toggle-btn--active' ],
['', 'Domain', 'domains-dropdown__toggle-btn'],
['my-domain.com', 'Domain: my-domain.com', 'domains-dropdown__toggle-btn--active'],
])('shows dropdown by default', (value, expectedText, expectedClassName) => {
const wrapper = createWrapper(value);
const input = wrapper.find(InputGroup);
@@ -54,9 +54,9 @@ describe('<DomainSelector />', () => {
});
it.each([
[ 0, 'default.com<span class="float-end text-muted">default</span>' ],
[ 1, 'foo.com' ],
[ 2, 'bar.com' ],
[0, 'default.com<span class="float-end text-muted">default</span>'],
[1, 'foo.com'],
[2, 'bar.com'],
])('shows expected content on every item', (index, expectedContent) => {
const item = createWrapper().find(DropdownItem).at(index);

View File

@@ -35,7 +35,7 @@ describe('<DomainStatusIcon />', () => {
faTimes,
'Oops! There is some missing configuration, and short URLs shared with this domain will not work.',
],
[ 'valid' as DomainStatus, faCheck, 'Congratulations! This domain is properly configured.' ],
['valid' as DomainStatus, faCheck, 'Congratulations! This domain is properly configured.'],
])('renders expected icon and tooltip when status is not validating', (status, expectedIcon, expectedText) => {
const wrapper = createWrapper(status);
const tooltip = wrapper.find(UncontrolledTooltip);
@@ -59,8 +59,8 @@ describe('<DomainStatusIcon />', () => {
});
it.each([
[ true, 'top-start' ],
[ false, 'left' ],
[true, 'top-start'],
[false, 'left'],
])('places the tooltip properly based on query match', (isMobile, expectedPlacement) => {
matchMedia.mockReturnValue(Mock.of<MediaQueryList>({ matches: isMobile }));

View File

@@ -30,7 +30,7 @@ describe('domainsListReducer', () => {
Mock.of<Domain>({ domain: 'foo', status: 'validating' }),
Mock.of<Domain>({ domain: 'boo', status: 'validating' }),
];
const domains = [ ...filteredDomains, Mock.of<Domain>({ domain: 'bar', status: 'validating' }) ];
const domains = [...filteredDomains, Mock.of<Domain>({ domain: 'bar', status: 'validating' })];
beforeEach(jest.clearAllMocks);
@@ -64,9 +64,9 @@ describe('domainsListReducer', () => {
});
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'does_not_exist' ],
['foo'],
['bar'],
['does_not_exist'],
])('replaces redirects on proper domain on EDIT_DOMAIN_REDIRECTS', (domain) => {
const redirects: ShlinkDomainRedirects = {
baseUrlRedirect: 'bar',
@@ -84,9 +84,9 @@ describe('domainsListReducer', () => {
});
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'does_not_exist' ],
['foo'],
['bar'],
['does_not_exist'],
])('replaces status on proper domain on VALIDATE_DOMAIN', (domain) => {
expect(reducer(
Mock.of<DomainsList>({ domains, filteredDomains }),
@@ -124,9 +124,9 @@ describe('domainsListReducer', () => {
describe('filterDomains', () => {
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'something' ],
['foo'],
['bar'],
['something'],
])('creates action as expected', (searchTerm) => {
expect(filterDomainsAction(searchTerm)).toEqual({ type: FILTER_DOMAINS, searchTerm });
});
@@ -166,8 +166,8 @@ describe('domainsListReducer', () => {
});
it.each([
[ 'pass', 'valid' ],
[ 'fail', 'invalid' ],
['pass', 'valid'],
['fail', 'invalid'],
])('dispatches proper status based on status returned from health endpoint', async (
healthStatus,
expectedStatus,

View File

@@ -14,13 +14,13 @@ describe('helpers', () => {
const onTokenExpired = jest.fn();
it.each([
[ Mock.of<MercureInfo>({ loading: true, error: false, mercureHubUrl: 'foo' }) ],
[ Mock.of<MercureInfo>({ loading: false, error: true, mercureHubUrl: 'foo' }) ],
[ Mock.of<MercureInfo>({ loading: true, error: true, mercureHubUrl: 'foo' }) ],
[ Mock.of<MercureInfo>({ loading: false, error: false, mercureHubUrl: undefined }) ],
[ Mock.of<MercureInfo>({ loading: true, error: true, mercureHubUrl: undefined }) ],
[Mock.of<MercureInfo>({ loading: true, error: false, mercureHubUrl: 'foo' })],
[Mock.of<MercureInfo>({ loading: false, error: true, mercureHubUrl: 'foo' })],
[Mock.of<MercureInfo>({ loading: true, error: true, mercureHubUrl: 'foo' })],
[Mock.of<MercureInfo>({ loading: false, error: false, mercureHubUrl: undefined })],
[Mock.of<MercureInfo>({ loading: true, error: true, mercureHubUrl: undefined })],
])('does not bind an EventSource when loading, error or no hub URL', (mercureInfo) => {
bindToMercureTopic(mercureInfo, [ '' ], identity, () => {});
bindToMercureTopic(mercureInfo, [''], identity, () => {});
expect(EventSourcePolyfill).not.toHaveBeenCalled();
expect(onMessage).not.toHaveBeenCalled();
@@ -40,7 +40,7 @@ describe('helpers', () => {
error: false,
mercureHubUrl,
token,
}, [ topic ], onMessage, onTokenExpired);
}, [topic], onMessage, onTokenExpired);
expect(EventSourcePolyfill).toHaveBeenCalledWith(hubUrl, {
headers: {
@@ -48,7 +48,7 @@ describe('helpers', () => {
},
});
const [ es ] = (EventSourcePolyfill as any).mock.instances as EventSourcePolyfill[];
const [es] = (EventSourcePolyfill as any).mock.instances as EventSourcePolyfill[];
es.onmessage?.({ data: '{"foo": "bar"}' });
es.onerror?.({ status: 401 });

View File

@@ -18,8 +18,8 @@ describe('<CreateServer />', () => {
(useNavigate as any).mockReturnValue(navigate);
const useStateFlagTimeout = jest.fn()
.mockReturnValueOnce([ serversImported, () => '' ])
.mockReturnValueOnce([ importFailed, () => '' ])
.mockReturnValueOnce([serversImported, () => ''])
.mockReturnValueOnce([importFailed, () => ''])
.mockReturnValue([]);
const CreateServer = createServerConstruct(ImportServersBtn, useStateFlagTimeout);

View File

@@ -21,7 +21,7 @@ describe('<DeleteServerModal />', () => {
<DeleteServerModal
server={Mock.of<ServerWithId>({ name: serverName })}
toggle={toggleMock}
isOpen={true}
isOpen
deleteServer={deleteServerMock}
/>,
);

View File

@@ -12,7 +12,7 @@ describe('<ManageServers />', () => {
const serversExporter = Mock.of<ServersExporter>({ exportServers });
const ImportServersBtn = () => null;
const ManageServersRow = () => null;
const useStateFlagTimeout = jest.fn().mockReturnValue([ false, jest.fn() ]);
const useStateFlagTimeout = jest.fn().mockReturnValue([false, jest.fn()]);
const ManageServers = createManageServers(serversExporter, ImportServersBtn, useStateFlagTimeout, ManageServersRow);
let wrapper: ShallowWrapper;
const createServerMock = (value: string, autoConnect = false) => Mock.of<ServerWithId>(
@@ -52,8 +52,8 @@ describe('<ManageServers />', () => {
});
it.each([
[ createServerMock('foo'), 3 ],
[ createServerMock('foo', true), 4 ],
[createServerMock('foo'), 3],
[createServerMock('foo', true), 4],
])('shows different amount of columns if there are at least one auto-connect server', (server, expectedCols) => {
const wrapper = createWrapper({ server });
const row = wrapper.find(ManageServersRow);
@@ -63,8 +63,8 @@ describe('<ManageServers />', () => {
});
it.each([
[{}, 1 ],
[{ foo: createServerMock('foo') }, 2 ],
[{}, 1],
[{ foo: createServerMock('foo') }, 2],
])('shows export button if the list of servers is not empty', (servers, expectedButtons) => {
const wrapper = createWrapper(servers);
const exportBtn = wrapper.find(Button);
@@ -82,7 +82,7 @@ describe('<ManageServers />', () => {
});
it('shows an error message if an error occurs while importing servers', () => {
useStateFlagTimeout.mockReturnValue([ true, jest.fn() ]);
useStateFlagTimeout.mockReturnValue([true, jest.fn()]);
const wrapper = createWrapper({ foo: createServerMock('foo') });
const result = wrapper.find(Result);

View File

@@ -24,8 +24,8 @@ describe('<ManageServersRow />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ true, 4 ],
[ false, 3 ],
[true, 4],
[false, 3],
])('renders expected amount of columns', (hasAutoConnect, expectedCols) => {
const wrapper = createWrapper(hasAutoConnect);
const td = wrapper.find('td');
@@ -43,8 +43,8 @@ describe('<ManageServersRow />', () => {
});
it.each([
[ true, 1 ],
[ false, 0 ],
[true, 1],
[false, 0],
])('renders auto-connect icon only if server is autoConnect', (autoConnect, expectedIcons) => {
const wrapper = createWrapper(true, autoConnect);
const icon = wrapper.find(FontAwesomeIcon);

View File

@@ -73,8 +73,8 @@ describe('<ManageServersRowDropdown />', () => {
});
it.each([
[ true, 'Do not auto-connect' ],
[ false, 'Auto-connect' ],
[true, 'Do not auto-connect'],
[false, 'Auto-connect'],
])('shows different auto-connect toggle text depending on current server status', (autoConnect, expectedText) => {
const wrapper = createWrapper(autoConnect);
const item = wrapper.find(DropdownItem).at(2);

View File

@@ -32,7 +32,7 @@ describe('<Overview />', () => {
listTags={listTags}
loadVisitsOverview={loadVisitsOverview}
shortUrlsList={Mock.of<ShortUrlsListState>({ loading, shortUrls })}
tagsList={Mock.of<TagsList>({ loading, tags: [ 'foo', 'bar', 'baz' ] })}
tagsList={Mock.of<TagsList>({ loading, tags: ['foo', 'bar', 'baz'] })}
visitsOverview={Mock.of<VisitsOverview>({ loading, visitsCount: 3456, orphanVisitsCount: 28 })}
selectedServer={Mock.of<ReachableServer>({ id: serverId })}
createNewVisits={jest.fn()}

View File

@@ -40,7 +40,7 @@ describe('<ServersListGroup />', () => {
});
it.each([
[ servers ],
[servers],
[[]],
])('shows servers list', (servers) => {
const wrapped = createComponent({ servers });
@@ -50,9 +50,9 @@ describe('<ServersListGroup />', () => {
});
it.each([
[ true, 'servers-list__list-group servers-list__list-group--embedded' ],
[ false, 'servers-list__list-group' ],
[ undefined, 'servers-list__list-group' ],
[true, 'servers-list__list-group servers-list__list-group--embedded'],
[false, 'servers-list__list-group'],
[undefined, 'servers-list__list-group'],
])('renders proper classes for embedded', (embedded, expectedClasses) => {
const wrapped = createComponent({ servers, embedded });
const listGroup = wrapped.find(ListGroup);

View File

@@ -20,11 +20,11 @@ describe('<DuplicatedServersModal />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[[], 0 ],
[[ Mock.all<ServerData>() ], 2 ],
[[ Mock.all<ServerData>(), Mock.all<ServerData>() ], 2 ],
[[ Mock.all<ServerData>(), Mock.all<ServerData>(), Mock.all<ServerData>() ], 3 ],
[[ Mock.all<ServerData>(), Mock.all<ServerData>(), Mock.all<ServerData>(), Mock.all<ServerData>() ], 4 ],
[[], 0],
[[Mock.all<ServerData>()], 2],
[[Mock.all<ServerData>(), Mock.all<ServerData>()], 2],
[[Mock.all<ServerData>(), Mock.all<ServerData>(), Mock.all<ServerData>()], 3],
[[Mock.all<ServerData>(), Mock.all<ServerData>(), Mock.all<ServerData>(), Mock.all<ServerData>()], 4],
])('renders expected amount of items', (duplicatedServers, expectedItems) => {
const wrapper = createWrapper(duplicatedServers);
const li = wrapper.find('li');
@@ -34,7 +34,7 @@ describe('<DuplicatedServersModal />', () => {
it.each([
[
[ Mock.all<ServerData>() ],
[Mock.all<ServerData>()],
{
header: 'Duplicated server',
firstParagraph: 'There is already a server with:',
@@ -43,7 +43,7 @@ describe('<DuplicatedServersModal />', () => {
},
],
[
[ Mock.all<ServerData>(), Mock.all<ServerData>() ],
[Mock.all<ServerData>(), Mock.all<ServerData>()],
{
header: 'Duplicated servers',
firstParagraph: 'The next servers already exist:',
@@ -66,7 +66,7 @@ describe('<DuplicatedServersModal />', () => {
it.each([
[[]],
[[ Mock.of<ServerData>({ url: 'url', apiKey: 'apiKey' }) ]],
[[Mock.of<ServerData>({ url: 'url', apiKey: 'apiKey' })]],
])('displays provided server data', (duplicatedServers) => {
const wrapper = createWrapper(duplicatedServers);
const li = wrapper.find('li');

View File

@@ -26,9 +26,9 @@ describe('<ForServerVersion />', () => {
});
it.each([
[ '2.0.0' as SemVerPattern, undefined, '1.8.3' as SemVer ],
[ undefined, '1.8.0' as SemVerPattern, '1.8.3' as SemVer ],
[ '1.7.0' as SemVerPattern, '1.8.0' as SemVerPattern, '1.8.3' as SemVer ],
['2.0.0' as SemVerPattern, undefined, '1.8.3' as SemVer],
[undefined, '1.8.0' as SemVerPattern, '1.8.3' as SemVer],
['1.7.0' as SemVerPattern, '1.8.0' as SemVerPattern, '1.8.3' as SemVer],
])('does not render children when current version does not match requirements', (min, max, version) => {
const wrapped = renderComponent(Mock.of<ReachableServer>({ version, printableVersion: version }), min, max);
@@ -36,11 +36,11 @@ describe('<ForServerVersion />', () => {
});
it.each([
[ '2.0.0' as SemVerPattern, undefined, '2.8.3' as SemVer ],
[ '2.0.0' as SemVerPattern, undefined, '2.0.0' as SemVer ],
[ undefined, '1.8.0' as SemVerPattern, '1.8.0' as SemVer ],
[ undefined, '1.8.0' as SemVerPattern, '1.7.1' as SemVer ],
[ '1.7.0' as SemVerPattern, '1.8.0' as SemVerPattern, '1.7.3' as SemVer ],
['2.0.0' as SemVerPattern, undefined, '2.8.3' as SemVer],
['2.0.0' as SemVerPattern, undefined, '2.0.0' as SemVer],
[undefined, '1.8.0' as SemVerPattern, '1.8.0' as SemVer],
[undefined, '1.8.0' as SemVerPattern, '1.7.1' as SemVer],
['1.7.0' as SemVerPattern, '1.8.0' as SemVerPattern, '1.7.3' as SemVer],
])('renders children when current version matches requirements', (min, max, version) => {
const wrapped = renderComponent(Mock.of<ReachableServer>({ version, printableVersion: version }), min, max);

View File

@@ -16,8 +16,8 @@ describe('<HighlightCard />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined ],
[ false ],
[undefined],
[false],
])('renders expected components', (link) => {
const wrapper = createWrapper({ title: 'foo', link: link as undefined | false });
@@ -30,9 +30,9 @@ describe('<HighlightCard />', () => {
});
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'baz' ],
['foo'],
['bar'],
['baz'],
])('renders provided title', (title) => {
const wrapper = createWrapper({ title });
const cardTitle = wrapper.find(CardTitle);
@@ -41,9 +41,9 @@ describe('<HighlightCard />', () => {
});
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'baz' ],
['foo'],
['bar'],
['baz'],
])('renders provided children', (children) => {
const wrapper = createWrapper({ title: 'foo', children });
const cardText = wrapper.find(CardText);
@@ -52,9 +52,9 @@ describe('<HighlightCard />', () => {
});
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'baz' ],
['foo'],
['bar'],
['baz'],
])('adds extra props when a link is provided', (link) => {
const wrapper = createWrapper({ title: 'foo', link });

View File

@@ -41,9 +41,9 @@ describe('<ImportServersBtn />', () => {
});
it.each([
[ undefined, '' ],
[ 'foo', 'foo' ],
[ 'bar', 'bar' ],
[undefined, ''],
['foo', 'foo'],
['bar', 'bar'],
])('allows a class name to be provided', (providedClassName, expectedClassName) => {
const wrapper = createWrapper({ className: providedClassName });
@@ -51,9 +51,9 @@ describe('<ImportServersBtn />', () => {
});
it.each([
[ undefined, true ],
[ 'foo', false ],
[ 'bar', false ],
[undefined, true],
['foo', false],
['bar', false],
])('has expected text', (children, expectToHaveDefaultText) => {
const wrapper = createWrapper({ children });
@@ -78,14 +78,14 @@ describe('<ImportServersBtn />', () => {
const wrapper = createWrapper();
const file = wrapper.find('.import-servers-btn__csv-select');
await file.simulate('change', { target: { files: [ '' ] } }); // eslint-disable-line @typescript-eslint/await-thenable
await file.simulate('change', { target: { files: [''] } }); // eslint-disable-line @typescript-eslint/await-thenable
expect(importServersFromFile).toHaveBeenCalledTimes(1);
});
it.each([
[ 'discard' ],
[ 'save' ],
['discard'],
['save'],
])('invokes callback in DuplicatedServersModal events', (event) => {
const wrapper = createWrapper();

View File

@@ -38,7 +38,7 @@ describe('<ServerError />', () => {
const wrapperText = wrapper.html();
const textPairs = Object.entries(textsToFind);
textPairs.forEach(([ text, shouldBeFound ]) => {
textPairs.forEach(([text, shouldBeFound]) => {
if (shouldBeFound) {
expect(wrapperText).toContain(text);
} else {

View File

@@ -80,7 +80,7 @@ describe('remoteServersReducer', () => {
},
},
],
[ '<html></html>', {}],
['<html></html>', {}],
[{}, {}],
])('tries to fetch servers from remote', async (mockedValue, expectedNewServers) => {
get.mockResolvedValue(mockedValue);

View File

@@ -45,9 +45,9 @@ describe('selectedServerReducer', () => {
afterEach(jest.clearAllMocks);
it.each([
[ version, version, `v${version}` ],
[ 'latest', MAX_FALLBACK_VERSION, 'latest' ],
[ '%invalid_semver%', MIN_FALLBACK_VERSION, '%invalid_semver%' ],
[version, version, `v${version}`],
['latest', MAX_FALLBACK_VERSION, 'latest'],
['%invalid_semver%', MIN_FALLBACK_VERSION, '%invalid_semver%'],
])('dispatches proper actions', async (serverVersion, expectedVersion, expectedPrintableVersion) => {
const id = uuid();
const getState = createGetStateMock(id);

View File

@@ -58,8 +58,8 @@ describe('serverReducer', () => {
}));
it.each([
[ true ],
[ false ],
[true],
[false],
])('returns state as it is when trying to set auto-connect on invalid server', (autoConnect) =>
expect(reducer(list, {
type: SET_AUTO_CONNECT,
@@ -149,8 +149,8 @@ describe('serverReducer', () => {
describe('setAutoConnect', () => {
it.each([
[ true ],
[ false ],
[true],
[false],
])('returns expected action', (autoConnect) => {
const serverToEdit = Mock.of<RegularServer>({ id: 'abc123' });
const result = setAutoConnect(serverToEdit, autoConnect);

View File

@@ -4,7 +4,7 @@ import { ServersImporter } from '../../../src/servers/services/ServersImporter';
import { RegularServer } from '../../../src/servers/data';
describe('ServersImporter', () => {
const servers: RegularServer[] = [ Mock.all<RegularServer>(), Mock.all<RegularServer>() ];
const servers: RegularServer[] = [Mock.all<RegularServer>(), Mock.all<RegularServer>()];
const toObject = jest.fn().mockReturnValue(servers);
const csvjsonMock = Mock.of<CsvJson>({ toObject });
const readAsText = jest.fn();
@@ -37,7 +37,7 @@ describe('ServersImporter', () => {
it.each([
[{}],
[ undefined ],
[undefined],
[[{ foo: 'bar' }]],
[
[

View File

@@ -62,10 +62,10 @@ describe('<RealTimeUpdatesSettings />', () => {
});
it.each([
[ 1, 'minute' ],
[ 2, 'minutes' ],
[ 10, 'minutes' ],
[ 100, 'minutes' ],
[1, 'minute'],
[2, 'minutes'],
[10, 'minutes'],
[100, 'minutes'],
])('shows expected children when interval is greater than 0', (interval, minutesWord) => {
const wrapper = createWrapper({ enabled: true, interval });
const span = wrapper.find('span');
@@ -78,7 +78,7 @@ describe('<RealTimeUpdatesSettings />', () => {
expect(input.prop('value')).toEqual(`${interval}`);
});
it.each([[ undefined ], [ 0 ]])('shows expected children when interval is 0 or undefined', (interval) => {
it.each([[undefined], [0]])('shows expected children when interval is 0 or undefined', (interval) => {
const wrapper = createWrapper({ enabled: true, interval });
const span = wrapper.find('span');
const formText = wrapper.find(FormText).at(1);

View File

@@ -25,9 +25,9 @@ describe('<ShortUrlCreationSettings />', () => {
afterEach(jest.clearAllMocks);
it.each([
[{ validateUrls: true }, true ],
[{ validateUrls: false }, false ],
[ undefined, false ],
[{ validateUrls: true }, true],
[{ validateUrls: false }, false],
[undefined, false],
])('URL validation switch is toggled if option is true', (shortUrlCreation, expectedChecked) => {
const wrapper = createWrapper(shortUrlCreation);
const urlValidationToggle = wrapper.find(ToggleSwitch).first();
@@ -36,9 +36,9 @@ describe('<ShortUrlCreationSettings />', () => {
});
it.each([
[{ forwardQuery: true }, true ],
[{ forwardQuery: false }, false ],
[{}, true ],
[{ forwardQuery: true }, true],
[{ forwardQuery: false }, false],
[{}, true],
])('forward query switch is toggled if option is true', (shortUrlCreation, expectedChecked) => {
const wrapper = createWrapper({ validateUrls: true, ...shortUrlCreation });
const forwardQueryToggle = wrapper.find(ToggleSwitch).last();
@@ -47,9 +47,9 @@ describe('<ShortUrlCreationSettings />', () => {
});
it.each([
[{ validateUrls: true }, '<b>Validate URL</b> checkbox will be <b>checked</b>' ],
[{ validateUrls: false }, '<b>Validate URL</b> checkbox will be <b>unchecked</b>' ],
[ undefined, '<b>Validate URL</b> checkbox will be <b>unchecked</b>' ],
[{ validateUrls: true }, '<b>Validate URL</b> checkbox will be <b>checked</b>'],
[{ validateUrls: false }, '<b>Validate URL</b> checkbox will be <b>unchecked</b>'],
[undefined, '<b>Validate URL</b> checkbox will be <b>unchecked</b>'],
])('shows expected helper text for URL validation', (shortUrlCreation, expectedText) => {
const wrapper = createWrapper(shortUrlCreation);
const validateUrlText = wrapper.find(FormText).first();
@@ -58,9 +58,9 @@ describe('<ShortUrlCreationSettings />', () => {
});
it.each([
[{ forwardQuery: true }, '<b>Forward query params on redirect</b> checkbox will be <b>checked</b>' ],
[{ forwardQuery: false }, '<b>Forward query params on redirect</b> checkbox will be <b>unchecked</b>' ],
[{}, '<b>Forward query params on redirect</b> checkbox will be <b>checked</b>' ],
[{ forwardQuery: true }, '<b>Forward query params on redirect</b> checkbox will be <b>checked</b>'],
[{ forwardQuery: false }, '<b>Forward query params on redirect</b> checkbox will be <b>unchecked</b>'],
[{}, '<b>Forward query params on redirect</b> checkbox will be <b>checked</b>'],
])('shows expected helper text for query forwarding', (shortUrlCreation, expectedText) => {
const wrapper = createWrapper({ validateUrls: true, ...shortUrlCreation });
const forwardQueryText = wrapper.find(FormText).at(1);
@@ -69,13 +69,13 @@ describe('<ShortUrlCreationSettings />', () => {
});
it.each([
[ { tagFilteringMode: 'includes' } as ShortUrlsSettings, 'Suggest tags including input', 'including' ],
[{ tagFilteringMode: 'includes' } as ShortUrlsSettings, 'Suggest tags including input', 'including'],
[
{ tagFilteringMode: 'startsWith' } as ShortUrlsSettings,
'Suggest tags starting with input',
'starting with',
],
[ undefined, 'Suggest tags starting with input', 'starting with' ],
[undefined, 'Suggest tags starting with input', 'starting with'],
])('shows expected texts for tags suggestions', (shortUrlCreation, expectedText, expectedHint) => {
const wrapper = createWrapper(shortUrlCreation);
const hintText = wrapper.find(FormText).last();
@@ -85,7 +85,7 @@ describe('<ShortUrlCreationSettings />', () => {
expect(hintText.html()).toContain(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', (validateUrls) => {
const wrapper = createWrapper();
const urlValidationToggle = wrapper.find(ToggleSwitch).first();
@@ -94,7 +94,7 @@ describe('<ShortUrlCreationSettings />', () => {
expect(setShortUrlCreationSettings).toHaveBeenCalledWith({ 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', (forwardQuery) => {
const wrapper = createWrapper();
const urlValidationToggle = wrapper.find(ToggleSwitch).last();

View File

@@ -24,8 +24,8 @@ describe('<ShortUrlsListSettings />', () => {
afterEach(jest.clearAllMocks);
it.each([
[ undefined, DEFAULT_SHORT_URLS_ORDERING ],
[{}, DEFAULT_SHORT_URLS_ORDERING ],
[undefined, DEFAULT_SHORT_URLS_ORDERING],
[{}, DEFAULT_SHORT_URLS_ORDERING],
[{ defaultOrdering: {} }, {}],
[{ defaultOrdering: { field: 'longUrl', dir: 'DESC' } as ShortUrlsOrder }, { field: 'longUrl', dir: 'DESC' }],
[{ defaultOrdering: { field: 'visits', dir: 'ASC' } as ShortUrlsOrder }, { field: 'visits', dir: 'ASC' }],
@@ -37,10 +37,10 @@ describe('<ShortUrlsListSettings />', () => {
});
it.each([
[ undefined, undefined ],
[ 'longUrl', 'ASC' ],
[ 'visits', undefined ],
[ 'title', 'DESC' ],
[undefined, undefined],
['longUrl', 'ASC'],
['visits', undefined],
['title', 'DESC'],
])('invokes setSettings when ordering changes', (field, dir) => {
const wrapper = createWrapper();
const dropdown = wrapper.find(OrderingDropdown);

View File

@@ -28,10 +28,10 @@ describe('<TagsSettings />', () => {
});
it.each([
[ undefined, 'cards' ],
[{}, 'cards' ],
[{ defaultMode: 'cards' as TagsMode }, 'cards' ],
[{ defaultMode: 'list' as TagsMode }, 'list' ],
[undefined, 'cards'],
[{}, 'cards'],
[{ defaultMode: 'cards' as TagsMode }, 'cards'],
[{ defaultMode: 'list' as TagsMode }, 'list'],
])('shows expected tags displaying mode', (tags, expectedMode) => {
const wrapper = createWrapper(tags);
const dropdown = wrapper.find(TagsModeDropdown);
@@ -42,8 +42,8 @@ describe('<TagsSettings />', () => {
});
it.each([
[ 'cards' as TagsMode ],
[ 'list' as TagsMode ],
['cards' as TagsMode],
['list' as TagsMode],
])('invokes setTagsSettings when tags mode changes', (defaultMode) => {
const wrapper = createWrapper();
const dropdown = wrapper.find(TagsModeDropdown);
@@ -54,7 +54,7 @@ describe('<TagsSettings />', () => {
});
it.each([
[ undefined, {}],
[undefined, {}],
[{}, {}],
[{ defaultOrdering: {} }, {}],
[{ defaultOrdering: { field: 'tag', dir: 'DESC' } as TagsOrder }, { field: 'tag', dir: 'DESC' }],
@@ -67,10 +67,10 @@ describe('<TagsSettings />', () => {
});
it.each([
[ undefined, undefined ],
[ 'tag', 'ASC' ],
[ 'visits', undefined ],
[ 'shortUrls', 'DESC' ],
[undefined, undefined],
['tag', 'ASC'],
['visits', undefined],
['shortUrls', 'DESC'],
])('invokes setTagsSettings when ordering changes', (field, dir) => {
const wrapper = createWrapper();
const dropdown = wrapper.find(OrderingDropdown);

View File

@@ -20,9 +20,9 @@ describe('<UserInterfaceSettings />', () => {
afterEach(jest.clearAllMocks);
it.each([
[{ theme: 'dark' as Theme }, true ],
[{ theme: 'light' as Theme }, false ],
[ undefined, false ],
[{ theme: 'dark' as Theme }, true],
[{ theme: 'light' as Theme }, false],
[undefined, false],
])('toggles switch if theme is dark', (ui, expectedChecked) => {
const wrapper = createWrapper(ui);
const toggle = wrapper.find(ToggleSwitch);
@@ -31,9 +31,9 @@ describe('<UserInterfaceSettings />', () => {
});
it.each([
[{ theme: 'dark' as Theme }, faMoon ],
[{ theme: 'light' as Theme }, faSun ],
[ undefined, faSun ],
[{ theme: 'dark' as Theme }, faMoon],
[{ theme: 'light' as Theme }, faSun],
[undefined, faSun],
])('shows different icons based on theme', (ui, expectedIcon) => {
const wrapper = createWrapper(ui);
const icon = wrapper.find(FontAwesomeIcon);
@@ -42,8 +42,8 @@ describe('<UserInterfaceSettings />', () => {
});
it.each([
[ true, 'dark' ],
[ false, 'light' ],
[true, 'dark'],
[false, 'light'],
])('invokes setUiSettings when theme toggle value changes', (checked, theme) => {
const wrapper = createWrapper();
const toggle = wrapper.find(ToggleSwitch);

View File

@@ -27,8 +27,8 @@ describe('<VisitsSettings />', () => {
});
it.each([
[ Mock.all<Settings>(), 'last30Days' ],
[ Mock.of<Settings>({ visits: {} }), 'last30Days' ],
[Mock.all<Settings>(), 'last30Days'],
[Mock.of<Settings>({ visits: {} }), 'last30Days'],
[
Mock.of<Settings>({
visits: {

View File

@@ -25,7 +25,7 @@ describe('settingsReducer', () => {
});
describe('toggleRealTimeUpdates', () => {
it.each([[ true ], [ false ]])('updates settings with provided value and then loads updates again', (enabled) => {
it.each([[true], [false]])('updates settings with provided value and then loads updates again', (enabled) => {
const result = toggleRealTimeUpdates(enabled);
expect(result).toEqual({ type: SET_SETTINGS, realTimeUpdates: { enabled } });
@@ -33,7 +33,7 @@ describe('settingsReducer', () => {
});
describe('setRealTimeUpdatesInterval', () => {
it.each([[ 0 ], [ 1 ], [ 2 ], [ 10 ]])('updates settings with provided value and then loads updates again', (interval) => {
it.each([[0], [1], [2], [10]])('updates settings with provided value and then loads updates again', (interval) => {
const result = setRealTimeUpdatesInterval(interval);
expect(result).toEqual({ type: SET_SETTINGS, realTimeUpdates: { interval } });

View File

@@ -60,7 +60,7 @@ describe('<EditShortUrl />', () => {
});
it.each([
[ undefined, { longUrl: '', validateUrl: true }, true ],
[undefined, { longUrl: '', validateUrl: true }, true],
[
Mock.of<ShortUrl>({ meta: {} }),
{

View File

@@ -12,22 +12,22 @@ describe('<Paginator />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined ],
[ buildPaginator() ],
[ buildPaginator(0) ],
[ buildPaginator(1) ],
[undefined],
[buildPaginator()],
[buildPaginator(0)],
[buildPaginator(1)],
])('renders nothing if the number of pages is below 2', (paginator) => {
wrapper = shallow(<Paginator serverId="abc123" paginator={paginator} />);
expect(wrapper.text()).toEqual('');
});
it.each([
[ buildPaginator(2), 4, 0 ],
[ buildPaginator(3), 5, 0 ],
[ buildPaginator(4), 6, 0 ],
[ buildPaginator(5), 7, 1 ],
[ buildPaginator(6), 7, 1 ],
[ buildPaginator(23), 7, 1 ],
[buildPaginator(2), 4, 0],
[buildPaginator(3), 5, 0],
[buildPaginator(4), 6, 0],
[buildPaginator(5), 7, 1],
[buildPaginator(6), 7, 1],
[buildPaginator(23), 7, 1],
])('renders previous, next and the list of pages, with ellipses when expected', (
paginator,
expectedPages,

View File

@@ -41,7 +41,7 @@ describe('<ShortUrlForm />', () => {
const validUntil = parseDate('2017-01-06', 'yyyy-MM-dd');
wrapper.find(Input).first().simulate('change', { target: { value: 'https://long-domain.com/foo/bar' } });
wrapper.find('TagsSelector').simulate('change', [ 'tag_foo', 'tag_bar' ]);
wrapper.find('TagsSelector').simulate('change', ['tag_foo', 'tag_bar']);
wrapper.find('#customSlug').simulate('change', { target: { value: 'my-slug' } });
wrapper.find(DomainSelector).simulate('change', 'example.com');
wrapper.find('#maxVisits').simulate('change', { target: { value: '20' } });
@@ -53,7 +53,7 @@ describe('<ShortUrlForm />', () => {
expect(createShortUrl).toHaveBeenCalledTimes(1);
expect(createShortUrl).toHaveBeenCalledWith({
longUrl: 'https://long-domain.com/foo/bar',
tags: [ 'tag_foo', 'tag_bar' ],
tags: ['tag_foo', 'tag_bar'],
customSlug: 'my-slug',
domain: 'example.com',
validSince: formatISO(validSince),
@@ -66,12 +66,12 @@ describe('<ShortUrlForm />', () => {
});
it.each([
[ null, 'create' as Mode, 4 ],
[ null, 'create-basic' as Mode, 0 ],
[ Mock.of<ReachableServer>({ version: '2.6.0' }), 'create' as Mode, 4 ],
[ Mock.of<ReachableServer>({ version: '2.5.0' }), 'create' as Mode, 4 ],
[ Mock.of<ReachableServer>({ version: '2.6.0' }), 'edit' as Mode, 4 ],
[ Mock.of<ReachableServer>({ version: '2.5.0' }), 'edit' as Mode, 3 ],
[null, 'create' as Mode, 4],
[null, 'create-basic' as Mode, 0],
[Mock.of<ReachableServer>({ version: '2.6.0' }), 'create' as Mode, 4],
[Mock.of<ReachableServer>({ version: '2.5.0' }), 'create' as Mode, 4],
[Mock.of<ReachableServer>({ version: '2.6.0' }), 'edit' as Mode, 4],
[Mock.of<ReachableServer>({ version: '2.5.0' }), 'edit' as Mode, 3],
])(
'renders expected amount of cards based on server capabilities and mode',
(selectedServer, mode, expectedAmountOfCards) => {
@@ -83,16 +83,16 @@ describe('<ShortUrlForm />', () => {
);
it.each([
[ null, 'new title', 'new title' ],
[ undefined, 'new title', 'new title' ],
[ '', 'new title', 'new title' ],
[ null, '', undefined ],
[ null, null, undefined ],
[ '', '', undefined ],
[ undefined, undefined, undefined ],
[ 'old title', null, null ],
[ 'old title', undefined, null ],
[ 'old title', '', null ],
[null, 'new title', 'new title'],
[undefined, 'new title', 'new title'],
['', 'new title', 'new title'],
[null, '', undefined],
[null, null, undefined],
['', '', undefined],
[undefined, undefined, undefined],
['old title', null, null],
['old title', undefined, null],
['old title', '', null],
])('sends expected title based on original and new values', (originalTitle, newTitle, expectedSentTitle) => {
const wrapper = createWrapper(Mock.of<ReachableServer>({ version: '2.6.0' }), 'create', originalTitle);

View File

@@ -53,10 +53,10 @@ describe('<ShortUrlsFilteringBar />', () => {
});
it.each([
[ 'tags=foo,bar,baz', 3 ],
[ 'tags=foo,baz', 2 ],
[ '', 0 ],
[ 'foo=bar', 0 ],
['tags=foo,bar,baz', 3],
['tags=foo,baz', 2],
['', 0],
['foo=bar', 0],
])('renders the proper amount of tags', (search, expectedTagComps) => {
const wrapper = createWrapper(search);
@@ -82,8 +82,8 @@ describe('<ShortUrlsFilteringBar />', () => {
});
it.each([
[{ startDate: now }, `startDate=${encodeURIComponent(formatISO(now))}` ],
[{ endDate: now }, `endDate=${encodeURIComponent(formatISO(now))}` ],
[{ startDate: now }, `startDate=${encodeURIComponent(formatISO(now))}`],
[{ endDate: now }, `endDate=${encodeURIComponent(formatISO(now))}`],
[
{ startDate: now, endDate: now },
`startDate=${encodeURIComponent(formatISO(now))}&endDate=${encodeURIComponent(formatISO(now))}`,
@@ -98,12 +98,12 @@ describe('<ShortUrlsFilteringBar />', () => {
});
it.each([
[ 'tags=foo,bar,baz', Mock.of<ReachableServer>({ version: '3.0.0' }), 1 ],
[ 'tags=foo,bar', Mock.of<ReachableServer>({ version: '3.1.0' }), 1 ],
[ 'tags=foo', Mock.of<ReachableServer>({ version: '3.0.0' }), 0 ],
[ '', Mock.of<ReachableServer>({ version: '3.0.0' }), 0 ],
[ 'tags=foo,bar,baz', Mock.of<ReachableServer>({ version: '2.10.0' }), 0 ],
[ '', Mock.of<ReachableServer>({ version: '2.10.0' }), 0 ],
['tags=foo,bar,baz', Mock.of<ReachableServer>({ version: '3.0.0' }), 1],
['tags=foo,bar', Mock.of<ReachableServer>({ version: '3.1.0' }), 1],
['tags=foo', Mock.of<ReachableServer>({ version: '3.0.0' }), 0],
['', Mock.of<ReachableServer>({ version: '3.0.0' }), 0],
['tags=foo,bar,baz', Mock.of<ReachableServer>({ version: '2.10.0' }), 0],
['', Mock.of<ReachableServer>({ version: '2.10.0' }), 0],
])(
'renders tags mode toggle if the server supports it and there is more than one tag selected',
(search, selectedServer, expectedTagToggleComponents) => {
@@ -115,9 +115,9 @@ describe('<ShortUrlsFilteringBar />', () => {
);
it.each([
[ '', 'Short URLs including any tag.', false ],
[ '&tagsMode=all', 'Short URLs including all tags.', true ],
[ '&tagsMode=any', 'Short URLs including any tag.', false ],
['', 'Short URLs including any tag.', false],
['&tagsMode=all', 'Short URLs including all tags.', true],
['&tagsMode=any', 'Short URLs including any tag.', false],
])('expected tags mode tooltip title', (initialTagsMode, expectedToggleText, expectedChecked) => {
const wrapper = createWrapper(`tags=foo,bar${initialTagsMode}`, Mock.of<ReachableServer>({ version: '3.0.0' }));
const toggle = wrapper.find(TooltipToggleSwitch);
@@ -127,9 +127,9 @@ describe('<ShortUrlsFilteringBar />', () => {
});
it.each([
[ '', 'tagsMode=all' ],
[ '&tagsMode=all', 'tagsMode=any' ],
[ '&tagsMode=any', 'tagsMode=all' ],
['', 'tagsMode=all'],
['&tagsMode=all', 'tagsMode=any'],
['&tagsMode=any', 'tagsMode=all'],
])('redirects to first page when tags mode changes', (initialTagsMode, expectedRedirectTagsMode) => {
const wrapper = createWrapper(`tags=foo,bar${initialTagsMode}`, Mock.of<ReachableServer>({ version: '3.0.0' }));
const toggle = wrapper.find(TooltipToggleSwitch);

View File

@@ -30,7 +30,7 @@ describe('<ShortUrlsList />', () => {
shortCode: 'testShortCode',
shortUrl: 'https://www.example.com/testShortUrl',
longUrl: 'https://www.example.com/testLongUrl',
tags: [ 'test tag' ],
tags: ['test tag'],
}),
],
pagination: {},
@@ -106,9 +106,9 @@ describe('<ShortUrlsList />', () => {
});
it.each([
[ Mock.of<ShortUrlsOrder>({ field: 'visits', dir: 'ASC' }), 'visits', 'ASC' ],
[ Mock.of<ShortUrlsOrder>({ field: 'title', dir: 'DESC' }), 'title', 'DESC' ],
[ Mock.of<ShortUrlsOrder>(), undefined, undefined ],
[Mock.of<ShortUrlsOrder>({ field: 'visits', dir: 'ASC' }), 'visits', 'ASC'],
[Mock.of<ShortUrlsOrder>({ field: 'title', dir: 'DESC' }), 'title', 'DESC'],
[Mock.of<ShortUrlsOrder>(), undefined, undefined],
])('has expected initial ordering', (initialOrderBy, field, dir) => {
const wrapper = createWrapper(initialOrderBy);

View File

@@ -62,10 +62,10 @@ describe('<ShortUrlsTable />', () => {
});
it.each([
[ '2.6.0' as SemVer ],
[ '2.6.1' as SemVer ],
[ '2.7.0' as SemVer ],
[ '3.0.0' as SemVer ],
['2.6.0' as SemVer],
['2.6.1' as SemVer],
['2.7.0' as SemVer],
['3.0.0' as SemVer],
])('should render composed column when server supports title', (version) => {
const wrapper = createWrapper(Mock.of<ReachableServer>({ version }));
const composedColumn = wrapper.find('table').find('th').at(2);

View File

@@ -10,7 +10,7 @@ import { Result } from '../../../src/utils/Result';
describe('<CreateShortUrlResult />', () => {
let wrapper: ShallowWrapper;
const copyToClipboard = jest.fn();
const useStateFlagTimeout = jest.fn(() => [ false, copyToClipboard ]) as StateFlagTimeout;
const useStateFlagTimeout = jest.fn(() => [false, copyToClipboard]) as StateFlagTimeout;
const CreateShortUrlResult = createCreateShortUrlResult(useStateFlagTimeout);
const createWrapper = (result: ShortUrl | null = null, error = false) => {
wrapper = shallow(

View File

@@ -30,9 +30,9 @@ describe('<ExportShortUrlsBtn />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined, 0 ],
[ 1, 1 ],
[ 4578, 4578 ],
[undefined, 0],
[1, 1],
[4578, 4578],
])('renders expected amount', (amount, expectedAmount) => {
const wrapper = createWrapper(amount);
@@ -40,8 +40,8 @@ describe('<ExportShortUrlsBtn />', () => {
});
it.each([
[ null ],
[ Mock.of<NotFoundServer>() ],
[null],
[Mock.of<NotFoundServer>()],
])('does nothing on click if selected server is not reachable', (selectedServer) => {
const wrapper = createWrapper(0, selectedServer);
@@ -51,12 +51,12 @@ describe('<ExportShortUrlsBtn />', () => {
});
it.each([
[ 10, 1 ],
[ 30, 2 ],
[ 39, 2 ],
[ 40, 2 ],
[ 41, 3 ],
[ 385, 20 ],
[10, 1],
[30, 2],
[39, 2],
[40, 2],
[41, 3],
[385, 20],
])('loads proper amount of pages based on the amount of results', async (amount, expectedPageLoads) => {
const wrapper = createWrapper(amount, Mock.of<ReachableServer>({ id: '123' }));

View File

@@ -22,7 +22,7 @@ describe('<QrCodeModal />', () => {
wrapper = shallow(
<QrCodeModal
shortUrl={Mock.of<ShortUrl>({ shortUrl })}
isOpen={true}
isOpen
toggle={() => {}}
selectedServer={selectedServer}
/>,
@@ -43,10 +43,10 @@ describe('<QrCodeModal />', () => {
});
it.each([
[ '2.5.0' as SemVer, 0, '/qr-code?size=300&format=png' ],
[ '2.6.0' as SemVer, 0, '/qr-code?size=300&format=png' ],
[ '2.6.0' as SemVer, 10, '/qr-code?size=300&format=png&margin=10' ],
[ '2.8.0' as SemVer, 0, '/qr-code?size=300&format=png&errorCorrection=L' ],
['2.5.0' as SemVer, 0, '/qr-code?size=300&format=png'],
['2.6.0' as SemVer, 0, '/qr-code?size=300&format=png'],
['2.6.0' as SemVer, 10, '/qr-code?size=300&format=png&margin=10'],
['2.8.0' as SemVer, 0, '/qr-code?size=300&format=png&errorCorrection=L'],
])('displays an image with the QR code of the URL', (version, margin, expectedUrl) => {
const wrapper = createWrapper(version);
const formControls = wrapper.find('.form-control-range');
@@ -66,12 +66,12 @@ describe('<QrCodeModal />', () => {
});
it.each([
[ 530, 0, 'lg' ],
[ 200, 0, undefined ],
[ 830, 0, 'xl' ],
[ 430, 80, 'lg' ],
[ 200, 50, undefined ],
[ 720, 100, 'xl' ],
[530, 0, 'lg'],
[200, 0, undefined],
[830, 0, 'xl'],
[430, 80, 'lg'],
[200, 50, undefined],
[720, 100, 'xl'],
])('renders expected size', (size, margin, modalSize) => {
const wrapper = createWrapper();
const formControls = wrapper.find('.form-control-range');
@@ -87,8 +87,8 @@ describe('<QrCodeModal />', () => {
});
it.each([
[ '2.6.0' as SemVer, 1, 'col-md-4' ],
[ '2.8.0' as SemVer, 2, 'col-md-6' ],
['2.6.0' as SemVer, 1, 'col-md-4'],
['2.8.0' as SemVer, 2, 'col-md-6'],
])('shows expected components based on server version', (version, expectedAmountOfDropdowns, expectedRangeClass) => {
const wrapper = createWrapper(version);
const dropdownsLength = wrapper.find(QrFormatDropdown).length + wrapper.find(QrErrorCorrectionDropdown).length;

View File

@@ -11,13 +11,13 @@ describe('<ShortUrlDetailLink />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined, undefined ],
[ null, null ],
[ Mock.of<ReachableServer>({ id: '1' }), null ],
[ Mock.of<ReachableServer>({ id: '1' }), undefined ],
[ Mock.of<NotFoundServer>(), Mock.all<ShortUrl>() ],
[ null, Mock.all<ShortUrl>() ],
[ undefined, Mock.all<ShortUrl>() ],
[undefined, undefined],
[null, null],
[Mock.of<ReachableServer>({ id: '1' }), null],
[Mock.of<ReachableServer>({ id: '1' }), undefined],
[Mock.of<NotFoundServer>(), Mock.all<ShortUrl>()],
[null, Mock.all<ShortUrl>()],
[undefined, Mock.all<ShortUrl>()],
])('only renders a plain span when either server or short URL are not set', (selectedServer, shortUrl) => {
wrapper = shallow(
<ShortUrlDetailLink selectedServer={selectedServer} shortUrl={shortUrl} suffix="visits">

View File

@@ -5,8 +5,8 @@ import { InfoTooltip } from '../../../src/utils/InfoTooltip';
describe('<ShortUrlFormCheckboxGroup />', () => {
it.each([
[ undefined, '', 0 ],
[ 'This is the tooltip', 'me-2', 1 ],
[undefined, '', 0],
['This is the tooltip', 'me-2', 1],
])('renders tooltip only when provided', (infoTooltip, expectedClassName, expectedAmountOfTooltips) => {
const wrapper = shallow(<ShortUrlFormCheckboxGroup infoTooltip={infoTooltip} />);
const checkbox = wrapper.find(Checkbox);

View File

@@ -15,7 +15,7 @@ describe('<ShortUrlVisitsCount />', () => {
afterEach(() => wrapper?.unmount());
it.each([ undefined, {}])('just returns visits when no maxVisits is provided', (meta) => {
it.each([undefined, {}])('just returns visits when no maxVisits is provided', (meta) => {
const visitsCount = 45;
const wrapper = createWrapper(visitsCount, Mock.of<ShortUrl>({ meta }));
const maxVisitsHelper = wrapper.find('.short-urls-visits-count__max-visits-control');

View File

@@ -18,7 +18,7 @@ describe('<ShortUrlsRow />', () => {
const mockFunction = () => null;
const ShortUrlsRowMenu = mockFunction;
const stateFlagTimeout = jest.fn(() => true);
const useStateFlagTimeout = jest.fn(() => [ false, stateFlagTimeout ]) as StateFlagTimeout;
const useStateFlagTimeout = jest.fn(() => [false, stateFlagTimeout]) as StateFlagTimeout;
const colorGenerator = Mock.of<ColorGenerator>({
getColorForKey: jest.fn(),
setColorForKey: jest.fn(),
@@ -29,7 +29,7 @@ describe('<ShortUrlsRow />', () => {
shortUrl: 'http://doma.in/abc123',
longUrl: 'http://foo.com/bar',
dateCreated: formatISO(parseDate('2018-05-23 18:30:41', 'yyyy-MM-dd HH:mm:ss')),
tags: [ 'nodejs', 'reactjs' ],
tags: ['nodejs', 'reactjs'],
visitsCount: 45,
domain: null,
meta: {
@@ -51,9 +51,9 @@ describe('<ShortUrlsRow />', () => {
afterEach(() => wrapper.unmount());
it.each([
[ null, 6 ],
[ undefined, 6 ],
[ 'The title', 7 ],
[null, 6],
[undefined, 6],
['The title', 7],
])('renders expected amount of columns', (title, expectedAmount) => {
const wrapper = createWrapper(title);
const cols = wrapper.find('td');

View File

@@ -60,7 +60,7 @@ describe('shortUrlDeletionReducer', () => {
});
it.each(
[[ undefined ], [ null ], [ 'example.com' ]],
[[undefined], [null], ['example.com']],
)('dispatches proper actions if API client request succeeds', async (domain) => {
const apiClientMock = Mock.of<ShlinkApiClient>({
deleteShortUrl: jest.fn(() => ''),

View File

@@ -62,8 +62,8 @@ describe('shortUrlDetailReducer', () => {
});
it.each([
[ undefined ],
[ Mock.all<ShortUrlsList>() ],
[undefined],
[Mock.all<ShortUrlsList>()],
[
Mock.of<ShortUrlsList>({
shortUrls: { data: [] },
@@ -72,7 +72,7 @@ describe('shortUrlDetailReducer', () => {
[
Mock.of<ShortUrlsList>({
shortUrls: {
data: [ Mock.of<ShortUrl>({ shortCode: 'this_will_not_match' }) ],
data: [Mock.of<ShortUrl>({ shortCode: 'this_will_not_match' })],
},
}),
],
@@ -96,7 +96,7 @@ describe('shortUrlDetailReducer', () => {
dispatchMock,
buildGetState(Mock.of<ShortUrlsList>({
shortUrls: {
data: [ foundShortUrl ],
data: [foundShortUrl],
},
})),
);

View File

@@ -48,7 +48,7 @@ describe('shortUrlEditionReducer', () => {
afterEach(jest.clearAllMocks);
it.each([[ undefined ], [ null ], [ 'example.com' ]])('dispatches short URL on success', async (domain) => {
it.each([[undefined], [null], ['example.com']])('dispatches short URL on success', async (domain) => {
await editShortUrl(buildShlinkApiClient)(shortCode, domain, { longUrl })(dispatch, createGetState());
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
@@ -60,12 +60,12 @@ describe('shortUrlEditionReducer', () => {
});
it.each([
[ null, { tags: [ 'foo', 'bar' ] }, 1 ],
[ null, {}, 0 ],
[ Mock.of<ReachableServer>({ version: '2.6.0' }), {}, 0 ],
[ Mock.of<ReachableServer>({ version: '2.6.0' }), { tags: [ 'foo', 'bar' ] }, 0 ],
[ Mock.of<ReachableServer>({ version: '2.5.0' }), {}, 0 ],
[ Mock.of<ReachableServer>({ version: '2.5.0' }), { tags: [ 'foo', 'bar' ] }, 1 ],
[null, { tags: ['foo', 'bar'] }, 1],
[null, {}, 0],
[Mock.of<ReachableServer>({ version: '2.6.0' }), {}, 0],
[Mock.of<ReachableServer>({ version: '2.6.0' }), { tags: ['foo', 'bar'] }, 0],
[Mock.of<ReachableServer>({ version: '2.5.0' }), {}, 0],
[Mock.of<ReachableServer>({ version: '2.5.0' }), { tags: ['foo', 'bar'] }, 1],
])(
'sends tags separately when appropriate, based on selected server and the payload',
async (server, payload, expectedTagsCalls) => {

View File

@@ -67,11 +67,11 @@ describe('shortUrlsListReducer', () => {
});
it.each([
[[ createNewShortUrlVisit(11) ], 11 ],
[[ createNewShortUrlVisit(30) ], 30 ],
[[ createNewShortUrlVisit(20), createNewShortUrlVisit(40) ], 40 ],
[[{}], 10 ],
[[], 10 ],
[[createNewShortUrlVisit(11)], 11],
[[createNewShortUrlVisit(30)], 30],
[[createNewShortUrlVisit(20), createNewShortUrlVisit(40)], 40],
[[{}], 10],
[[], 10],
])('updates visits count on CREATE_VISITS', (createdVisits, expectedCount) => {
const state = {
shortUrls: Mock.of<ShlinkShortUrlsResponse>({
@@ -155,9 +155,9 @@ describe('shortUrlsListReducer', () => {
it.each([
((): [ShortUrl, ShortUrl[], ShortUrl[]] => {
const editedShortUrl = Mock.of<ShortUrl>({ shortCode: 'notMatching' });
const list = [ Mock.of<ShortUrl>({ shortCode: 'foo' }), Mock.of<ShortUrl>({ shortCode: 'bar' }) ];
const list = [Mock.of<ShortUrl>({ shortCode: 'foo' }), Mock.of<ShortUrl>({ shortCode: 'bar' })];
return [ editedShortUrl, list, list ];
return [editedShortUrl, list, list];
})(),
((): [ShortUrl, ShortUrl[], ShortUrl[]] => {
const editedShortUrl = Mock.of<ShortUrl>({ shortCode: 'matching', longUrl: 'new_one' });
@@ -165,9 +165,9 @@ describe('shortUrlsListReducer', () => {
Mock.of<ShortUrl>({ shortCode: 'matching', longUrl: 'old_one' }),
Mock.of<ShortUrl>({ shortCode: 'bar' }),
];
const expectedList = [ editedShortUrl, list[1] ];
const expectedList = [editedShortUrl, list[1]];
return [ editedShortUrl, list, expectedList ];
return [editedShortUrl, list, expectedList];
})(),
])('updates matching short URL on SHORT_URL_EDITED', (editedShortUrl, initialList, expectedList) => {
const state = {

View File

@@ -16,7 +16,7 @@ describe('<TagCard />', () => {
<TagCard
tag={{ tag, visits: 23257, shortUrls: 48 }}
selectedServer={Mock.of<ReachableServer>({ id: '1' })}
displayed={true}
displayed
toggle={() => {}}
/>,
);
@@ -30,8 +30,8 @@ describe('<TagCard />', () => {
afterEach(jest.resetAllMocks);
it.each([
[ 'ssr', '/server/1/list-short-urls/1?tags=ssr' ],
[ 'ssr-&-foo', '/server/1/list-short-urls/1?tags=ssr-%26-foo' ],
['ssr', '/server/1/list-short-urls/1?tags=ssr'],
['ssr-&-foo', '/server/1/list-short-urls/1?tags=ssr-%26-foo'],
])('shows a TagBullet and a link to the list filtering by the tag', (tag, expectedLink) => {
const wrapper = createWrapper(tag);
const links = wrapper.find(Link);

View File

@@ -65,7 +65,7 @@ describe('<TagsList />', () => {
});
it('renders proper component based on the display mode', () => {
const wrapper = createWrapper({ filteredTags: [ 'foo', 'bar' ], stats: {} });
const wrapper = createWrapper({ filteredTags: ['foo', 'bar'], stats: {} });
expect(wrapper.find(TagsCards)).toHaveLength(1);
expect(wrapper.find(TagsTable)).toHaveLength(0);
@@ -97,7 +97,7 @@ describe('<TagsList />', () => {
});
it('can update current order via orderByColumn from table component', () => {
const wrapper = createWrapper({ filteredTags: [ 'foo', 'bar' ], stats: {} });
const wrapper = createWrapper({ filteredTags: ['foo', 'bar'], stats: {} });
const callOrderBy = (field: TagsOrderableFields) => {
((wrapper.find(TagsTable).prop('orderByColumn') as Function)(field) as Function)();
};

View File

@@ -43,12 +43,12 @@ describe('<TagsTable />', () => {
});
it.each([
[[ 'foo', 'bar', 'baz' ], 3 ],
[[ 'foo' ], 1 ],
[ tags(19), 19 ],
[ tags(20), 20 ],
[ tags(30), 20 ],
[ tags(100), 20 ],
[['foo', 'bar', 'baz'], 3],
[['foo'], 1],
[tags(19), 19],
[tags(20), 20],
[tags(30), 20],
[tags(100), 20],
])('renders as many rows as there are in current page', (filteredTags, expectedRows) => {
const wrapper = createWrapper(filteredTags);
const tagRows = wrapper.find(TagsTableRow);
@@ -57,12 +57,12 @@ describe('<TagsTable />', () => {
});
it.each([
[[ 'foo', 'bar', 'baz' ], 0 ],
[[ 'foo' ], 0 ],
[ tags(19), 0 ],
[ tags(20), 0 ],
[ tags(30), 1 ],
[ tags(100), 1 ],
[['foo', 'bar', 'baz'], 0],
[['foo'], 0],
[tags(19), 0],
[tags(20), 0],
[tags(30), 1],
[tags(100), 1],
])('renders paginator if there are more than one page', (filteredTags, expectedPaginators) => {
const wrapper = createWrapper(filteredTags);
const paginator = wrapper.find(SimplePaginator);
@@ -71,12 +71,12 @@ describe('<TagsTable />', () => {
});
it.each([
[ 1, 20, 0 ],
[ 2, 20, 20 ],
[ 3, 20, 40 ],
[ 4, 20, 60 ],
[ 5, 7, 80 ],
[ 6, 0, 0 ],
[1, 20, 0],
[2, 20, 20],
[3, 20, 40],
[4, 20, 60],
[5, 7, 80],
[6, 0, 0],
])('renders page from query if present', (page, expectedRows, offset) => {
const wrapper = createWrapper(tags(87), `page=${page}`);
const tagRows = wrapper.find(TagsTableRow);

View File

@@ -26,8 +26,8 @@ describe('<TagsTableRow />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined, '0', '0' ],
[{ shortUrls: 10, visits: 3480 }, '10', '3,480' ],
[undefined, '0', '0'],
[{ shortUrls: 10, visits: 3480 }, '10', '3,480'],
])('shows expected tag stats', (stats, expectedShortUrls, expectedVisits) => {
const wrapper = createWrapper(stats);
const links = wrapper.find(Link);

View File

@@ -46,8 +46,8 @@ describe('<EditTagModal />', () => {
});
it.each([
[ true, 'Saving...' ],
[ false, 'Save' ],
[true, 'Saving...'],
[false, 'Save'],
])('renders submit button in expected state', (editing, expectedText) => {
const wrapper = createWrapper({ editing });
const submitBtn = wrapper.find(Button).findWhere((btn) => btn.prop('color') === 'primary');
@@ -57,8 +57,8 @@ describe('<EditTagModal />', () => {
});
it.each([
[ true, 1 ],
[ false, 0 ],
[true, 1],
[false, 0],
])('displays error result in case of error', (error, expectedResultCount) => {
const wrapper = createWrapper({ error, errorData: Mock.all<ProblemDetailsError>() });
const result = wrapper.find(Result);

View File

@@ -26,8 +26,8 @@ describe('<Tag />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ true ],
[ false ],
[true],
[false],
])('includes an extra class when the color is light', (isLight) => {
isColorLightForKey.mockReturnValue(isLight);
@@ -37,11 +37,11 @@ describe('<Tag />', () => {
});
it.each([
[ MAIN_COLOR ],
[ '#8A661C' ],
[ '#F7BE05' ],
[ '#5A02D8' ],
[ '#202786' ],
[MAIN_COLOR],
['#8A661C'],
['#F7BE05'],
['#5A02D8'],
['#202786'],
])('includes generated color as backgroundColor', (generatedColor) => {
getColorForKey.mockReturnValue(generatedColor);
@@ -64,9 +64,9 @@ describe('<Tag />', () => {
});
it.each([
[ true, 1, 'auto' ],
[ false, 0, 'pointer' ],
[ undefined, 0, 'pointer' ],
[true, 1, 'auto'],
[false, 0, 'pointer'],
[undefined, 0, 'pointer'],
])('includes a close component when the tag is clearable', (clearable, expectedCloseBtnAmount, expectedCursor) => {
const wrapper = createWrapper('foo', clearable);
@@ -75,8 +75,8 @@ describe('<Tag />', () => {
});
it.each([
[ undefined, 'foo' ],
[ 'bar', 'bar' ],
[undefined, 'foo'],
['bar', 'bar'],
])('falls back to text as children when no children are provided', (children, expectedChildren) => {
const wrapper = createWrapper('foo', false, children);

View File

@@ -8,8 +8,8 @@ import { Settings } from '../../../src/settings/reducers/settings';
describe('<TagsSelector />', () => {
const onChange = jest.fn();
const TagsSelector = createTagsSelector(Mock.all<ColorGenerator>());
const tags = [ 'foo', 'bar' ];
const tagsList = Mock.of<TagsList>({ tags: [ ...tags, 'baz' ] });
const tags = ['foo', 'bar'];
const tagsList = Mock.of<TagsList>({ tags: [...tags, 'baz'] });
let wrapper: ShallowWrapper;
beforeEach(jest.clearAllMocks);
@@ -57,9 +57,9 @@ describe('<TagsSelector />', () => {
});
it.each([
[ 'The-New-Tag', [ ...tags, 'the-new-tag' ]],
[ 'comma,separated,tags', [ ...tags, 'comma', 'separated', 'tags' ]],
[ 'foo', tags ],
['The-New-Tag', [...tags, 'the-new-tag']],
['comma,separated,tags', [...tags, 'comma', 'separated', 'tags']],
['foo', tags],
])('invokes onChange when new tags are added', (newTag, expectedTags) => {
wrapper.simulate('addition', { name: newTag });
@@ -67,11 +67,11 @@ describe('<TagsSelector />', () => {
});
it.each([
[ 0, 'bar' ],
[ 1, 'foo' ],
[0, 'bar'],
[1, 'foo'],
])('invokes onChange when tags are deleted', (index, expected) => {
wrapper.simulate('delete', index);
expect(onChange).toHaveBeenCalledWith([ expected ]);
expect(onChange).toHaveBeenCalledWith([expected]);
});
});

View File

@@ -59,7 +59,7 @@ describe('tagDeleteReducer', () => {
await dispatchable(dispatch, getState);
expect(apiClientMock.deleteTags).toHaveBeenCalledTimes(1);
expect(apiClientMock.deleteTags).toHaveBeenNthCalledWith(1, [ tag ]);
expect(apiClientMock.deleteTags).toHaveBeenNthCalledWith(1, [tag]);
expect(dispatch).toHaveBeenCalledTimes(2);
expect(dispatch).toHaveBeenNthCalledWith(1, { type: DELETE_TAG_START });
@@ -79,7 +79,7 @@ describe('tagDeleteReducer', () => {
}
expect(apiClientMock.deleteTags).toHaveBeenCalledTimes(1);
expect(apiClientMock.deleteTags).toHaveBeenNthCalledWith(1, [ tag ]);
expect(apiClientMock.deleteTags).toHaveBeenNthCalledWith(1, [tag]);
expect(dispatch).toHaveBeenCalledTimes(2);
expect(dispatch).toHaveBeenNthCalledWith(1, { type: DELETE_TAG_START });

View File

@@ -33,7 +33,7 @@ describe('tagsListReducer', () => {
});
it('returns provided tags as filtered and regular tags on LIST_TAGS', () => {
const tags = [ 'foo', 'bar', 'baz' ];
const tags = ['foo', 'bar', 'baz'];
expect(reducer(undefined, { type: LIST_TAGS, tags } as any)).toEqual({
tags,
@@ -44,9 +44,9 @@ describe('tagsListReducer', () => {
});
it('removes provided tag from filtered and regular tags on TAG_DELETED', () => {
const tags = [ 'foo', 'bar', 'baz' ];
const tags = ['foo', 'bar', 'baz'];
const tag = 'foo';
const expectedTags = [ 'bar', 'baz' ];
const expectedTags = ['bar', 'baz'];
expect(reducer(state({ tags, filteredTags: tags }), { type: TAG_DELETED, tag } as any)).toEqual({
tags: expectedTags,
@@ -55,10 +55,10 @@ describe('tagsListReducer', () => {
});
it('renames provided tag from filtered and regular tags on TAG_EDITED', () => {
const tags = [ 'foo', 'bar', 'baz' ];
const tags = ['foo', 'bar', 'baz'];
const oldName = 'bar';
const newName = 'renamed';
const expectedTags = [ 'foo', 'renamed', 'baz' ].sort();
const expectedTags = ['foo', 'renamed', 'baz'].sort();
expect(reducer(state({ tags, filteredTags: tags }), { type: TAG_EDITED, oldName, newName } as any)).toEqual({
tags: expectedTags,
@@ -67,9 +67,9 @@ describe('tagsListReducer', () => {
});
it('filters original list of tags by provided search term on FILTER_TAGS', () => {
const tags = [ 'foo', 'bar', 'baz', 'foo2', 'fo' ];
const tags = ['foo', 'bar', 'baz', 'foo2', 'fo'];
const searchTerm = 'fo';
const filteredTags = [ 'foo', 'foo2', 'fo' ];
const filteredTags = ['foo', 'foo2', 'fo'];
expect(reducer(state({ tags }), { type: FILTER_TAGS, searchTerm } as any)).toEqual({
tags,
@@ -78,11 +78,11 @@ describe('tagsListReducer', () => {
});
it.each([
[[ 'foo', 'foo3', 'bar3', 'fo' ], [ 'foo', 'bar', 'baz', 'foo2', 'fo', 'foo3', 'bar3' ]],
[[ 'foo', 'bar' ], [ 'foo', 'bar', 'baz', 'foo2', 'fo' ]],
[[ 'new', 'tag' ], [ 'foo', 'bar', 'baz', 'foo2', 'fo', 'new', 'tag' ]],
[['foo', 'foo3', 'bar3', 'fo'], ['foo', 'bar', 'baz', 'foo2', 'fo', 'foo3', 'bar3']],
[['foo', 'bar'], ['foo', 'bar', 'baz', 'foo2', 'fo']],
[['new', 'tag'], ['foo', 'bar', 'baz', 'foo2', 'fo', 'new', 'tag']],
])('appends new short URL\'s tags to the list of tags on CREATE_SHORT_URL', (shortUrlTags, expectedTags) => {
const tags = [ 'foo', 'bar', 'baz', 'foo2', 'fo' ];
const tags = ['foo', 'bar', 'baz', 'foo2', 'fo'];
const result = Mock.of<ShortUrl>({ tags: shortUrlTags });
expect(reducer(state({ tags }), { type: CREATE_SHORT_URL, result } as any)).toEqual({
@@ -116,11 +116,11 @@ describe('tagsListReducer', () => {
it('does nothing when loading', async () => assertNoAction(state({ loading: true })));
it(
'does nothing when list is not empty',
async () => assertNoAction(state({ loading: false, tags: [ 'foo', 'bar' ] })),
async () => assertNoAction(state({ loading: false, tags: ['foo', 'bar'] })),
);
it('dispatches loaded lists when no error occurs', async () => {
const tags = [ 'foo', 'bar', 'baz' ];
const tags = ['foo', 'bar', 'baz'];
listTagsMock.mockResolvedValue({ tags, stats: [] });
buildShlinkApiClient.mockReturnValue({ listTags: listTagsMock });

View File

@@ -16,7 +16,7 @@ describe('<Checkbox />', () => {
afterEach(() => wrapped?.unmount());
it('includes extra class names when provided', () => {
const classNames = [ 'foo', 'bar', 'baz' ];
const classNames = ['foo', 'bar', 'baz'];
expect.assertions(classNames.length);
classNames.forEach((className) => {
@@ -27,7 +27,7 @@ describe('<Checkbox />', () => {
});
it('marks input as checked if defined', () => {
const checkeds = [ true, false ];
const checkeds = [true, false];
expect.assertions(checkeds.length);
checkeds.forEach((checked) => {
@@ -39,7 +39,7 @@ describe('<Checkbox />', () => {
});
it('renders provided children inside the label', () => {
const labels = [ 'foo', 'bar', 'baz' ];
const labels = ['foo', 'bar', 'baz'];
expect.assertions(labels.length);
labels.forEach((children) => {

View File

@@ -6,21 +6,21 @@ import { DropdownBtn, DropdownBtnProps } from '../../src/utils/DropdownBtn';
describe('<DropdownBtn />', () => {
let wrapper: ShallowWrapper;
const createWrapper = (props: PropsWithChildren<DropdownBtnProps>) => {
wrapper = shallow(<DropdownBtn children={'foo'} {...props} />);
wrapper = shallow(<DropdownBtn children="foo" {...props} />);
return wrapper;
};
afterEach(() => wrapper?.unmount());
it.each([[ 'foo' ], [ 'bar' ], [ 'baz' ]])('displays provided text', (text) => {
it.each([['foo'], ['bar'], ['baz']])('displays provided text', (text) => {
const wrapper = createWrapper({ text });
const toggle = wrapper.find(DropdownToggle);
expect(toggle.prop('children')).toContain(text);
});
it.each([[ 'foo' ], [ 'bar' ], [ 'baz' ]])('displays provided children', (children) => {
it.each([['foo'], ['bar'], ['baz']])('displays provided children', (children) => {
const wrapper = createWrapper({ text: '', children });
const menu = wrapper.find(DropdownMenu);
@@ -28,10 +28,10 @@ describe('<DropdownBtn />', () => {
});
it.each([
[ undefined, 'dropdown-btn__toggle btn-block' ],
[ '', 'dropdown-btn__toggle btn-block' ],
[ 'foo', 'dropdown-btn__toggle btn-block foo' ],
[ 'bar', 'dropdown-btn__toggle btn-block bar' ],
[undefined, 'dropdown-btn__toggle btn-block'],
['', 'dropdown-btn__toggle btn-block'],
['foo', 'dropdown-btn__toggle btn-block foo'],
['bar', 'dropdown-btn__toggle btn-block bar'],
])('includes provided classes', (className, expectedClasses) => {
const wrapper = createWrapper({ text: '', className });
const toggle = wrapper.find(DropdownToggle);
@@ -40,9 +40,9 @@ describe('<DropdownBtn />', () => {
});
it.each([
[ 100, { minWidth: '100px' }],
[ 250, { minWidth: '250px' }],
[ undefined, {}],
[100, { minWidth: '100px' }],
[250, { minWidth: '250px' }],
[undefined, {}],
])('renders proper styles when minWidth is provided', (minWidth, expectedStyle) => {
const wrapper = createWrapper({ text: '', minWidth });
const style = wrapper.find(DropdownMenu).prop('style');

View File

@@ -37,9 +37,9 @@ describe('<DropdownBtnMenu />', () => {
});
it.each([
[ undefined, true ],
[ true, true ],
[ false, false ],
[undefined, true],
[true, true],
[false, false],
])('renders menu to right when expected', (right, expectedRight) => {
const wrapper = createWrapper({ right });

View File

@@ -15,8 +15,8 @@ describe('<ExportBtn />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ true, 'Exporting...' ],
[ false, 'Export (' ],
[true, 'Exporting...'],
[false, 'Export ('],
])('renders a button', (loading, text) => {
const wrapper = createWrapper(undefined, loading);
@@ -27,10 +27,10 @@ describe('<ExportBtn />', () => {
});
it.each([
[ undefined, '0' ],
[ 10, '10' ],
[ 10_000, '10,000' ],
[ 10_000_000, '10,000,000' ],
[undefined, '0'],
[10, '10'],
[10_000, '10,000'],
[10_000_000, '10,000,000'],
])('renders expected amount', (amount, expectedRenderedAmount) => {
const wrapper = createWrapper(amount);

View File

@@ -5,9 +5,9 @@ import { InfoTooltip } from '../../src/utils/InfoTooltip';
describe('<InfoTooltip />', () => {
it.each([
[ undefined ],
[ 'foo' ],
[ 'bar' ],
[undefined],
['foo'],
['bar'],
])('renders expected className on span', (className) => {
const wrapper = shallow(<InfoTooltip placement="right" className={className} />);
const span = wrapper.find('span');
@@ -16,10 +16,10 @@ describe('<InfoTooltip />', () => {
});
it.each([
[ <span key={1} /> ],
[ 'Foo' ],
[ 'Hello' ],
[[ 'One', 'Two', <span key={3} /> ]],
[<span key={1} />],
['Foo'],
['Hello'],
[['One', 'Two', <span key={3} />]],
])('passes children down to the nested tooltip component', (children) => {
const wrapper = shallow(<InfoTooltip placement="right">{children}</InfoTooltip>);
const tooltip = wrapper.find(UncontrolledTooltip);
@@ -28,10 +28,10 @@ describe('<InfoTooltip />', () => {
});
it.each([
[ 'right' as Placement ],
[ 'left' as Placement ],
[ 'top' as Placement ],
[ 'bottom' as Placement ],
['right' as Placement],
['left' as Placement],
['top' as Placement],
['bottom' as Placement],
])('places tooltip where requested', (placement) => {
const wrapper = shallow(<InfoTooltip placement={placement} />);
const tooltip = wrapper.find(UncontrolledTooltip);

View File

@@ -15,9 +15,9 @@ describe('<Message />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ true, 1, 0 ],
[ false, 0, 1 ],
[ undefined, 0, 1 ],
[true, 1, 0],
[false, 0, 1],
[undefined, 0, 1],
])('renders expected classes based on width', (fullWidth, expectedFull, expectedNonFull) => {
const wrapper = createWrapper({ fullWidth });
@@ -26,27 +26,27 @@ describe('<Message />', () => {
});
it.each([
[ true, 'These are the children contents' ],
[ false, 'These are the children contents' ],
[ true, undefined ],
[ false, undefined ],
[true, 'These are the children contents'],
[false, 'These are the children contents'],
[true, undefined],
[false, undefined],
])('renders expected content', (loading, children) => {
const wrapper = createWrapper({ loading, children });
expect(wrapper.find(FontAwesomeIcon)).toHaveLength(loading ? 1 : 0);
if (loading) {
expect(wrapper.find('span').text()).toContain(children ? children : 'Loading...');
expect(wrapper.find('span').text()).toContain(children || 'Loading...');
} else {
expect(wrapper.find('span')).toHaveLength(0);
expect(wrapper.find('h3').text()).toContain(children ? children : '');
expect(wrapper.find('h3').text()).toContain(children || '');
}
});
it.each([
[ 'error', 'border-danger', 'text-danger' ],
[ 'default', '', 'text-muted' ],
[ undefined, '', 'text-muted' ],
['error', 'border-danger', 'text-danger'],
['default', '', 'text-muted'],
[undefined, '', 'text-muted'],
])('renders proper classes based on message type', (type, expectedCardClass, expectedH3Class) => {
const wrapper = createWrapper({ type: type as 'default' | 'error' | undefined });
const card = wrapper.find(Card);

View File

@@ -4,9 +4,9 @@ import { NavPillItem, NavPills } from '../../src/utils/NavPills';
describe('<NavPills />', () => {
it.each([
[ 'Foo' ],
[ <span key="1">Hi!</span> ],
[[ <NavPillItem key="1" to="" />, <span key="2">Hi!</span> ]],
['Foo'],
[<span key="1">Hi!</span>],
[[<NavPillItem key="1" to="" />, <span key="2">Hi!</span>]],
])('throws error when any of the children is not a NavPillItem', (children) => {
expect.assertions(1);
@@ -18,9 +18,9 @@ describe('<NavPills />', () => {
});
it.each([
[ undefined ],
[ true ],
[ false ],
[undefined],
[true],
[false],
])('renders provided items', (fill) => {
const wrapper = shallow(
<NavPills fill={fill}>

View File

@@ -7,7 +7,7 @@ describe('<PaginationDropdown />', () => {
let wrapper: ShallowWrapper;
beforeEach(() => {
wrapper = shallow(<PaginationDropdown ranges={[ 10, 50, 100, 200 ]} value={50} setValue={setValue} />);
wrapper = shallow(<PaginationDropdown ranges={[10, 50, 100, 200]} value={50} setValue={setValue} />);
});
afterEach(jest.clearAllMocks);
@@ -20,11 +20,11 @@ describe('<PaginationDropdown />', () => {
});
it.each([
[ 0, 10 ],
[ 1, 50 ],
[ 2, 100 ],
[ 3, 200 ],
[ 5, Infinity ],
[0, 10],
[1, 50],
[2, 100],
[3, 200],
[5, Infinity],
])('sets expected value when an item is clicked', (index, expectedValue) => {
const item = wrapper.find(DropdownItem).at(index);

View File

@@ -13,9 +13,9 @@ describe('<Result />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ 'success' as ResultType, 'bg-main text-white' ],
[ 'error' as ResultType, 'bg-danger text-white' ],
[ 'warning' as ResultType, 'bg-warning' ],
['success' as ResultType, 'bg-main text-white'],
['error' as ResultType, 'bg-danger text-white'],
['warning' as ResultType, 'bg-warning'],
])('renders expected classes based on type', (type, expectedClasses) => {
const wrapper = createWrapper({ type });
const innerCard = wrapper.find(SimpleCard);
@@ -24,9 +24,9 @@ describe('<Result />', () => {
});
it.each([
[ undefined ],
[ 'foo' ],
[ 'bar' ],
[undefined],
['foo'],
['bar'],
])('renders provided classes in root element', (className) => {
const wrapper = createWrapper({ type: 'success', className });

View File

@@ -4,8 +4,8 @@ import { SimpleCard } from '../../src/utils/SimpleCard';
describe('<SimpleCard />', () => {
it.each([
[{}, 0 ],
[{ title: 'Cool title' }, 1 ],
[{}, 0],
[{ title: 'Cool title' }, 1],
])('renders header only if title is provided', (props, expectedAmountOfHeaders) => {
const wrapper = shallow(<SimpleCard {...props} />);

View File

@@ -76,8 +76,8 @@ describe('<SortingDropdown />', () => {
});
it.each([
[{ isButton: false }, <>Order by</> ],
[{ isButton: true }, <>Order by...</> ],
[{ isButton: false }, <>Order by</>],
[{ isButton: true }, <>Order by...</>],
[
{ isButton: true, order: { field: 'foo', dir: 'ASC' as OrderDir } },
'Order by: "Foo" - "ASC"',
@@ -86,11 +86,11 @@ describe('<SortingDropdown />', () => {
{ isButton: true, order: { field: 'baz', dir: 'DESC' as OrderDir } },
'Order by: "Hello World" - "DESC"',
],
[{ isButton: true, order: { field: 'baz' } }, 'Order by: "Hello World" - "DESC"' ],
[{ isButton: true, order: { field: 'baz' } }, 'Order by: "Hello World" - "DESC"'],
])('displays expected text in toggle', (props, expectedText) => {
const wrapper = createWrapper(props);
const toggle = wrapper.find(DropdownToggle);
const [ children ] = (toggle.prop('children') as any[]).filter(Boolean);
const [children] = (toggle.prop('children') as any[]).filter(Boolean);
expect(children).toEqual(expectedText);
});

View File

@@ -13,8 +13,8 @@ describe('<Time />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[{ date: parseDate('2020-05-05', 'yyyy-MM-dd') }, '1588636800000', '2020-05-05 00:00' ],
[{ date: parseDate('2021-03-20', 'yyyy-MM-dd'), format: 'dd/MM/yyyy' }, '1616198400000', '20/03/2021' ],
[{ date: parseDate('2020-05-05', 'yyyy-MM-dd') }, '1588636800000', '2020-05-05 00:00'],
[{ date: parseDate('2021-03-20', 'yyyy-MM-dd'), format: 'dd/MM/yyyy' }, '1616198400000', '20/03/2021'],
])('includes expected dateTime and format', (props, expectedDateTime, expectedFormatted) => {
const wrapper = createWrapper(props);

View File

@@ -15,9 +15,9 @@ describe('<TooltipToggleSwitch />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'baz' ],
['foo'],
['bar'],
['baz'],
])('shows children inside tooltip', (children) => {
const wrapper = createWrapper({ children });
const tooltip = wrapper.find(UncontrolledTooltip);

View File

@@ -37,16 +37,16 @@ describe('<DateRangeSelector />', () => {
});
it.each([
[ undefined, 0 ],
[ 'all' as DateInterval, 1 ],
[ 'today' as DateInterval, 1 ],
[ 'yesterday' as DateInterval, 1 ],
[ 'last7Days' as DateInterval, 1 ],
[ 'last30Days' as DateInterval, 1 ],
[ 'last90Days' as DateInterval, 1 ],
[ 'last180Days' as DateInterval, 1 ],
[ 'last365Days' as DateInterval, 1 ],
[{ startDate: new Date() }, 0 ],
[undefined, 0],
['all' as DateInterval, 1],
['today' as DateInterval, 1],
['yesterday' as DateInterval, 1],
['last7Days' as DateInterval, 1],
['last30Days' as DateInterval, 1],
['last90Days' as DateInterval, 1],
['last180Days' as DateInterval, 1],
['last365Days' as DateInterval, 1],
[{ startDate: new Date() }, 0],
])('sets proper element as active based on provided date range', (initialDateRange, expectedActiveIntervalItems) => {
const wrapper = createWrapper({ initialDateRange });
const dateIntervalItems = wrapper.find(DateIntervalDropdownItems).filterWhere(

View File

@@ -15,19 +15,19 @@ describe('date-types', () => {
describe('dateRangeIsEmpty', () => {
it.each([
[ undefined, true ],
[{}, true ],
[{ startDate: null }, true ],
[{ endDate: null }, true ],
[{ startDate: null, endDate: null }, true ],
[{ startDate: undefined }, true ],
[{ endDate: undefined }, true ],
[{ startDate: undefined, endDate: undefined }, true ],
[{ startDate: undefined, endDate: null }, true ],
[{ startDate: null, endDate: undefined }, true ],
[{ startDate: new Date() }, false ],
[{ endDate: new Date() }, false ],
[{ startDate: new Date(), endDate: new Date() }, false ],
[undefined, true],
[{}, true],
[{ startDate: null }, true],
[{ endDate: null }, true],
[{ startDate: null, endDate: null }, true],
[{ startDate: undefined }, true],
[{ endDate: undefined }, true],
[{ startDate: undefined, endDate: undefined }, true],
[{ startDate: undefined, endDate: null }, true],
[{ startDate: null, endDate: undefined }, true],
[{ startDate: new Date() }, false],
[{ endDate: new Date() }, false],
[{ startDate: new Date(), endDate: new Date() }, false],
])('returns proper result', (dateRange, expectedResult) => {
expect(dateRangeIsEmpty(dateRange)).toEqual(expectedResult);
});
@@ -35,10 +35,10 @@ describe('date-types', () => {
describe('rangeIsInterval', () => {
it.each([
[ undefined, false ],
[{}, false ],
[ 'today' as DateInterval, true ],
[ 'yesterday' as DateInterval, true ],
[undefined, false],
[{}, false],
['today' as DateInterval, true],
['yesterday' as DateInterval, true],
])('returns proper result', (range, expectedResult) => {
expect(rangeIsInterval(range)).toEqual(expectedResult);
});
@@ -46,25 +46,25 @@ describe('date-types', () => {
describe('rangeOrIntervalToString', () => {
it.each([
[ undefined, undefined ],
[ 'today' as DateInterval, 'Today' ],
[ 'yesterday' as DateInterval, 'Yesterday' ],
[ 'last7Days' as DateInterval, 'Last 7 days' ],
[ 'last30Days' as DateInterval, 'Last 30 days' ],
[ 'last90Days' as DateInterval, 'Last 90 days' ],
[ 'last180Days' as DateInterval, 'Last 180 days' ],
[ 'last365Days' as DateInterval, 'Last 365 days' ],
[{}, undefined ],
[{ startDate: null }, undefined ],
[{ endDate: null }, undefined ],
[{ startDate: null, endDate: null }, undefined ],
[{ startDate: undefined }, undefined ],
[{ endDate: undefined }, undefined ],
[{ startDate: undefined, endDate: undefined }, undefined ],
[{ startDate: undefined, endDate: null }, undefined ],
[{ startDate: null, endDate: undefined }, undefined ],
[{ startDate: parseDate('2020-01-01', 'yyyy-MM-dd') }, 'Since 2020-01-01' ],
[{ endDate: parseDate('2020-01-01', 'yyyy-MM-dd') }, 'Until 2020-01-01' ],
[undefined, undefined],
['today' as DateInterval, 'Today'],
['yesterday' as DateInterval, 'Yesterday'],
['last7Days' as DateInterval, 'Last 7 days'],
['last30Days' as DateInterval, 'Last 30 days'],
['last90Days' as DateInterval, 'Last 90 days'],
['last180Days' as DateInterval, 'Last 180 days'],
['last365Days' as DateInterval, 'Last 365 days'],
[{}, undefined],
[{ startDate: null }, undefined],
[{ endDate: null }, undefined],
[{ startDate: null, endDate: null }, undefined],
[{ startDate: undefined }, undefined],
[{ endDate: undefined }, undefined],
[{ startDate: undefined, endDate: undefined }, undefined],
[{ startDate: undefined, endDate: null }, undefined],
[{ startDate: null, endDate: undefined }, undefined],
[{ startDate: parseDate('2020-01-01', 'yyyy-MM-dd') }, 'Since 2020-01-01'],
[{ endDate: parseDate('2020-01-01', 'yyyy-MM-dd') }, 'Until 2020-01-01'],
[
{ startDate: parseDate('2020-01-01', 'yyyy-MM-dd'), endDate: parseDate('2021-02-02', 'yyyy-MM-dd') },
'2020-01-01 - 2021-02-02',
@@ -75,17 +75,17 @@ describe('date-types', () => {
});
describe('intervalToDateRange', () => {
const formatted = (date?: Date | null): string | undefined => !date ? undefined : format(date, 'yyyy-MM-dd');
const formatted = (date?: Date | null): string | undefined => (!date ? undefined : format(date, 'yyyy-MM-dd'));
it.each([
[ undefined, undefined, undefined ],
[ 'today' as DateInterval, now(), now() ],
[ 'yesterday' as DateInterval, daysBack(1), daysBack(1) ],
[ 'last7Days' as DateInterval, daysBack(7), now() ],
[ 'last30Days' as DateInterval, daysBack(30), now() ],
[ 'last90Days' as DateInterval, daysBack(90), now() ],
[ 'last180Days' as DateInterval, daysBack(180), now() ],
[ 'last365Days' as DateInterval, daysBack(365), now() ],
[undefined, undefined, undefined],
['today' as DateInterval, now(), now()],
['yesterday' as DateInterval, daysBack(1), daysBack(1)],
['last7Days' as DateInterval, daysBack(7), now()],
['last30Days' as DateInterval, daysBack(30), now()],
['last90Days' as DateInterval, daysBack(90), now()],
['last180Days' as DateInterval, daysBack(180), now()],
['last365Days' as DateInterval, daysBack(365), now()],
])('returns proper result', (interval, expectedStartDate, expectedEndDate) => {
const { startDate, endDate } = intervalToDateRange(interval);
@@ -96,22 +96,22 @@ describe('date-types', () => {
describe('dateToMatchingInterval', () => {
it.each([
[ startOfDay(now()), 'today' ],
[ now(), 'today' ],
[ formatISO(now()), 'today' ],
[ daysBack(1), 'yesterday' ],
[ endOfDay(daysBack(1)), 'yesterday' ],
[ daysBack(2), 'last7Days' ],
[ daysBack(7), 'last7Days' ],
[ startOfDay(daysBack(7)), 'last7Days' ],
[ daysBack(18), 'last30Days' ],
[ daysBack(29), 'last30Days' ],
[ daysBack(58), 'last90Days' ],
[ startOfDay(daysBack(90)), 'last90Days' ],
[ daysBack(120), 'last180Days' ],
[ daysBack(250), 'last365Days' ],
[ daysBack(366), 'all' ],
[ formatISO(daysBack(500)), 'all' ],
[startOfDay(now()), 'today'],
[now(), 'today'],
[formatISO(now()), 'today'],
[daysBack(1), 'yesterday'],
[endOfDay(daysBack(1)), 'yesterday'],
[daysBack(2), 'last7Days'],
[daysBack(7), 'last7Days'],
[startOfDay(daysBack(7)), 'last7Days'],
[daysBack(18), 'last30Days'],
[daysBack(29), 'last30Days'],
[daysBack(58), 'last90Days'],
[startOfDay(daysBack(90)), 'last90Days'],
[daysBack(120), 'last180Days'],
[daysBack(250), 'last365Days'],
[daysBack(366), 'all'],
[formatISO(daysBack(500)), 'all'],
])('returns the first interval which contains provided date', (date, expectedInterval) => {
expect(dateToMatchingInterval(date)).toEqual(expectedInterval);
});

View File

@@ -6,13 +6,13 @@ describe('date', () => {
describe('formatDate', () => {
it.each([
[ parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'), 'dd/MM/yyyy', '05/03/2020' ],
[ parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'), 'yyyy-MM', '2020-03' ],
[ parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'), undefined, '2020-03-05' ],
[ '2020-03-05 10:00:10', 'dd-MM-yyyy', '2020-03-05 10:00:10' ],
[ '2020-03-05 10:00:10', undefined, '2020-03-05 10:00:10' ],
[ undefined, undefined, undefined ],
[ null, undefined, null ],
[parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'), 'dd/MM/yyyy', '05/03/2020'],
[parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'), 'yyyy-MM', '2020-03'],
[parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'), undefined, '2020-03-05'],
['2020-03-05 10:00:10', 'dd-MM-yyyy', '2020-03-05 10:00:10'],
['2020-03-05 10:00:10', undefined, '2020-03-05 10:00:10'],
[undefined, undefined, undefined],
[null, undefined, null],
])('formats date as expected', (date, format, expected) => {
expect(formatDate(format)(date)).toEqual(expected);
});
@@ -24,10 +24,10 @@ describe('date', () => {
parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss'),
formatISO(parseDate('2020-03-05 10:00:10', 'yyyy-MM-dd HH:mm:ss')),
],
[ '2020-03-05 10:00:10', '2020-03-05 10:00:10' ],
[ 'foo', 'foo' ],
[ undefined, undefined ],
[ null, null ],
['2020-03-05 10:00:10', '2020-03-05 10:00:10'],
['foo', 'foo'],
[undefined, undefined],
[null, null],
])('formats date as expected', (date, expected) => {
expect(formatIsoDate(date)).toEqual(expected);
});
@@ -35,17 +35,17 @@ describe('date', () => {
describe('isBetween', () => {
it.each([
[ now, undefined, undefined, true ],
[ now, subDays(now, 1), undefined, true ],
[ now, now, undefined, true ],
[ now, undefined, addDays(now, 1), true ],
[ now, undefined, now, true ],
[ now, subDays(now, 1), addDays(now, 1), true ],
[ now, now, now, true ],
[ now, addDays(now, 1), undefined, false ],
[ now, undefined, subDays(now, 1), false ],
[ now, subDays(now, 3), subDays(now, 1), false ],
[ now, addDays(now, 1), addDays(now, 3), false ],
[now, undefined, undefined, true],
[now, subDays(now, 1), undefined, true],
[now, now, undefined, true],
[now, undefined, addDays(now, 1), true],
[now, undefined, now, true],
[now, subDays(now, 1), addDays(now, 1), true],
[now, now, now, true],
[now, addDays(now, 1), undefined, false],
[now, undefined, subDays(now, 1), false],
[now, subDays(now, 3), subDays(now, 1), false],
[now, addDays(now, 1), addDays(now, 3), false],
])('returns true when a date is between provided range', (date, start, end, expectedResult) => {
expect(isBetween(date, start, end)).toEqual(expectedResult);
});
@@ -53,9 +53,9 @@ describe('date', () => {
describe('isBeforeOrEqual', () => {
it.each([
[ now, now, true ],
[ now, addDays(now, 1), true ],
[ now, subDays(now, 1), false ],
[now, now, true],
[now, addDays(now, 1), true],
[now, subDays(now, 1), false],
])('returns true when the date before or equal to provided one', (date, dateToCompare, expectedResult) => {
expect(isBeforeOrEqual(date, dateToCompare)).toEqual(expectedResult);
});

View File

@@ -4,15 +4,15 @@ describe('numbers', () => {
describe('roundTen', () => {
it('rounds provided number to the next multiple of ten', () => {
const expectationsPairs = [
[ 10, 10 ],
[ 12, 20 ],
[ 158, 160 ],
[ 5, 10 ],
[ -42, -40 ],
[10, 10],
[12, 20],
[158, 160],
[5, 10],
[-42, -40],
];
expect.assertions(expectationsPairs.length);
expectationsPairs.forEach(([ number, expected ]) => {
expectationsPairs.forEach(([number, expected]) => {
expect(roundTen(number)).toEqual(expected);
});
});

View File

@@ -25,10 +25,10 @@ describe('ordering', () => {
describe('orderToString', () => {
it.each([
[{}, undefined ],
[{ field: 'foo' }, undefined ],
[{ field: 'foo', dir: 'ASC' as OrderDir }, 'foo-ASC' ],
[{ field: 'bar', dir: 'DESC' as OrderDir }, 'bar-DESC' ],
[{}, undefined],
[{ field: 'foo' }, undefined],
[{ field: 'foo', dir: 'ASC' as OrderDir }, 'foo-ASC'],
[{ field: 'bar', dir: 'DESC' as OrderDir }, 'bar-DESC'],
])('casts the order to string', (order, expectedResult) => {
expect(orderToString(order)).toEqual(expectedResult);
});
@@ -36,8 +36,8 @@ describe('ordering', () => {
describe('stringToOrder', () => {
it.each([
[ 'foo-ASC', { field: 'foo', dir: 'ASC' }],
[ 'bar-DESC', { field: 'bar', dir: 'DESC' }],
['foo-ASC', { field: 'foo', dir: 'ASC' }],
['bar-DESC', { field: 'bar', dir: 'DESC' }],
])('casts a string to an order objects', (order, expectedResult) => {
expect(stringToOrder(order)).toEqual(expectedResult);
});

View File

@@ -3,10 +3,10 @@ import { parseQuery, stringifyQuery } from '../../../src/utils/helpers/query';
describe('query', () => {
describe('parseQuery', () => {
it.each([
[ '', {}],
[ 'foo=bar', { foo: 'bar' }],
[ '?foo=bar', { foo: 'bar' }],
[ '?foo=bar&baz=123', { foo: 'bar', baz: '123' }],
['', {}],
['foo=bar', { foo: 'bar' }],
['?foo=bar', { foo: 'bar' }],
['?foo=bar&baz=123', { foo: 'bar', baz: '123' }],
])('parses query string as expected', (queryString, expectedResult) => {
expect(parseQuery(queryString)).toEqual(expectedResult);
});
@@ -14,10 +14,10 @@ describe('query', () => {
describe('stringifyQuery', () => {
it.each([
[{}, '' ],
[{ foo: 'bar' }, 'foo=bar' ],
[{ foo: 'bar', baz: '123' }, 'foo=bar&baz=123' ],
[{ bar: 'foo', list: [ 'one', 'two' ] }, encodeURI('bar=foo&list[]=one&list[]=two') ],
[{}, ''],
[{ foo: 'bar' }, 'foo=bar'],
[{ foo: 'bar', baz: '123' }, 'foo=bar&baz=123'],
[{ bar: 'foo', list: ['one', 'two'] }, encodeURI('bar=foo&list[]=one&list[]=two')],
])('stringifies query as expected', (queryObj, expectedResult) => {
expect(stringifyQuery(queryObj)).toEqual(expectedResult);
});

View File

@@ -6,9 +6,9 @@ describe('redux', () => {
describe('buildActionCreator', () => {
it.each([
[ 'foo', { type: 'foo' }],
[ 'bar', { type: 'bar' }],
[ 'something', { type: 'something' }],
['foo', { type: 'foo' }],
['bar', { type: 'bar' }],
['something', { type: 'something' }],
])('returns an action creator', (type, expected) => {
const actionCreator = buildActionCreator(type);
@@ -37,8 +37,8 @@ describe('redux', () => {
});
it.each([
[ 'foo', 'foo result', fooActionHandler, barActionHandler ],
[ 'bar', 'bar result', barActionHandler, fooActionHandler ],
['foo', 'foo result', fooActionHandler, barActionHandler],
['bar', 'bar result', barActionHandler, fooActionHandler],
])(
'returns a reducer which calls corresponding action handler',
(type, expected, invokedActionHandler, notInvokedActionHandler) => {
@@ -49,9 +49,9 @@ describe('redux', () => {
);
it.each([
[ undefined, initialState ],
[ 'foo', 'foo' ],
[ 'something', 'something' ],
[undefined, initialState],
['foo', 'foo'],
['something', 'something'],
])('returns a reducer which calls action handler with provided state or initial', (state, expected) => {
reducer(state, { type: 'foo' });

View File

@@ -3,9 +3,9 @@ import { replaceAuthorityFromUri } from '../../../src/utils/helpers/uri';
describe('uri-helper', () => {
describe('replaceAuthorityFromUri', () => {
it.each([
[ 'http://something.com/foo/bar', 'www.new.to', 'http://www.new.to/foo/bar' ],
[ 'https://www.authori.ty:8000/', 'doma.in', 'https://doma.in/' ],
[ 'http://localhost:8080/this/is-a-long/path', 'somewhere:8888', 'http://somewhere:8888/this/is-a-long/path' ],
['http://something.com/foo/bar', 'www.new.to', 'http://www.new.to/foo/bar'],
['https://www.authori.ty:8000/', 'doma.in', 'https://doma.in/'],
['http://localhost:8080/this/is-a-long/path', 'somewhere:8888', 'http://somewhere:8888/this/is-a-long/path'],
])('replaces authority as expected', (uri, newAuthority, expectedResult) => {
expect(replaceAuthorityFromUri(uri, newAuthority)).toEqual(expectedResult);
});

View File

@@ -5,19 +5,19 @@ import { Empty } from '../../../src/utils/utils';
describe('version', () => {
describe('versionMatch', () => {
it.each([
[ undefined, Mock.all<Versions>(), false ],
[ null, Mock.all<Versions>(), false ],
[ '' as Empty, Mock.all<Versions>(), false ],
[[], Mock.all<Versions>(), false ],
[ '2.8.3' as SemVer, Mock.all<Versions>(), true ],
[ '2.8.3' as SemVer, Mock.of<Versions>({ minVersion: '2.0.0' }), true ],
[ '2.0.0' as SemVer, Mock.of<Versions>({ minVersion: '2.0.0' }), true ],
[ '1.8.0' as SemVer, Mock.of<Versions>({ maxVersion: '1.8.0' }), true ],
[ '1.7.1' as SemVer, Mock.of<Versions>({ maxVersion: '1.8.0' }), true ],
[ '1.7.3' as SemVer, Mock.of<Versions>({ minVersion: '1.7.0', maxVersion: '1.8.0' }), true ],
[ '1.8.3' as SemVer, Mock.of<Versions>({ minVersion: '2.0.0' }), false ],
[ '1.8.3' as SemVer, Mock.of<Versions>({ maxVersion: '1.8.0' }), false ],
[ '1.8.3' as SemVer, Mock.of<Versions>({ minVersion: '1.7.0', maxVersion: '1.8.0' }), false ],
[undefined, Mock.all<Versions>(), false],
[null, Mock.all<Versions>(), false],
['' as Empty, Mock.all<Versions>(), false],
[[], Mock.all<Versions>(), false],
['2.8.3' as SemVer, Mock.all<Versions>(), true],
['2.8.3' as SemVer, Mock.of<Versions>({ minVersion: '2.0.0' }), true],
['2.0.0' as SemVer, Mock.of<Versions>({ minVersion: '2.0.0' }), true],
['1.8.0' as SemVer, Mock.of<Versions>({ maxVersion: '1.8.0' }), true],
['1.7.1' as SemVer, Mock.of<Versions>({ maxVersion: '1.8.0' }), true],
['1.7.3' as SemVer, Mock.of<Versions>({ minVersion: '1.7.0', maxVersion: '1.8.0' }), true],
['1.8.3' as SemVer, Mock.of<Versions>({ minVersion: '2.0.0' }), false],
['1.8.3' as SemVer, Mock.of<Versions>({ maxVersion: '1.8.0' }), false],
['1.8.3' as SemVer, Mock.of<Versions>({ minVersion: '1.7.0', maxVersion: '1.8.0' }), false],
])('properly matches versions based on what is provided', (version, versionConstraints, expected) => {
expect(versionMatch(version, versionConstraints)).toEqual(expected);
});

View File

@@ -48,11 +48,11 @@ describe('ColorGenerator', () => {
describe('isColorLightForKey', () => {
it.each([
[ MAIN_COLOR, true ],
[ '#8A661C', false ],
[ '#F7BE05', true ],
[ '#5A02D8', false ],
[ '#202786', false ],
[MAIN_COLOR, true],
['#8A661C', false],
['#F7BE05', true],
['#5A02D8', false],
['#202786', false],
])('returns that the color for a key is light based on the color assigned to that key', (color, isLight) => {
colorGenerator.setColorForKey('foo', color);

View File

@@ -2,7 +2,7 @@ import { Mock } from 'ts-mockery';
import LocalStorage from '../../../src/utils/services/LocalStorage';
describe('LocalStorage', () => {
const getItem = jest.fn((key) => key === 'shlink.foo' ? JSON.stringify({ foo: 'bar' }) : null);
const getItem = jest.fn((key) => (key === 'shlink.foo' ? JSON.stringify({ foo: 'bar' }) : null));
const setItem = jest.fn();
const localStorageMock = Mock.of<Storage>({ getItem, setItem });
let storage: LocalStorage;

View File

@@ -16,9 +16,9 @@ describe('<TableOrderIcon />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ 'foo', undefined ],
[ 'bar', 'DESC' as OrderDir ],
[ 'bar', 'ASC' as OrderDir ],
['foo', undefined],
['bar', 'DESC' as OrderDir],
['bar', 'ASC' as OrderDir],
])('renders empty when not all conditions are met', (field, dir) => {
const wrapper = createWrapper(field, dir);
@@ -26,8 +26,8 @@ describe('<TableOrderIcon />', () => {
});
it.each([
[ 'DESC' as OrderDir, caretDownIcon ],
[ 'ASC' as OrderDir, caretUpIcon ],
['DESC' as OrderDir, caretDownIcon],
['ASC' as OrderDir, caretUpIcon],
])('renders an icon when all conditions are met', (dir, expectedIcon) => {
const wrapper = createWrapper('foo', dir);
@@ -36,9 +36,9 @@ describe('<TableOrderIcon />', () => {
});
it.each([
[ undefined, 'ms-1' ],
[ 'foo', 'foo' ],
[ 'bar', 'bar' ],
[undefined, 'ms-1'],
['foo', 'foo'],
['bar', 'bar'],
])('renders expected classname', (className, expectedClassName) => {
const wrapper = createWrapper('foo', 'ASC', className);

View File

@@ -28,11 +28,11 @@ describe('utils', () => {
describe('nonEmptyValueOrNull', () => {
it.each([
[ '', null ],
[ 'Hello', 'Hello' ],
[[], null ],
[[ 1, 2, 3 ], [ 1, 2, 3 ]],
[{}, null ],
['', null],
['Hello', 'Hello'],
[[], null],
[[1, 2, 3], [1, 2, 3]],
[{}, null],
[{ foo: 'bar' }, { foo: 'bar' }],
])('returns expected value based on input', (value, expected) => {
expect(nonEmptyValueOrNull(value)).toEqual(expected);
@@ -41,10 +41,10 @@ describe('utils', () => {
describe('capitalize', () => {
it.each([
[ 'foo', 'Foo' ],
[ 'BAR', 'BAR' ],
[ 'bAZ', 'BAZ' ],
[ 'with spaces', 'With spaces' ],
['foo', 'Foo'],
['BAR', 'BAR'],
['bAZ', 'BAZ'],
['with spaces', 'With spaces'],
])('sets first letter in uppercase', (value, expectedResult) => {
expect(capitalize(value)).toEqual(expectedResult);
});

View File

@@ -42,9 +42,9 @@ describe('<ShortUrlVisitsHeader />', () => {
});
it.each([
[ null, longUrl ],
[ undefined, longUrl ],
[ 'My cool title', 'My cool title' ],
[null, longUrl],
[undefined, longUrl],
['My cool title', 'My cool title'],
])('shows the long URL and title', (title, expectedContent) => {
const wrapper = createWrapper(title);
const longUrlLink = wrapper.find(ExternalLink).last();

View File

@@ -5,7 +5,7 @@ import { Visit } from '../../src/visits/types';
describe('<VisitsHeader />', () => {
let wrapper: ShallowWrapper;
const visits = [ Mock.all<Visit>(), Mock.all<Visit>(), Mock.all<Visit>() ];
const visits = [Mock.all<Visit>(), Mock.all<Visit>(), Mock.all<Visit>()];
const title = 'My header title';
const goBack = jest.fn();

View File

@@ -16,7 +16,7 @@ import { DoughnutChartCard } from '../../src/visits/charts/DoughnutChartCard';
import { ExportBtn } from '../../src/utils/ExportBtn';
describe('<VisitsStats />', () => {
const visits = [ Mock.all<Visit>(), Mock.all<Visit>(), Mock.all<Visit>() ];
const visits = [Mock.all<Visit>(), Mock.all<Visit>(), Mock.all<Visit>()];
let wrapper: ShallowWrapper;
const getVisitsMock = jest.fn();

View File

@@ -47,8 +47,8 @@ describe('<VisitsTable />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ '2.6.0' as SemVer, [ 'Date', 'Country', 'City', 'Browser', 'OS', 'Referrer' ]],
[ '2.7.0' as SemVer, [ 'fa-robot', 'Date', 'Country', 'City', 'Browser', 'OS', 'Referrer' ]],
['2.6.0' as SemVer, ['Date', 'Country', 'City', 'Browser', 'OS', 'Referrer']],
['2.7.0' as SemVer, ['fa-robot', 'Date', 'Country', 'City', 'Browser', 'OS', 'Referrer']],
])('renders columns as expected', (version, expectedColumns) => {
const wrapper = createServerVersionWrapper(version);
const th = wrapper.find('thead').find('th');
@@ -68,11 +68,11 @@ describe('<VisitsTable />', () => {
});
it.each([
[ 50, 3 ],
[ 21, 2 ],
[ 30, 2 ],
[ 60, 3 ],
[ 115, 6 ],
[50, 3],
[21, 2],
[30, 2],
[60, 3],
[115, 6],
])('renders the expected amount of pages', (visitsCount, expectedAmountOfPages) => {
const wrapper = createWrapper(
rangeOf(visitsCount, () => Mock.of<NormalizedVisit>({ browser: '', date: '', referer: '' })),
@@ -85,7 +85,7 @@ describe('<VisitsTable />', () => {
});
it.each(
rangeOf(20, (value) => [ value ]),
rangeOf(20, (value) => [value]),
)('does not render footer when there is only one page to render', (visitsCount) => {
const wrapper = createWrapper(
rangeOf(visitsCount, () => Mock.of<NormalizedVisit>({ browser: '', date: '', referer: '' })),
@@ -101,7 +101,7 @@ describe('<VisitsTable />', () => {
const visits = rangeOf(10, () => Mock.of<NormalizedVisit>({ browser: '', date: '', referer: '' }));
const wrapper = createWrapper(
visits,
[ visits[1], visits[2] ],
[visits[1], visits[2]],
);
expect(wrapper.find('.text-primary')).toHaveLength(3);
@@ -109,11 +109,11 @@ describe('<VisitsTable />', () => {
// Select one extra
wrapper.find('tr').at(5).simulate('click');
expect(setSelectedVisits).toHaveBeenCalledWith([ visits[1], visits[2], visits[4] ]);
expect(setSelectedVisits).toHaveBeenCalledWith([visits[1], visits[2], visits[4]]);
// Deselect one
wrapper.find('tr').at(3).simulate('click');
expect(setSelectedVisits).toHaveBeenCalledWith([ visits[1] ]);
expect(setSelectedVisits).toHaveBeenCalledWith([visits[1]]);
// Select all
wrapper.find('thead').find('th').at(0).simulate('click');
@@ -128,15 +128,25 @@ describe('<VisitsTable />', () => {
country: `Country_${index}`,
})));
expect(wrapper.find('tbody').find('tr').at(0).find('td').at(2).text()).toContain('Country_1');
expect(wrapper.find('tbody').find('tr').at(0).find('td')
.at(2)
.text()).toContain('Country_1');
wrapper.find('thead').find('th').at(1).simulate('click'); // Date column ASC
expect(wrapper.find('tbody').find('tr').at(0).find('td').at(2).text()).toContain('Country_9');
expect(wrapper.find('tbody').find('tr').at(0).find('td')
.at(2)
.text()).toContain('Country_9');
wrapper.find('thead').find('th').at(6).simulate('click'); // Referer column - ASC
expect(wrapper.find('tbody').find('tr').at(0).find('td').at(2).text()).toContain('Country_1');
expect(wrapper.find('tbody').find('tr').at(0).find('td')
.at(2)
.text()).toContain('Country_1');
wrapper.find('thead').find('th').at(6).simulate('click'); // Referer column - DESC
expect(wrapper.find('tbody').find('tr').at(0).find('td').at(2).text()).toContain('Country_9');
expect(wrapper.find('tbody').find('tr').at(0).find('td')
.at(2)
.text()).toContain('Country_9');
wrapper.find('thead').find('th').at(6).simulate('click'); // Referer column - reset
expect(wrapper.find('tbody').find('tr').at(0).find('td').at(2).text()).toContain('Country_1');
expect(wrapper.find('tbody').find('tr').at(0).find('td')
.at(2)
.text()).toContain('Country_1');
});
it('filters list when writing in search box', () => {
@@ -156,10 +166,10 @@ describe('<VisitsTable />', () => {
});
it.each([
[ true, '2.6.0' as SemVer, 8 ],
[ false, '2.6.0' as SemVer, 7 ],
[ true, '2.7.0' as SemVer, 9 ],
[ false, '2.7.0' as SemVer, 8 ],
[true, '2.6.0' as SemVer, 8],
[false, '2.6.0' as SemVer, 7],
[true, '2.7.0' as SemVer, 9],
[false, '2.7.0' as SemVer, 8],
])('displays proper amount of columns for orphan and non-orphan visits', (isOrphanVisits, version, expectedCols) => {
const wrapper = createOrphanVisitsWrapper(isOrphanVisits, version);
const rowsWithColspan = wrapper.find('[colSpan]');

View File

@@ -27,8 +27,8 @@ describe('<ChartCard />', () => {
});
it.each([
[ 'the title', 'the title' ],
[ () => 'the title from func', 'the title from func' ],
['the title', 'the title'],
[() => 'the title from func', 'the title from func'],
])('properly renders title by parsing provided value', (title, expectedTitle) => {
const wrapper = createWrapper(title);
const header = wrapper.find(CardHeader);

View File

@@ -4,10 +4,10 @@ import { Chart, ChartDataset } from 'chart.js';
import { DoughnutChartLegend } from '../../../src/visits/charts/DoughnutChartLegend';
describe('<DoughnutChartLegend />', () => {
const labels = [ 'foo', 'bar', 'baz', 'foo2', 'bar2' ];
const colors = [ 'foo_color', 'bar_color', 'baz_color' ];
const labels = ['foo', 'bar', 'baz', 'foo2', 'bar2'];
const colors = ['foo_color', 'bar_color', 'baz_color'];
const defaultColor = 'red';
const datasets = [ Mock.of<ChartDataset>({ backgroundColor: colors }) ];
const datasets = [Mock.of<ChartDataset>({ backgroundColor: colors })];
const chart = Mock.of<Chart>({
config: {
data: { labels, datasets },

View File

@@ -39,16 +39,16 @@ describe('<HorizontalBarChart />', () => {
});
it.each([
[{ foo: 23 }, [ 100, 456 ], [ 23, 0 ]],
[{ foo: 50 }, [ 73, 456 ], [ 50, 0 ]],
[{ bar: 45 }, [ 123, 411 ], [ 0, 45 ]],
[{ bar: 20, foo: 13 }, [ 110, 436 ], [ 13, 20 ]],
[ undefined, [ 123, 456 ], undefined ],
[{ foo: 23 }, [100, 456], [23, 0]],
[{ foo: 50 }, [73, 456], [50, 0]],
[{ bar: 45 }, [123, 411], [0, 45]],
[{ bar: 20, foo: 13 }, [110, 436], [13, 20]],
[undefined, [123, 456], undefined],
])('splits highlighted data from regular data', (highlightedStats, expectedData, expectedHighlightedData) => {
wrapper = shallow(<HorizontalBarChart stats={stats} highlightedStats={highlightedStats} />);
const horizontal = wrapper.find(Bar);
const { datasets: [{ data, label }, highlightedData ] } = horizontal.prop('data') as any;
const { datasets: [{ data, label }, highlightedData] } = horizontal.prop('data') as any;
expect(label).toEqual('Visits');
expect(data).toEqual(expectedData);

Some files were not shown because too many files have changed in this diff Show More