From 340f4b8fb50057df9e1568998709624bca240e6d Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 13 Apr 2023 21:48:29 +0200 Subject: [PATCH] Introduce shoehorn as a possible replacement for ts-mockery --- package-lock.json | 18 +++++++-- package.json | 1 + test/__mocks__/Window.mock.ts | 8 ++-- test/api/ShlinkApiError.test.tsx | 12 +++--- test/api/services/ShlinkApiClient.test.ts | 14 +++---- .../services/ShlinkApiClientBuilder.test.ts | 12 +++--- test/app/App.test.tsx | 5 +-- test/common/AsideMenu.test.tsx | 5 +-- test/common/ErrorHandler.test.tsx | 6 +-- test/common/Home.test.tsx | 8 ++-- test/common/MenuLayout.test.tsx | 10 ++--- test/common/ShlinkVersions.test.tsx | 16 ++++---- test/common/ShlinkVersionsContainer.test.tsx | 5 +-- test/common/services/ImageDownloader.test.ts | 4 +- test/domains/DomainRow.test.tsx | 23 ++++++------ test/domains/DomainSelector.test.tsx | 11 +++--- test/domains/ManageDomains.test.tsx | 27 +++++++------- test/domains/helpers/DomainDropdown.test.tsx | 18 ++++----- .../domains/helpers/DomainStatusIcon.test.tsx | 4 +- .../helpers/EditDomainRedirectsModal.test.tsx | 4 +- test/domains/reducers/domainRedirects.test.ts | 9 ++--- test/domains/reducers/domainsList.test.ts | 37 +++++++++---------- test/mercure/helpers/index.test.tsx | 12 +++--- test/mercure/reducers/mercureInfo.test.ts | 4 +- test/servers/CreateServer.test.tsx | 4 +- test/servers/DeleteServerButton.test.tsx | 5 +-- test/servers/DeleteServerModal.test.tsx | 5 +-- test/servers/EditServer.test.tsx | 6 +-- test/servers/ManageServers.test.tsx | 6 +-- .../servers/ManageServersRowDropdown.test.tsx | 4 +- test/servers/Overview.test.tsx | 19 ++++------ test/servers/ServersDropdown.test.tsx | 10 ++--- test/servers/ServersListGroup.test.tsx | 8 ++-- .../helpers/DuplicatedServersModal.test.tsx | 21 ++++++----- .../servers/helpers/ImportServersBtn.test.tsx | 8 ++-- test/servers/helpers/ServerError.test.tsx | 6 +-- test/servers/reducers/remoteServers.test.ts | 4 +- test/servers/reducers/selectedServer.test.ts | 19 +++++----- test/servers/reducers/servers.test.ts | 24 ++++++------ test/servers/services/ServersExporter.test.ts | 8 ++-- test/servers/services/ServersImporter.test.ts | 18 ++++----- .../settings/RealTimeUpdatesSettings.test.tsx | 5 +-- .../ShortUrlCreationSettings.test.tsx | 6 +-- test/settings/ShortUrlsListSettings.test.tsx | 6 +-- test/settings/TagsSettings.test.tsx | 6 +-- test/settings/UserInterfaceSettings.test.tsx | 6 +-- test/settings/VisitsSettings.test.tsx | 18 ++++----- test/settings/helpers/index.test.ts | 4 +- test/short-urls/CreateShortUrl.test.tsx | 7 ++-- test/short-urls/EditShortUrl.test.tsx | 12 +++--- test/short-urls/Paginator.test.tsx | 4 +- test/short-urls/ShortUrlForm.test.tsx | 14 +++---- .../short-urls/ShortUrlsFilteringBar.test.tsx | 25 ++++++------- test/short-urls/ShortUrlsList.test.tsx | 31 ++++++++-------- test/short-urls/ShortUrlsTable.test.tsx | 8 ++-- .../helpers/CreateShortUrlResult.test.tsx | 7 ++-- .../helpers/DeleteShortUrlModal.test.tsx | 14 +++---- .../helpers/ExportShortUrlsBtn.test.tsx | 12 +++--- test/short-urls/helpers/QrCodeModal.test.tsx | 11 ++---- .../helpers/ShortUrlDetailLink.test.tsx | 28 +++++++------- .../helpers/ShortUrlStatus.test.tsx | 24 ++++++------ .../helpers/ShortUrlVisitsCount.test.tsx | 8 ++-- test/short-urls/helpers/ShortUrlsRow.test.tsx | 18 ++++----- .../helpers/ShortUrlsRowMenu.test.tsx | 6 +-- test/short-urls/helpers/index.test.ts | 4 +- 65 files changed, 357 insertions(+), 375 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7d394ed..8b74c082 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,6 +60,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", + "@total-typescript/shoehorn": "^0.1.0", "@types/jest": "^29.2.4", "@types/json2csv": "^5.0.3", "@types/leaflet": "^1.9.0", @@ -3563,6 +3564,12 @@ "node": ">= 10" } }, + "node_modules/@total-typescript/shoehorn": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@total-typescript/shoehorn/-/shoehorn-0.1.0.tgz", + "integrity": "sha512-XKig6hXxWnUh0fsW3LR2vxpxwLlPFokfOSR0riHKA9uXvdHDfwOOPdAOi4U/YNKLmgYUu/plUfnF3yiAAz1+Zg==", + "dev": true + }, "node_modules/@types/aria-query": { "version": "4.2.2", "dev": true, @@ -14987,6 +14994,12 @@ "version": "2.0.0", "dev": true }, + "@total-typescript/shoehorn": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@total-typescript/shoehorn/-/shoehorn-0.1.0.tgz", + "integrity": "sha512-XKig6hXxWnUh0fsW3LR2vxpxwLlPFokfOSR0riHKA9uXvdHDfwOOPdAOi4U/YNKLmgYUu/plUfnF3yiAAz1+Zg==", + "dev": true + }, "@types/aria-query": { "version": "4.2.2", "dev": true @@ -15884,9 +15897,6 @@ } } }, - "caniuse-lite": { - "version": "1.0.30001415" - }, "chalk": { "version": "5.2.0", "dev": true @@ -20949,4 +20959,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 66ebcd44..62bb4d0d 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", + "@total-typescript/shoehorn": "^0.1.0", "@types/jest": "^29.2.4", "@types/json2csv": "^5.0.3", "@types/leaflet": "^1.9.0", diff --git a/test/__mocks__/Window.mock.ts b/test/__mocks__/Window.mock.ts index 69cb1f4e..dbd91da6 100644 --- a/test/__mocks__/Window.mock.ts +++ b/test/__mocks__/Window.mock.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromAny, fromPartial } from '@total-typescript/shoehorn'; const createLinkMock = () => ({ setAttribute: jest.fn(), @@ -10,9 +10,9 @@ export const appendChild = jest.fn(); export const removeChild = jest.fn(); -export const windowMock = Mock.of({ - document: { +export const windowMock = fromPartial({ + document: fromAny({ createElement: jest.fn(createLinkMock), body: { appendChild, removeChild }, - }, + }), }); diff --git a/test/api/ShlinkApiError.test.tsx b/test/api/ShlinkApiError.test.tsx index daa42f69..1690b5ce 100644 --- a/test/api/ShlinkApiError.test.tsx +++ b/test/api/ShlinkApiError.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkApiErrorProps } from '../../src/api/ShlinkApiError'; import { ShlinkApiError } from '../../src/api/ShlinkApiError'; import type { InvalidArgumentError, ProblemDetailsError } from '../../src/api/types/errors'; @@ -10,8 +10,8 @@ describe('', () => { it.each([ [undefined, 'the fallback', 'the fallback'], - [Mock.all(), 'the fallback', 'the fallback'], - [Mock.of({ detail: 'the detail' }), 'the fallback', 'the detail'], + [fromPartial({}), 'the fallback', 'the fallback'], + [fromPartial({ detail: 'the detail' }), 'the fallback', 'the detail'], ])('renders proper message', (errorData, fallbackMessage, expectedMessage) => { const { container } = setUp({ errorData, fallbackMessage }); @@ -21,9 +21,9 @@ describe('', () => { it.each([ [undefined, 0], - [Mock.all(), 0], - [Mock.of({ type: ErrorTypeV2.INVALID_ARGUMENT, invalidElements: [] }), 1], - [Mock.of({ type: ErrorTypeV3.INVALID_ARGUMENT, invalidElements: [] }), 1], + [fromPartial({}), 0], + [fromPartial({ type: ErrorTypeV2.INVALID_ARGUMENT, invalidElements: [] }), 1], + [fromPartial({ type: ErrorTypeV3.INVALID_ARGUMENT, invalidElements: [] }), 1], ])('renders list of invalid elements when provided error is an InvalidError', (errorData, expectedElementsCount) => { setUp({ errorData }); expect(screen.queryAllByText(/^Invalid elements/)).toHaveLength(expectedElementsCount); diff --git a/test/api/services/ShlinkApiClient.test.ts b/test/api/services/ShlinkApiClient.test.ts index 408f6903..8423e68d 100644 --- a/test/api/services/ShlinkApiClient.test.ts +++ b/test/api/services/ShlinkApiClient.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import { ShlinkApiClient } from '../../../src/api/services/ShlinkApiClient'; import type { ShlinkDomain, ShlinkVisits, ShlinkVisitsOverview } from '../../../src/api/types'; import { ErrorTypeV2, ErrorTypeV3 } from '../../../src/api/types/errors'; @@ -9,7 +9,7 @@ import type { OptionalString } from '../../../src/utils/utils'; describe('ShlinkApiClient', () => { const fetchJson = jest.fn().mockResolvedValue({}); const fetchEmpty = jest.fn().mockResolvedValue(undefined); - const httpClient = Mock.of({ fetchJson, fetchEmpty }); + const httpClient = fromPartial({ fetchJson, fetchEmpty }); const buildApiClient = () => new ShlinkApiClient(httpClient, '', ''); const shortCodesWithDomainCombinations: [string, OptionalString][] = [ ['abc123', null], @@ -177,7 +177,7 @@ describe('ShlinkApiClient', () => { maxVisits: 50, validSince: '2025-01-01T10:00:00+01:00', }; - const expectedResp = Mock.of(); + const expectedResp = fromPartial({}); fetchJson.mockResolvedValue(expectedResp); const { updateShortUrl } = buildApiClient(); const expectedQuery = domain ? `?domain=${domain}` : ''; @@ -311,7 +311,7 @@ describe('ShlinkApiClient', () => { describe('listDomains', () => { it('returns domains', async () => { - const expectedData = { data: [Mock.all(), Mock.all()] }; + const expectedData = { data: [fromPartial({}), fromPartial({})] }; fetchJson.mockResolvedValue({ domains: expectedData }); const { listDomains } = buildApiClient(); @@ -324,7 +324,7 @@ describe('ShlinkApiClient', () => { describe('getVisitsOverview', () => { it('returns visits overview', async () => { - const expectedData = Mock.all(); + const expectedData = fromPartial({}); fetchJson.mockResolvedValue({ visits: expectedData }); const { getVisitsOverview } = buildApiClient(); @@ -337,7 +337,7 @@ describe('ShlinkApiClient', () => { describe('getOrphanVisits', () => { it('returns orphan visits', async () => { - fetchJson.mockResolvedValue({ visits: Mock.of({ data: [] }) }); + fetchJson.mockResolvedValue({ visits: fromPartial({ data: [] }) }); const { getOrphanVisits } = buildApiClient(); const result = await getOrphanVisits(); @@ -349,7 +349,7 @@ describe('ShlinkApiClient', () => { describe('getNonOrphanVisits', () => { it('returns non-orphan visits', async () => { - fetchJson.mockResolvedValue({ visits: Mock.of({ data: [] }) }); + fetchJson.mockResolvedValue({ visits: fromPartial({ data: [] }) }); const { getNonOrphanVisits } = buildApiClient(); const result = await getNonOrphanVisits(); diff --git a/test/api/services/ShlinkApiClientBuilder.test.ts b/test/api/services/ShlinkApiClientBuilder.test.ts index 3729bf07..af5d3faa 100644 --- a/test/api/services/ShlinkApiClientBuilder.test.ts +++ b/test/api/services/ShlinkApiClientBuilder.test.ts @@ -1,15 +1,13 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import { buildShlinkApiClient } from '../../../src/api/services/ShlinkApiClientBuilder'; -import type { HttpClient } from '../../../src/common/services/HttpClient'; -import type { ShlinkState } from '../../../src/container/types'; import type { ReachableServer, SelectedServer } from '../../../src/servers/data'; describe('ShlinkApiClientBuilder', () => { - const server = (data: Partial) => Mock.of(data); + const server = fromPartial; const createBuilder = () => { - const builder = buildShlinkApiClient(Mock.of()); - return (selectedServer: SelectedServer) => builder(() => Mock.of({ selectedServer })); + const builder = buildShlinkApiClient(fromPartial({})); + return (selectedServer: SelectedServer) => builder(() => fromPartial({ selectedServer })); }; it('creates new instances when provided params are different', async () => { @@ -42,7 +40,7 @@ describe('ShlinkApiClientBuilder', () => { it('does not fetch from state when provided param is already selected server', () => { const url = 'url'; const apiKey = 'apiKey'; - const apiClient = buildShlinkApiClient(Mock.of())(server({ url, apiKey })); + const apiClient = buildShlinkApiClient(fromPartial({}))(server({ url, apiKey })); expect(apiClient['baseUrl']).toEqual(url); // eslint-disable-line @typescript-eslint/dot-notation expect(apiClient['apiKey']).toEqual(apiKey); // eslint-disable-line @typescript-eslint/dot-notation diff --git a/test/app/App.test.tsx b/test/app/App.test.tsx index 345ce5d6..6063b05a 100644 --- a/test/app/App.test.tsx +++ b/test/app/App.test.tsx @@ -1,9 +1,8 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import { App as createApp } from '../../src/app/App'; -import type { Settings } from '../../src/settings/reducers/settings'; describe('', () => { const App = createApp( @@ -25,7 +24,7 @@ describe('', () => { {}} servers={{}} - settings={Mock.all()} + settings={fromPartial({})} appUpdated resetAppUpdate={() => {}} /> diff --git a/test/common/AsideMenu.test.tsx b/test/common/AsideMenu.test.tsx index 7e149e15..c0fa448a 100644 --- a/test/common/AsideMenu.test.tsx +++ b/test/common/AsideMenu.test.tsx @@ -1,14 +1,13 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import { AsideMenu as createAsideMenu } from '../../src/common/AsideMenu'; -import type { ReachableServer } from '../../src/servers/data'; describe('', () => { const AsideMenu = createAsideMenu(() => <>DeleteServerButton); const setUp = (id: string | false = 'abc123') => render( - ({ id: id || undefined, version: '2.8.0' })} /> + , ); diff --git a/test/common/ErrorHandler.test.tsx b/test/common/ErrorHandler.test.tsx index 67d271c4..41c82dde 100644 --- a/test/common/ErrorHandler.test.tsx +++ b/test/common/ErrorHandler.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import { ErrorHandler as createErrorHandler } from '../../src/common/ErrorHandler'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -9,10 +9,10 @@ const ComponentWithError = () => { describe('', () => { const reload = jest.fn(); - const window = Mock.of({ + const window = fromPartial({ location: { reload }, }); - const cons = Mock.of({ error: jest.fn() }); + const cons = fromPartial({ error: jest.fn() }); const ErrorHandler = createErrorHandler(window, cons); beforeEach(() => { diff --git a/test/common/Home.test.tsx b/test/common/Home.test.tsx index 9f389c83..8e619b89 100644 --- a/test/common/Home.test.tsx +++ b/test/common/Home.test.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import { Home } from '../../src/common/Home'; import type { ServersMap, ServerWithId } from '../../src/servers/data'; @@ -19,9 +19,9 @@ describe('', () => { it.each([ [ { - '1a': Mock.of({ name: 'foo', id: '1' }), - '2b': Mock.of({ name: 'bar', id: '2' }), - '3c': Mock.of({ name: 'baz', id: '3' }), + '1a': fromPartial({ name: 'foo', id: '1' }), + '2b': fromPartial({ name: 'bar', id: '2' }), + '3c': fromPartial({ name: 'baz', id: '3' }), }, 3, ], diff --git a/test/common/MenuLayout.test.tsx b/test/common/MenuLayout.test.tsx index 644235f6..a6ae0191 100644 --- a/test/common/MenuLayout.test.tsx +++ b/test/common/MenuLayout.test.tsx @@ -1,9 +1,9 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { createMemoryHistory } from 'history'; import { Router, useParams } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import { MenuLayout as createMenuLayout } from '../../src/common/MenuLayout'; -import type { NonReachableServer, NotFoundServer, ReachableServer, SelectedServer } from '../../src/servers/data'; +import type { NonReachableServer, NotFoundServer, SelectedServer } from '../../src/servers/data'; import type { SemVer } from '../../src/utils/helpers/version'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useParams: jest.fn() })); @@ -54,8 +54,8 @@ describe('', () => { }); it.each([ - [Mock.of({ serverNotFound: true })], - [Mock.of({ serverNotReachable: true })], + [fromPartial({ serverNotFound: true })], + [fromPartial({ serverNotReachable: true })], ])('shows error for non reachable servers', (selectedServer) => { setUp(selectedServer); @@ -81,7 +81,7 @@ describe('', () => { ])( 'renders expected component based on location and server version', (version, currentPath, expectedContent) => { - setUp(Mock.of({ version }), currentPath); + setUp(fromPartial({ version }), currentPath); expect(screen.getByText(expectedContent)).toBeInTheDocument(); }, ); diff --git a/test/common/ShlinkVersions.test.tsx b/test/common/ShlinkVersions.test.tsx index cd35d9d7..e079e9c8 100644 --- a/test/common/ShlinkVersions.test.tsx +++ b/test/common/ShlinkVersions.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkVersionsProps } from '../../src/common/ShlinkVersions'; import { ShlinkVersions } from '../../src/common/ShlinkVersions'; import type { NonReachableServer, NotFoundServer, ReachableServer } from '../../src/servers/data'; @@ -8,11 +8,11 @@ describe('', () => { const setUp = (props: ShlinkVersionsProps) => render(); it.each([ - ['1.2.3', Mock.of({ version: '1.0.0', printableVersion: 'foo' }), 'v1.2.3', 'foo'], - ['foo', Mock.of({ version: '1.0.0', printableVersion: '1.2.3' }), 'latest', '1.2.3'], - ['latest', Mock.of({ version: '1.0.0', printableVersion: 'latest' }), 'latest', 'latest'], - ['5.5.0', Mock.of({ version: '1.0.0', printableVersion: '0.2.8' }), 'v5.5.0', '0.2.8'], - ['not-semver', Mock.of({ version: '1.0.0', printableVersion: 'some' }), 'latest', 'some'], + ['1.2.3', fromPartial({ version: '1.0.0', printableVersion: 'foo' }), 'v1.2.3', 'foo'], + ['foo', fromPartial({ version: '1.0.0', printableVersion: '1.2.3' }), 'latest', '1.2.3'], + ['latest', fromPartial({ version: '1.0.0', printableVersion: 'latest' }), 'latest', 'latest'], + ['5.5.0', fromPartial({ version: '1.0.0', printableVersion: '0.2.8' }), 'v5.5.0', '0.2.8'], + ['not-semver', fromPartial({ version: '1.0.0', printableVersion: 'some' }), 'latest', 'some'], ])( 'displays expected versions when selected server is reachable', (clientVersion, selectedServer, expectedClientVersion, expectedServerVersion) => { @@ -34,8 +34,8 @@ describe('', () => { it.each([ ['1.2.3', null], - ['1.2.3', Mock.of({ serverNotFound: true })], - ['1.2.3', Mock.of({ serverNotReachable: true })], + ['1.2.3', fromPartial({ serverNotFound: true })], + ['1.2.3', fromPartial({ serverNotReachable: true })], ])('displays only client version when selected server is not reachable', (clientVersion, selectedServer) => { setUp({ clientVersion, selectedServer }); const links = screen.getAllByRole('link'); diff --git a/test/common/ShlinkVersionsContainer.test.tsx b/test/common/ShlinkVersionsContainer.test.tsx index 75f3143a..1676ebfa 100644 --- a/test/common/ShlinkVersionsContainer.test.tsx +++ b/test/common/ShlinkVersionsContainer.test.tsx @@ -1,12 +1,11 @@ import { render } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { Sidebar } from '../../src/common/reducers/sidebar'; import { ShlinkVersionsContainer } from '../../src/common/ShlinkVersionsContainer'; -import type { SelectedServer } from '../../src/servers/data'; describe('', () => { const setUp = (sidebar: Sidebar) => render( - ()} sidebar={sidebar} />, + , ); it.each([ diff --git a/test/common/services/ImageDownloader.test.ts b/test/common/services/ImageDownloader.test.ts index 498b9e60..d7c80dc7 100644 --- a/test/common/services/ImageDownloader.test.ts +++ b/test/common/services/ImageDownloader.test.ts @@ -1,11 +1,11 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { HttpClient } from '../../../src/common/services/HttpClient'; import { ImageDownloader } from '../../../src/common/services/ImageDownloader'; import { windowMock } from '../../__mocks__/Window.mock'; describe('ImageDownloader', () => { const fetchBlob = jest.fn(); - const httpClient = Mock.of({ fetchBlob }); + const httpClient = fromPartial({ fetchBlob }); let imageDownloader: ImageDownloader; beforeEach(() => { diff --git a/test/domains/DomainRow.test.tsx b/test/domains/DomainRow.test.tsx index 2fd4f26d..a6d2969a 100644 --- a/test/domains/DomainRow.test.tsx +++ b/test/domains/DomainRow.test.tsx @@ -1,17 +1,16 @@ import { render, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkDomainRedirects } from '../../src/api/types'; import type { Domain } from '../../src/domains/data'; import { DomainRow } from '../../src/domains/DomainRow'; -import type { SelectedServer } from '../../src/servers/data'; describe('', () => { const redirectsCombinations = [ - [Mock.of({ baseUrlRedirect: 'foo' })], - [Mock.of({ invalidShortUrlRedirect: 'bar' })], - [Mock.of({ baseUrlRedirect: 'baz', regular404Redirect: 'foo' })], + [fromPartial({ baseUrlRedirect: 'foo' })], + [fromPartial({ invalidShortUrlRedirect: 'bar' })], + [fromPartial({ baseUrlRedirect: 'baz', regular404Redirect: 'foo' })], [ - Mock.of( + fromPartial( { baseUrlRedirect: 'baz', regular404Redirect: 'bar', invalidShortUrlRedirect: 'foo' }, ), ], @@ -22,7 +21,7 @@ describe('', () => { ()} + selectedServer={fromPartial({})} editDomainRedirects={jest.fn()} checkDomainHealth={jest.fn()} /> @@ -31,7 +30,7 @@ describe('', () => { ); it.each(redirectsCombinations)('shows expected redirects', (redirects) => { - setUp(Mock.of({ domain: '', isDefault: true, redirects })); + setUp(fromPartial({ domain: '', isDefault: true, redirects })); const cells = screen.getAllByRole('cell'); redirects?.baseUrlRedirect && expect(cells[1]).toHaveTextContent(redirects.baseUrlRedirect); @@ -42,9 +41,9 @@ describe('', () => { it.each([ [undefined], - [Mock.of()], + [fromPartial({})], ])('shows expected "no redirects"', (redirects) => { - setUp(Mock.of({ domain: '', isDefault: true, redirects })); + setUp(fromPartial({ domain: '', isDefault: true, redirects })); const cells = screen.getAllByRole('cell'); expect(cells[1]).toHaveTextContent('No redirect'); @@ -54,7 +53,7 @@ describe('', () => { }); it.each(redirectsCombinations)('shows expected fallback redirects', (fallbackRedirects) => { - setUp(Mock.of({ domain: '', isDefault: true }), fallbackRedirects); + setUp(fromPartial({ domain: '', isDefault: true }), fallbackRedirects); const cells = screen.getAllByRole('cell'); fallbackRedirects?.baseUrlRedirect && expect(cells[1]).toHaveTextContent( @@ -69,7 +68,7 @@ describe('', () => { }); it.each([[true], [false]])('shows icon on default domain only', (isDefault) => { - const { container } = setUp(Mock.of({ domain: '', isDefault })); + const { container } = setUp(fromPartial({ domain: '', isDefault })); if (isDefault) { expect(container.querySelector('#defaultDomainIcon')).toBeInTheDocument(); diff --git a/test/domains/DomainSelector.test.tsx b/test/domains/DomainSelector.test.tsx index 065201bc..008414af 100644 --- a/test/domains/DomainSelector.test.tsx +++ b/test/domains/DomainSelector.test.tsx @@ -1,16 +1,15 @@ import { screen, waitFor } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { ShlinkDomain } from '../../src/api/types'; +import { fromPartial } from '@total-typescript/shoehorn'; import { DomainSelector } from '../../src/domains/DomainSelector'; import type { DomainsList } from '../../src/domains/reducers/domainsList'; import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { - const domainsList = Mock.of({ + const domainsList = fromPartial({ domains: [ - Mock.of({ domain: 'default.com', isDefault: true }), - Mock.of({ domain: 'foo.com' }), - Mock.of({ domain: 'bar.com' }), + fromPartial({ domain: 'default.com', isDefault: true }), + fromPartial({ domain: 'foo.com' }), + fromPartial({ domain: 'bar.com' }), ], }); const setUp = (value = '') => renderWithEvents( diff --git a/test/domains/ManageDomains.test.tsx b/test/domains/ManageDomains.test.tsx index fc3c295d..30cf6048 100644 --- a/test/domains/ManageDomains.test.tsx +++ b/test/domains/ManageDomains.test.tsx @@ -1,10 +1,9 @@ import { screen, waitFor } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkDomain } from '../../src/api/types'; import type { ProblemDetailsError } from '../../src/api/types/errors'; import { ManageDomains } from '../../src/domains/ManageDomains'; import type { DomainsList } from '../../src/domains/reducers/domainsList'; -import type { SelectedServer } from '../../src/servers/data'; import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { @@ -17,14 +16,14 @@ describe('', () => { editDomainRedirects={jest.fn()} checkDomainHealth={jest.fn()} domainsList={domainsList} - selectedServer={Mock.all()} + selectedServer={fromPartial({})} />, ); afterEach(jest.clearAllMocks); it('shows loading message while domains are loading', () => { - setUp(Mock.of({ loading: true, filteredDomains: [] })); + setUp(fromPartial({ loading: true, filteredDomains: [] })); expect(screen.getByText('Loading...')).toBeInTheDocument(); expect(screen.queryByText('Error loading domains :(')).not.toBeInTheDocument(); @@ -32,17 +31,17 @@ describe('', () => { it.each([ [undefined, 'Error loading domains :('], - [Mock.of(), 'Error loading domains :('], - [Mock.of({ detail: 'Foo error!!' }), 'Foo error!!'], + [fromPartial({}), 'Error loading domains :('], + [fromPartial({ detail: 'Foo error!!' }), 'Foo error!!'], ])('shows error result when domains loading fails', (errorData, expectedErrorMessage) => { - setUp(Mock.of({ loading: false, error: true, errorData, filteredDomains: [] })); + setUp(fromPartial({ loading: false, error: true, errorData, filteredDomains: [] })); expect(screen.queryByText('Loading...')).not.toBeInTheDocument(); expect(screen.getByText(expectedErrorMessage)).toBeInTheDocument(); }); it('filters domains when SearchField changes', async () => { - const { user } = setUp(Mock.of({ loading: false, error: false, filteredDomains: [] })); + const { user } = setUp(fromPartial({ loading: false, error: false, filteredDomains: [] })); expect(filterDomains).not.toHaveBeenCalled(); await user.type(screen.getByPlaceholderText('Search...'), 'Foo'); @@ -50,19 +49,19 @@ describe('', () => { }); it('shows expected headers and one row when list of domains is empty', () => { - setUp(Mock.of({ loading: false, error: false, filteredDomains: [] })); + setUp(fromPartial({ loading: false, error: false, filteredDomains: [] })); expect(screen.getAllByRole('columnheader')).toHaveLength(7); expect(screen.getByText('No results found')).toBeInTheDocument(); }); it('has many rows if multiple domains are provided', () => { - const filteredDomains = [ - Mock.of({ domain: 'foo' }), - Mock.of({ domain: 'bar' }), - Mock.of({ domain: 'baz' }), + const filteredDomains: ShlinkDomain[] = [ + fromPartial({ domain: 'foo' }), + fromPartial({ domain: 'bar' }), + fromPartial({ domain: 'baz' }), ]; - setUp(Mock.of({ loading: false, error: false, filteredDomains })); + setUp(fromPartial({ loading: false, error: false, filteredDomains })); expect(screen.getAllByRole('row')).toHaveLength(filteredDomains.length + 1); expect(screen.getByText('foo')).toBeInTheDocument(); diff --git a/test/domains/helpers/DomainDropdown.test.tsx b/test/domains/helpers/DomainDropdown.test.tsx index 6acd0b9b..f121978b 100644 --- a/test/domains/helpers/DomainDropdown.test.tsx +++ b/test/domains/helpers/DomainDropdown.test.tsx @@ -1,9 +1,9 @@ import { screen, waitForElementToBeRemoved } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { Domain } from '../../../src/domains/data'; import { DomainDropdown } from '../../../src/domains/helpers/DomainDropdown'; -import type { ReachableServer, SelectedServer } from '../../../src/servers/data'; +import type { SelectedServer } from '../../../src/servers/data'; import type { SemVer } from '../../../src/utils/helpers/version'; import { renderWithEvents } from '../../__helpers__/setUpTest'; @@ -12,8 +12,8 @@ describe('', () => { const setUp = (domain?: Domain, selectedServer?: SelectedServer) => renderWithEvents( ()} - selectedServer={selectedServer ?? Mock.all()} + domain={domain ?? fromPartial({})} + selectedServer={selectedServer ?? fromPartial({})} editDomainRedirects={editDomainRedirects} /> , @@ -33,8 +33,8 @@ describe('', () => { [false, ''], ])('points first link to the proper section', (isDefault, expectedLink) => { setUp( - Mock.of({ domain: 'foo.com', isDefault }), - Mock.of({ version: '3.1.0', id: '123' }), + fromPartial({ domain: 'foo.com', isDefault }), + fromPartial({ version: '3.1.0', id: '123' }), ); expect(screen.getByText('Visit stats')).toHaveAttribute('href', `/server/123/domain/foo.com${expectedLink}/visits`); @@ -46,8 +46,8 @@ describe('', () => { [false, '2.9.0' as SemVer, true], ])('allows editing certain the domains', (isDefault, serverVersion, canBeEdited) => { setUp( - Mock.of({ domain: 'foo.com', isDefault }), - Mock.of({ version: serverVersion, id: '123' }), + fromPartial({ domain: 'foo.com', isDefault }), + fromPartial({ version: serverVersion, id: '123' }), ); if (canBeEdited) { @@ -62,7 +62,7 @@ describe('', () => { ['bar.org'], ['baz.net'], ])('displays modal when editing redirects', async (domain) => { - const { user } = setUp(Mock.of({ domain, isDefault: false })); + const { user } = setUp(fromPartial({ domain, isDefault: false })); expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); expect(screen.queryByRole('form')).not.toBeInTheDocument(); diff --git a/test/domains/helpers/DomainStatusIcon.test.tsx b/test/domains/helpers/DomainStatusIcon.test.tsx index ee5d3410..d695a92b 100644 --- a/test/domains/helpers/DomainStatusIcon.test.tsx +++ b/test/domains/helpers/DomainStatusIcon.test.tsx @@ -1,11 +1,11 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { DomainStatus } from '../../../src/domains/data'; import { DomainStatusIcon } from '../../../src/domains/helpers/DomainStatusIcon'; import { renderWithEvents } from '../../__helpers__/setUpTest'; describe('', () => { - const matchMedia = jest.fn().mockReturnValue(Mock.of({ matches: false })); + const matchMedia = jest.fn().mockReturnValue(fromPartial({ matches: false })); const setUp = (status: DomainStatus) => renderWithEvents( , ); diff --git a/test/domains/helpers/EditDomainRedirectsModal.test.tsx b/test/domains/helpers/EditDomainRedirectsModal.test.tsx index fb9a98fc..dad4e887 100644 --- a/test/domains/helpers/EditDomainRedirectsModal.test.tsx +++ b/test/domains/helpers/EditDomainRedirectsModal.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkDomain } from '../../../src/api/types'; import { EditDomainRedirectsModal } from '../../../src/domains/helpers/EditDomainRedirectsModal'; import { renderWithEvents } from '../../__helpers__/setUpTest'; @@ -7,7 +7,7 @@ import { renderWithEvents } from '../../__helpers__/setUpTest'; describe('', () => { const editDomainRedirects = jest.fn().mockResolvedValue(undefined); const toggle = jest.fn(); - const domain = Mock.of({ + const domain = fromPartial({ domain: 'foo.com', redirects: { baseUrlRedirect: 'baz', diff --git a/test/domains/reducers/domainRedirects.test.ts b/test/domains/reducers/domainRedirects.test.ts index 99c41554..e9f092b9 100644 --- a/test/domains/reducers/domainRedirects.test.ts +++ b/test/domains/reducers/domainRedirects.test.ts @@ -1,7 +1,6 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkApiClient } from '../../../src/api/services/ShlinkApiClient'; import type { ShlinkDomainRedirects } from '../../../src/api/types'; -import type { EditDomainRedirects } from '../../../src/domains/reducers/domainRedirects'; import { editDomainRedirects } from '../../../src/domains/reducers/domainRedirects'; describe('domainRedirectsReducer', () => { @@ -9,17 +8,17 @@ describe('domainRedirectsReducer', () => { describe('editDomainRedirects', () => { const domain = 'example.com'; - const redirects = Mock.all(); + const redirects = fromPartial({}); const dispatch = jest.fn(); const getState = jest.fn(); const editDomainRedirectsCall = jest.fn(); - const buildShlinkApiClient = () => Mock.of({ editDomainRedirects: editDomainRedirectsCall }); + const buildShlinkApiClient = () => fromPartial({ editDomainRedirects: editDomainRedirectsCall }); const editDomainRedirectsAction = editDomainRedirects(buildShlinkApiClient); it('dispatches domain and redirects once loaded', async () => { editDomainRedirectsCall.mockResolvedValue(redirects); - await editDomainRedirectsAction(Mock.of({ domain }))(dispatch, getState, {}); + await editDomainRedirectsAction(fromPartial({ domain }))(dispatch, getState, {}); expect(dispatch).toHaveBeenCalledTimes(2); expect(dispatch).toHaveBeenLastCalledWith(expect.objectContaining({ diff --git a/test/domains/reducers/domainsList.test.ts b/test/domains/reducers/domainsList.test.ts index 842f8ab5..9381e671 100644 --- a/test/domains/reducers/domainsList.test.ts +++ b/test/domains/reducers/domainsList.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkApiClient } from '../../../src/api/services/ShlinkApiClient'; import type { ShlinkDomainRedirects } from '../../../src/api/types'; import { parseApiError } from '../../../src/api/utils'; @@ -6,26 +6,23 @@ import type { ShlinkState } from '../../../src/container/types'; import type { Domain } from '../../../src/domains/data'; import type { EditDomainRedirects } from '../../../src/domains/reducers/domainRedirects'; import { editDomainRedirects } from '../../../src/domains/reducers/domainRedirects'; -import type { - DomainsList } from '../../../src/domains/reducers/domainsList'; import { domainsListReducerCreator, replaceRedirectsOnDomain, replaceStatusOnDomain, } from '../../../src/domains/reducers/domainsList'; -import type { SelectedServer, ServerData } from '../../../src/servers/data'; describe('domainsListReducer', () => { const dispatch = jest.fn(); const getState = jest.fn(); const listDomains = jest.fn(); const health = jest.fn(); - const buildShlinkApiClient = () => Mock.of({ listDomains, health }); - const filteredDomains = [ - Mock.of({ domain: 'foo', status: 'validating' }), - Mock.of({ domain: 'Boo', status: 'validating' }), + const buildShlinkApiClient = () => fromPartial({ listDomains, health }); + const filteredDomains: Domain[] = [ + fromPartial({ domain: 'foo', status: 'validating' }), + fromPartial({ domain: 'Boo', status: 'validating' }), ]; - const domains = [...filteredDomains, Mock.of({ domain: 'bar', status: 'validating' })]; + const domains: Domain[] = [...filteredDomains, fromPartial({ domain: 'bar', status: 'validating' })]; const error = { type: 'NOT_FOUND', status: 404 } as unknown as Error; const editDomainRedirectsThunk = editDomainRedirects(buildShlinkApiClient); const { reducer, listDomains: listDomainsAction, checkDomainHealth, filterDomains } = domainsListReducerCreator( @@ -55,7 +52,7 @@ describe('domainsListReducer', () => { }); it('filters domains on FILTER_DOMAINS', () => { - expect(reducer(Mock.of({ domains }), filterDomains('oO'))).toEqual({ domains, filteredDomains }); + expect(reducer(fromPartial({ domains }), filterDomains('oO'))).toEqual({ domains, filteredDomains }); }); it.each([ @@ -71,7 +68,7 @@ describe('domainsListReducer', () => { const editDomainRedirects: EditDomainRedirects = { domain, redirects }; expect(reducer( - Mock.of({ domains, filteredDomains }), + fromPartial({ domains, filteredDomains }), editDomainRedirectsThunk.fulfilled(editDomainRedirects, '', editDomainRedirects), )).toEqual({ domains: domains.map(replaceRedirectsOnDomain(editDomainRedirects)), @@ -85,7 +82,7 @@ describe('domainsListReducer', () => { ['does_not_exist'], ])('replaces status on proper domain on VALIDATE_DOMAIN', (domain) => { expect(reducer( - Mock.of({ domains, filteredDomains }), + fromPartial({ domains, filteredDomains }), checkDomainHealth.fulfilled({ domain, status: 'valid' }, '', ''), )).toEqual({ domains: domains.map(replaceStatusOnDomain(domain, 'valid')), @@ -122,8 +119,8 @@ describe('domainsListReducer', () => { const domain = 'example.com'; it('dispatches invalid status when selected server does not have all required data', async () => { - getState.mockReturnValue(Mock.of({ - selectedServer: Mock.all(), + getState.mockReturnValue(fromPartial({ + selectedServer: {}, })); await checkDomainHealth(domain)(dispatch, getState, {}); @@ -136,11 +133,11 @@ describe('domainsListReducer', () => { }); it('dispatches invalid status when health endpoint returns an error', async () => { - getState.mockReturnValue(Mock.of({ - selectedServer: Mock.of({ + getState.mockReturnValue(fromPartial({ + selectedServer: { url: 'https://myerver.com', apiKey: '123', - }), + }, })); health.mockRejectedValue({}); @@ -160,11 +157,11 @@ describe('domainsListReducer', () => { healthStatus, expectedStatus, ) => { - getState.mockReturnValue(Mock.of({ - selectedServer: Mock.of({ + getState.mockReturnValue(fromPartial({ + selectedServer: { url: 'https://myerver.com', apiKey: '123', - }), + }, })); health.mockResolvedValue({ status: healthStatus }); diff --git a/test/mercure/helpers/index.test.tsx b/test/mercure/helpers/index.test.tsx index 335cd79c..15a76d15 100644 --- a/test/mercure/helpers/index.test.tsx +++ b/test/mercure/helpers/index.test.tsx @@ -1,6 +1,6 @@ +import { fromPartial } from '@total-typescript/shoehorn'; import { EventSourcePolyfill } from 'event-source-polyfill'; import { identity } from 'ramda'; -import { Mock } from 'ts-mockery'; import { bindToMercureTopic } from '../../../src/mercure/helpers'; import type { MercureInfo } from '../../../src/mercure/reducers/mercureInfo'; @@ -14,11 +14,11 @@ describe('helpers', () => { const onTokenExpired = jest.fn(); it.each([ - [Mock.of({ loading: true, error: false, mercureHubUrl: 'foo' })], - [Mock.of({ loading: false, error: true, mercureHubUrl: 'foo' })], - [Mock.of({ loading: true, error: true, mercureHubUrl: 'foo' })], - [Mock.of({ loading: false, error: false, mercureHubUrl: undefined })], - [Mock.of({ loading: true, error: true, mercureHubUrl: undefined })], + [fromPartial({ loading: true, error: false, mercureHubUrl: 'foo' })], + [fromPartial({ loading: false, error: true, mercureHubUrl: 'foo' })], + [fromPartial({ loading: true, error: true, mercureHubUrl: 'foo' })], + [fromPartial({ loading: false, error: false, mercureHubUrl: undefined })], + [fromPartial({ loading: true, error: true, mercureHubUrl: undefined })], ])('does not bind an EventSource when loading, error or no hub URL', (mercureInfo) => { bindToMercureTopic(mercureInfo, [''], identity, () => {}); diff --git a/test/mercure/reducers/mercureInfo.test.ts b/test/mercure/reducers/mercureInfo.test.ts index 27be5710..907a7b67 100644 --- a/test/mercure/reducers/mercureInfo.test.ts +++ b/test/mercure/reducers/mercureInfo.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkApiClient } from '../../../src/api/services/ShlinkApiClient'; import type { GetState } from '../../../src/container/types'; import { mercureInfoReducerCreator } from '../../../src/mercure/reducers/mercureInfo'; @@ -9,7 +9,7 @@ describe('mercureInfoReducer', () => { token: 'abc.123.def', }; const getMercureInfo = jest.fn(); - const buildShlinkApiClient = () => Mock.of({ mercureInfo: getMercureInfo }); + const buildShlinkApiClient = () => fromPartial({ mercureInfo: getMercureInfo }); const { loadMercureInfo, reducer } = mercureInfoReducerCreator(buildShlinkApiClient); beforeEach(jest.resetAllMocks); diff --git a/test/servers/CreateServer.test.tsx b/test/servers/CreateServer.test.tsx index 4930d9f7..adbc1b2c 100644 --- a/test/servers/CreateServer.test.tsx +++ b/test/servers/CreateServer.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, screen, waitFor } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { useNavigate } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import { CreateServer as createCreateServer } from '../../src/servers/CreateServer'; import type { ServerWithId } from '../../src/servers/data'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -10,7 +10,7 @@ jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom') describe('', () => { const createServersMock = jest.fn(); const navigate = jest.fn(); - const servers = { foo: Mock.of({ url: 'https://existing_url.com', apiKey: 'existing_api_key' }) }; + const servers = { foo: fromPartial({ url: 'https://existing_url.com', apiKey: 'existing_api_key' }) }; const setUp = (serversImported = false, importFailed = false) => { (useNavigate as any).mockReturnValue(navigate); diff --git a/test/servers/DeleteServerButton.test.tsx b/test/servers/DeleteServerButton.test.tsx index 4b17fcb0..2b3e69f9 100644 --- a/test/servers/DeleteServerButton.test.tsx +++ b/test/servers/DeleteServerButton.test.tsx @@ -1,7 +1,6 @@ import { screen, waitFor } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ReactNode } from 'react'; -import { Mock } from 'ts-mockery'; -import type { ServerWithId } from '../../src/servers/data'; import { DeleteServerButton as createDeleteServerButton } from '../../src/servers/DeleteServerButton'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -10,7 +9,7 @@ describe('', () => { ({ isOpen }) => <>DeleteServerModal {isOpen ? '[Open]' : '[Closed]'}, ); const setUp = (children?: ReactNode) => renderWithEvents( - ()} textClassName="button">{children}, + {children}, ); it.each([ diff --git a/test/servers/DeleteServerModal.test.tsx b/test/servers/DeleteServerModal.test.tsx index 3df5a2e5..f2f66d42 100644 --- a/test/servers/DeleteServerModal.test.tsx +++ b/test/servers/DeleteServerModal.test.tsx @@ -1,7 +1,6 @@ import { screen, waitFor } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { useNavigate } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; -import type { ServerWithId } from '../../src/servers/data'; import { DeleteServerModal } from '../../src/servers/DeleteServerModal'; import { renderWithEvents } from '../__helpers__/setUpTest'; import { TestModalWrapper } from '../__helpers__/TestModalWrapper'; @@ -20,7 +19,7 @@ describe('', () => { renderModal={(args) => ( ({ name: serverName })} + server={fromPartial({ name: serverName })} deleteServer={deleteServerMock} /> )} diff --git a/test/servers/EditServer.test.tsx b/test/servers/EditServer.test.tsx index f38b2e64..4d680158 100644 --- a/test/servers/EditServer.test.tsx +++ b/test/servers/EditServer.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter, useNavigate } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ReachableServer, SelectedServer } from '../../src/servers/data'; import { EditServer as editServerConstruct } from '../../src/servers/EditServer'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -11,7 +11,7 @@ describe('', () => { const ServerError = jest.fn(); const editServerMock = jest.fn(); const navigate = jest.fn(); - const defaultSelectedServer = Mock.of({ + const defaultSelectedServer = fromPartial({ id: 'abc123', name: 'the_name', url: 'the_url', @@ -31,7 +31,7 @@ describe('', () => { afterEach(jest.clearAllMocks); it('renders nothing if selected server is not reachable', () => { - setUp(Mock.all()); + setUp(fromPartial({})); expect(screen.queryByText('Edit')).not.toBeInTheDocument(); expect(screen.queryByText('Cancel')).not.toBeInTheDocument(); diff --git a/test/servers/ManageServers.test.tsx b/test/servers/ManageServers.test.tsx index b3c97e8f..ce5c2a08 100644 --- a/test/servers/ManageServers.test.tsx +++ b/test/servers/ManageServers.test.tsx @@ -1,6 +1,6 @@ import { screen, waitFor } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ServersMap, ServerWithId } from '../../src/servers/data'; import { ManageServers as createManageServers } from '../../src/servers/ManageServers'; import type { ServersExporter } from '../../src/servers/services/ServersExporter'; @@ -8,7 +8,7 @@ import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { const exportServers = jest.fn(); - const serversExporter = Mock.of({ exportServers }); + const serversExporter = fromPartial({ exportServers }); const useTimeoutToggle = jest.fn().mockReturnValue([false, jest.fn()]); const ManageServers = createManageServers( serversExporter, @@ -16,7 +16,7 @@ describe('', () => { useTimeoutToggle, ({ hasAutoConnect }) => ManageServersRow {hasAutoConnect ? '[YES]' : '[NO]'}, ); - const createServerMock = (value: string, autoConnect = false) => Mock.of( + const createServerMock = (value: string, autoConnect = false) => fromPartial( { id: value, name: value, url: value, autoConnect }, ); const setUp = (servers: ServersMap = {}) => renderWithEvents( diff --git a/test/servers/ManageServersRowDropdown.test.tsx b/test/servers/ManageServersRowDropdown.test.tsx index df8c0946..9d1d536b 100644 --- a/test/servers/ManageServersRowDropdown.test.tsx +++ b/test/servers/ManageServersRowDropdown.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ServerWithId } from '../../src/servers/data'; import { ManageServersRowDropdown as createManageServersRowDropdown } from '../../src/servers/ManageServersRowDropdown'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -11,7 +11,7 @@ describe('', () => { ); const setAutoConnect = jest.fn(); const setUp = (autoConnect = false) => { - const server = Mock.of({ id: 'abc123', autoConnect }); + const server = fromPartial({ id: 'abc123', autoConnect }); return renderWithEvents( diff --git a/test/servers/Overview.test.tsx b/test/servers/Overview.test.tsx index 0b4c6b6d..bff2b42d 100644 --- a/test/servers/Overview.test.tsx +++ b/test/servers/Overview.test.tsx @@ -1,14 +1,9 @@ import { screen, waitFor } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { MercureInfo } from '../../src/mercure/reducers/mercureInfo'; -import type { ReachableServer } from '../../src/servers/data'; import { Overview as overviewCreator } from '../../src/servers/Overview'; -import type { Settings } from '../../src/settings/reducers/settings'; -import type { ShortUrlsList as ShortUrlsListState } from '../../src/short-urls/reducers/shortUrlsList'; -import type { TagsList } from '../../src/tags/reducers/tagsList'; import { prettify } from '../../src/utils/helpers/numbers'; -import type { VisitsOverview } from '../../src/visits/reducers/visitsOverview'; import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { @@ -28,18 +23,18 @@ describe('', () => { listShortUrls={listShortUrls} listTags={listTags} loadVisitsOverview={loadVisitsOverview} - shortUrlsList={Mock.of({ loading, shortUrls })} - tagsList={Mock.of({ loading, tags: ['foo', 'bar', 'baz'] })} - visitsOverview={Mock.of({ + shortUrlsList={fromPartial({ loading, shortUrls })} + tagsList={fromPartial({ loading, tags: ['foo', 'bar', 'baz'] })} + visitsOverview={fromPartial({ loading, nonOrphanVisits: { total: 3456, bots: 1000, nonBots: 2456 }, orphanVisits: { total: 28, bots: 15, nonBots: 13 }, })} - selectedServer={Mock.of({ id: serverId })} + selectedServer={fromPartial({ id: serverId })} createNewVisits={jest.fn()} loadMercureInfo={jest.fn()} - mercureInfo={Mock.all()} - settings={Mock.of({ visits: { excludeBots } })} + mercureInfo={fromPartial({})} + settings={fromPartial({ visits: { excludeBots } })} /> , ); diff --git a/test/servers/ServersDropdown.test.tsx b/test/servers/ServersDropdown.test.tsx index b22ceb24..c78ed5f6 100644 --- a/test/servers/ServersDropdown.test.tsx +++ b/test/servers/ServersDropdown.test.tsx @@ -1,16 +1,16 @@ import { screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { values } from 'ramda'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; -import type { ServersMap, ServerWithId } from '../../src/servers/data'; +import type { ServersMap } from '../../src/servers/data'; import { ServersDropdown } from '../../src/servers/ServersDropdown'; import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { const fallbackServers: ServersMap = { - '1a': Mock.of({ name: 'foo', id: '1a' }), - '2b': Mock.of({ name: 'bar', id: '2b' }), - '3c': Mock.of({ name: 'baz', id: '3c' }), + '1a': fromPartial({ name: 'foo', id: '1a' }), + '2b': fromPartial({ name: 'bar', id: '2b' }), + '3c': fromPartial({ name: 'baz', id: '3c' }), }; const setUp = (servers: ServersMap = fallbackServers) => renderWithEvents( , diff --git a/test/servers/ServersListGroup.test.tsx b/test/servers/ServersListGroup.test.tsx index 5c0e45a5..d99f68e0 100644 --- a/test/servers/ServersListGroup.test.tsx +++ b/test/servers/ServersListGroup.test.tsx @@ -1,13 +1,13 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ServerWithId } from '../../src/servers/data'; import { ServersListGroup } from '../../src/servers/ServersListGroup'; describe('', () => { - const servers = [ - Mock.of({ name: 'foo', id: '123' }), - Mock.of({ name: 'bar', id: '456' }), + const servers: ServerWithId[] = [ + fromPartial({ name: 'foo', id: '123' }), + fromPartial({ name: 'bar', id: '456' }), ]; const setUp = (params: { servers?: ServerWithId[]; withChildren?: boolean; embedded?: boolean }) => { const { servers = [], withChildren = true, embedded } = params; diff --git a/test/servers/helpers/DuplicatedServersModal.test.tsx b/test/servers/helpers/DuplicatedServersModal.test.tsx index 81ef52d3..b4918fc4 100644 --- a/test/servers/helpers/DuplicatedServersModal.test.tsx +++ b/test/servers/helpers/DuplicatedServersModal.test.tsx @@ -1,5 +1,5 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ServerData } from '../../../src/servers/data'; import { DuplicatedServersModal } from '../../../src/servers/helpers/DuplicatedServersModal'; import { renderWithEvents } from '../../__helpers__/setUpTest'; @@ -10,15 +10,16 @@ describe('', () => { const setUp = (duplicatedServers: ServerData[] = []) => renderWithEvents( , ); + const mockServer = (data: Partial = {}) => fromPartial(data); beforeEach(jest.clearAllMocks); it.each([ [[], 0], - [[Mock.all()], 2], - [[Mock.all(), Mock.all()], 2], - [[Mock.all(), Mock.all(), Mock.all()], 3], - [[Mock.all(), Mock.all(), Mock.all(), Mock.all()], 4], + [[mockServer()], 2], + [[mockServer(), mockServer()], 2], + [[mockServer(), mockServer(), mockServer()], 3], + [[mockServer(), mockServer(), mockServer(), mockServer()], 4], ])('renders expected amount of items', (duplicatedServers, expectedItems) => { setUp(duplicatedServers); expect(screen.queryAllByRole('listitem')).toHaveLength(expectedItems); @@ -26,7 +27,7 @@ describe('', () => { it.each([ [ - [Mock.all()], + [mockServer()], { header: 'Duplicated server', firstParagraph: 'There is already a server with:', @@ -35,7 +36,7 @@ describe('', () => { }, ], [ - [Mock.all(), Mock.all()], + [mockServer(), mockServer()], { header: 'Duplicated servers', firstParagraph: 'The next servers already exist:', @@ -54,10 +55,10 @@ describe('', () => { it.each([ [[]], - [[Mock.of({ url: 'url', apiKey: 'apiKey' })]], + [[mockServer({ url: 'url', apiKey: 'apiKey' })]], [[ - Mock.of({ url: 'url_1', apiKey: 'apiKey_1' }), - Mock.of({ url: 'url_2', apiKey: 'apiKey_2' }), + mockServer({ url: 'url_1', apiKey: 'apiKey_1' }), + mockServer({ url: 'url_2', apiKey: 'apiKey_2' }), ]], ])('displays provided server data', (duplicatedServers) => { setUp(duplicatedServers); diff --git a/test/servers/helpers/ImportServersBtn.test.tsx b/test/servers/helpers/ImportServersBtn.test.tsx index 2abc105f..a452e094 100644 --- a/test/servers/helpers/ImportServersBtn.test.tsx +++ b/test/servers/helpers/ImportServersBtn.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ServersMap, ServerWithId } from '../../../src/servers/data'; import type { ImportServersBtnProps } from '../../../src/servers/helpers/ImportServersBtn'; @@ -13,7 +13,7 @@ describe('', () => { const onImportMock = jest.fn(); const createServersMock = jest.fn(); const importServersFromFile = jest.fn().mockResolvedValue([]); - const serversImporterMock = Mock.of({ importServersFromFile }); + const serversImporterMock = fromPartial({ importServersFromFile }); const ImportServersBtn = createImportServersBtn(serversImporterMock); const setUp = (props: Partial = {}, servers: ServersMap = {}) => renderWithEvents( ', () => { ['Save anyway', true], ['Discard', false], ])('creates expected servers depending on selected option in modal', async (btnName, savesDuplicatedServers) => { - const existingServer = Mock.of({ id: 'abc', url: 'existingUrl', apiKey: 'existingApiKey' }); - const newServer = Mock.of({ url: 'newUrl', apiKey: 'newApiKey' }); + const existingServer = fromPartial({ id: 'abc', url: 'existingUrl', apiKey: 'existingApiKey' }); + const newServer = fromPartial({ url: 'newUrl', apiKey: 'newApiKey' }); const { container, user } = setUp({}, { abc: existingServer }); const input = container.querySelector('[type=file]'); importServersFromFile.mockResolvedValue([existingServer, newServer]); diff --git a/test/servers/helpers/ServerError.test.tsx b/test/servers/helpers/ServerError.test.tsx index be428ccf..afad6217 100644 --- a/test/servers/helpers/ServerError.test.tsx +++ b/test/servers/helpers/ServerError.test.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { NonReachableServer, NotFoundServer } from '../../../src/servers/data'; import { ServerError as createServerError } from '../../../src/servers/helpers/ServerError'; @@ -9,7 +9,7 @@ describe('', () => { it.each([ [ - Mock.all(), + fromPartial({}), { found: ['Could not find this Shlink server.'], notFound: [ @@ -20,7 +20,7 @@ describe('', () => { }, ], [ - Mock.of({ id: 'abc123' }), + fromPartial({ id: 'abc123' }), { found: [ 'Oops! Could not connect to this Shlink server.', diff --git a/test/servers/reducers/remoteServers.test.ts b/test/servers/reducers/remoteServers.test.ts index 37b493bb..230488c6 100644 --- a/test/servers/reducers/remoteServers.test.ts +++ b/test/servers/reducers/remoteServers.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { HttpClient } from '../../../src/common/services/HttpClient'; import { fetchServers } from '../../../src/servers/reducers/remoteServers'; @@ -8,7 +8,7 @@ describe('remoteServersReducer', () => { describe('fetchServers', () => { const dispatch = jest.fn(); const fetchJson = jest.fn(); - const httpClient = Mock.of({ fetchJson }); + const httpClient = fromPartial({ fetchJson }); it.each([ [ diff --git a/test/servers/reducers/selectedServer.test.ts b/test/servers/reducers/selectedServer.test.ts index 664d69d8..34609864 100644 --- a/test/servers/reducers/selectedServer.test.ts +++ b/test/servers/reducers/selectedServer.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import { v4 as uuid } from 'uuid'; import type { ShlinkApiClient } from '../../../src/api/services/ShlinkApiClient'; import type { ShlinkState } from '../../../src/container/types'; @@ -15,7 +15,7 @@ import { describe('selectedServerReducer', () => { const dispatch = jest.fn(); const health = jest.fn(); - const buildApiClient = jest.fn().mockReturnValue(Mock.of({ health })); + const buildApiClient = jest.fn().mockReturnValue(fromPartial({ health })); const selectServer = selectServerCreator(buildApiClient); const { reducer } = selectedServerReducerCreator(selectServer); @@ -26,8 +26,7 @@ describe('selectedServerReducer', () => { expect(reducer(null, resetSelectedServer())).toBeNull()); it('returns selected server when action is SELECT_SERVER', () => { - const payload = Mock.of({ id: 'abc123' }); - + const payload = fromPartial({ id: 'abc123' }); expect(reducer(null, selectServer.fulfilled(payload, '', ''))).toEqual(payload); }); }); @@ -66,7 +65,7 @@ describe('selectedServerReducer', () => { it('dispatches error when health endpoint fails', async () => { const id = uuid(); const getState = createGetStateMock(id); - const expectedSelectedServer = Mock.of({ id, serverNotReachable: true }); + const expectedSelectedServer = fromPartial({ id, serverNotReachable: true }); health.mockRejectedValue({}); @@ -78,7 +77,7 @@ describe('selectedServerReducer', () => { it('dispatches error when server is not found', async () => { const id = uuid(); - const getState = jest.fn(() => Mock.of({ servers: {} })); + const getState = jest.fn(() => fromPartial({ servers: {} })); const expectedSelectedServer: NotFoundServer = { serverNotFound: true }; await selectServer(id)(dispatch, getState, {}); @@ -95,9 +94,9 @@ describe('selectedServerReducer', () => { const { middleware } = selectServerListener(selectServer, loadMercureInfo); it.each([ - [Mock.of({ version: '1.2.3' }), 1], - [Mock.of({ serverNotFound: true }), 0], - [Mock.of({ serverNotReachable: true }), 0], + [fromPartial({ version: '1.2.3' }), 1], + [fromPartial({ serverNotFound: true }), 0], + [fromPartial({ serverNotReachable: true }), 0], ])('dispatches loadMercureInfo when provided server is reachable', (payload, expectedCalls) => { middleware({ dispatch, getState })(jest.fn())({ payload, @@ -110,7 +109,7 @@ describe('selectedServerReducer', () => { it('does not dispatch loadMercureInfo when action is not of the proper type', () => { middleware({ dispatch, getState })(jest.fn())({ - payload: Mock.of({ version: '1.2.3' }), + payload: fromPartial({ version: '1.2.3' }), type: 'something_else', }); diff --git a/test/servers/reducers/servers.test.ts b/test/servers/reducers/servers.test.ts index d385eeaf..17637483 100644 --- a/test/servers/reducers/servers.test.ts +++ b/test/servers/reducers/servers.test.ts @@ -1,6 +1,6 @@ +import { fromPartial } from '@total-typescript/shoehorn'; import { dissoc, values } from 'ramda'; -import { Mock } from 'ts-mockery'; -import type { RegularServer, ServerWithId } from '../../../src/servers/data'; +import type { RegularServer, ServersMap, ServerWithId } from '../../../src/servers/data'; import { createServers, deleteServer, @@ -10,9 +10,9 @@ import { } from '../../../src/servers/reducers/servers'; describe('serversReducer', () => { - const list = { - abc123: Mock.of({ id: 'abc123' }), - def456: Mock.of({ id: 'def456' }), + const list: ServersMap = { + abc123: fromPartial({ id: 'abc123' }), + def456: fromPartial({ id: 'def456' }), }; afterEach(jest.clearAllMocks); @@ -31,12 +31,12 @@ describe('serversReducer', () => { })); it('removes server when action is DELETE_SERVER', () => - expect(serversReducer(list, deleteServer(Mock.of({ id: 'abc123' })))).toEqual({ + expect(serversReducer(list, deleteServer(fromPartial({ id: 'abc123' })))).toEqual({ def456: { id: 'def456' }, })); it('appends server when action is CREATE_SERVERS', () => - expect(serversReducer(list, createServers([Mock.of({ id: 'ghi789' })]))).toEqual({ + expect(serversReducer(list, createServers([fromPartial({ id: 'ghi789' })]))).toEqual({ abc123: { id: 'abc123' }, def456: { id: 'def456' }, ghi789: { id: 'ghi789' }, @@ -46,7 +46,7 @@ describe('serversReducer', () => { [true], [false], ])('returns state as it is when trying to set auto-connect on invalid server', (autoConnect) => - expect(serversReducer(list, setAutoConnect(Mock.of({ id: 'invalid' }), autoConnect))).toEqual({ + expect(serversReducer(list, setAutoConnect(fromPartial({ id: 'invalid' }), autoConnect))).toEqual({ abc123: { id: 'abc123' }, def456: { id: 'def456' }, })); @@ -59,7 +59,7 @@ describe('serversReducer', () => { expect(serversReducer( listWithDisabledAutoConnect, - setAutoConnect(Mock.of({ id: 'abc123' }), false), + setAutoConnect(fromPartial({ id: 'abc123' }), false), )).toEqual({ abc123: { id: 'abc123', autoConnect: false }, def456: { id: 'def456' }, @@ -74,7 +74,7 @@ describe('serversReducer', () => { expect(serversReducer( listWithEnabledAutoConnect, - setAutoConnect(Mock.of({ id: 'def456' }), true), + setAutoConnect(fromPartial({ id: 'def456' }), true), )).toEqual({ abc123: { id: 'abc123', autoConnect: false }, def456: { id: 'def456', autoConnect: true }, @@ -94,7 +94,7 @@ describe('serversReducer', () => { describe('deleteServer', () => { it('returns expected action', () => { - const serverToDelete = Mock.of({ id: 'abc123' }); + const serverToDelete = fromPartial({ id: 'abc123' }); const { payload } = deleteServer(serverToDelete); expect(payload).toEqual({ id: 'abc123' }); @@ -122,7 +122,7 @@ describe('serversReducer', () => { [true], [false], ])('returns expected action', (autoConnect) => { - const serverToEdit = Mock.of({ id: 'abc123' }); + const serverToEdit = fromPartial({ id: 'abc123' }); const { payload } = setAutoConnect(serverToEdit, autoConnect); expect(payload).toEqual({ serverId: 'abc123', autoConnect }); diff --git a/test/servers/services/ServersExporter.test.ts b/test/servers/services/ServersExporter.test.ts index 796ca5d9..a50a5eeb 100644 --- a/test/servers/services/ServersExporter.test.ts +++ b/test/servers/services/ServersExporter.test.ts @@ -1,10 +1,10 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import { ServersExporter } from '../../../src/servers/services/ServersExporter'; import type { LocalStorage } from '../../../src/utils/services/LocalStorage'; import { appendChild, removeChild, windowMock } from '../../__mocks__/Window.mock'; describe('ServersExporter', () => { - const storageMock = Mock.of({ + const storageMock = fromPartial({ get: jest.fn(() => ({ abc123: { id: 'abc123', @@ -16,7 +16,7 @@ describe('ServersExporter', () => { name: 'bar', autoConnect: false, }, - })), + } as any)), }); const erroneousToCsv = jest.fn(() => { throw new Error(''); @@ -31,7 +31,7 @@ describe('ServersExporter', () => { beforeEach(() => { originalConsole = global.console; - global.console = Mock.of({ error }); + global.console = fromPartial({ error }); (global as any).Blob = class Blob {}; (global as any).URL = { createObjectURL: () => '' }; }); diff --git a/test/servers/services/ServersImporter.test.ts b/test/servers/services/ServersImporter.test.ts index be0a12dc..be909a9c 100644 --- a/test/servers/services/ServersImporter.test.ts +++ b/test/servers/services/ServersImporter.test.ts @@ -1,16 +1,16 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { RegularServer } from '../../../src/servers/data'; import { ServersImporter } from '../../../src/servers/services/ServersImporter'; describe('ServersImporter', () => { - const servers: RegularServer[] = [Mock.all(), Mock.all()]; + const servers: RegularServer[] = [fromPartial({}), fromPartial({})]; const csvjsonMock = jest.fn().mockResolvedValue(servers); const readAsText = jest.fn(); - const fileReaderMock = Mock.of({ + const fileReaderMock = fromPartial({ readAsText, - addEventListener: (_eventName: string, listener: (e: ProgressEvent) => void) => listener( - Mock.of>({ target: { result: '' } }), - ), + addEventListener: ((_eventName: string, listener: (e: ProgressEvent) => void) => listener( + fromPartial({ target: { result: '' } }), + )) as any, }); const importer = new ServersImporter(csvjsonMock, () => fileReaderMock); @@ -28,7 +28,7 @@ describe('ServersImporter', () => { csvjsonMock.mockRejectedValue(expectedError); - await expect(importer.importServersFromFile(Mock.of({ type: 'text/html' }))).rejects.toEqual(expectedError); + await expect(importer.importServersFromFile(fromPartial({ type: 'text/html' }))).rejects.toEqual(expectedError); }); it.each([ @@ -57,7 +57,7 @@ describe('ServersImporter', () => { ])('rejects with error if provided file does not parse to valid list of servers', async (parsedObject) => { csvjsonMock.mockResolvedValue(parsedObject); - await expect(importer.importServersFromFile(Mock.of({ type: 'text/html' }))).rejects.toEqual( + await expect(importer.importServersFromFile(fromPartial({ type: 'text/html' }))).rejects.toEqual( new Error('Provided file does not have the right format.'), ); }); @@ -78,7 +78,7 @@ describe('ServersImporter', () => { csvjsonMock.mockResolvedValue(expectedServers); - const result = await importer.importServersFromFile(Mock.all()); + const result = await importer.importServersFromFile(fromPartial({})); expect(result).toEqual(expectedServers); expect(readAsText).toHaveBeenCalledTimes(1); diff --git a/test/settings/RealTimeUpdatesSettings.test.tsx b/test/settings/RealTimeUpdatesSettings.test.tsx index 98586dda..63d2c65c 100644 --- a/test/settings/RealTimeUpdatesSettings.test.tsx +++ b/test/settings/RealTimeUpdatesSettings.test.tsx @@ -1,9 +1,8 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import { RealTimeUpdatesSettings } from '../../src/settings/RealTimeUpdatesSettings'; import type { RealTimeUpdatesSettings as RealTimeUpdatesSettingsOptions, - Settings, } from '../../src/settings/reducers/settings'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -12,7 +11,7 @@ describe('', () => { const setRealTimeUpdatesInterval = jest.fn(); const setUp = (realTimeUpdates: Partial = {}) => renderWithEvents( ({ realTimeUpdates })} + settings={fromPartial({ realTimeUpdates })} toggleRealTimeUpdates={toggleRealTimeUpdates} setRealTimeUpdatesInterval={setRealTimeUpdatesInterval} />, diff --git a/test/settings/ShortUrlCreationSettings.test.tsx b/test/settings/ShortUrlCreationSettings.test.tsx index 220ff554..45dcd4b2 100644 --- a/test/settings/ShortUrlCreationSettings.test.tsx +++ b/test/settings/ShortUrlCreationSettings.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { Settings, ShortUrlCreationSettings as ShortUrlsSettings } from '../../src/settings/reducers/settings'; +import { fromPartial } from '@total-typescript/shoehorn'; +import type { ShortUrlCreationSettings as ShortUrlsSettings } from '../../src/settings/reducers/settings'; import { ShortUrlCreationSettings } from '../../src/settings/ShortUrlCreationSettings'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -8,7 +8,7 @@ describe('', () => { const setShortUrlCreationSettings = jest.fn(); const setUp = (shortUrlCreation?: ShortUrlsSettings) => renderWithEvents( ({ shortUrlCreation })} + settings={fromPartial({ shortUrlCreation })} setShortUrlCreationSettings={setShortUrlCreationSettings} />, ); diff --git a/test/settings/ShortUrlsListSettings.test.tsx b/test/settings/ShortUrlsListSettings.test.tsx index c0cd1a4b..889559f4 100644 --- a/test/settings/ShortUrlsListSettings.test.tsx +++ b/test/settings/ShortUrlsListSettings.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { Settings, ShortUrlsListSettings as ShortUrlsSettings } from '../../src/settings/reducers/settings'; +import { fromPartial } from '@total-typescript/shoehorn'; +import type { ShortUrlsListSettings as ShortUrlsSettings } from '../../src/settings/reducers/settings'; import { ShortUrlsListSettings } from '../../src/settings/ShortUrlsListSettings'; import type { ShortUrlsOrder } from '../../src/short-urls/data'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -8,7 +8,7 @@ import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { const setSettings = jest.fn(); const setUp = (shortUrlsList?: ShortUrlsSettings) => renderWithEvents( - ({ shortUrlsList })} setShortUrlsListSettings={setSettings} />, + , ); afterEach(jest.clearAllMocks); diff --git a/test/settings/TagsSettings.test.tsx b/test/settings/TagsSettings.test.tsx index 050e4b1c..c3bf1b20 100644 --- a/test/settings/TagsSettings.test.tsx +++ b/test/settings/TagsSettings.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { Settings, TagsSettings as TagsSettingsOptions } from '../../src/settings/reducers/settings'; +import { fromPartial } from '@total-typescript/shoehorn'; +import type { TagsSettings as TagsSettingsOptions } from '../../src/settings/reducers/settings'; import { TagsSettings } from '../../src/settings/TagsSettings'; import type { TagsOrder } from '../../src/tags/data/TagsListChildrenProps'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -8,7 +8,7 @@ import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { const setTagsSettings = jest.fn(); const setUp = (tags?: TagsSettingsOptions) => renderWithEvents( - ({ tags })} setTagsSettings={setTagsSettings} />, + , ); afterEach(jest.clearAllMocks); diff --git a/test/settings/UserInterfaceSettings.test.tsx b/test/settings/UserInterfaceSettings.test.tsx index 0ca68e86..b0ecf856 100644 --- a/test/settings/UserInterfaceSettings.test.tsx +++ b/test/settings/UserInterfaceSettings.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { Settings, UiSettings } from '../../src/settings/reducers/settings'; +import { fromPartial } from '@total-typescript/shoehorn'; +import type { UiSettings } from '../../src/settings/reducers/settings'; import { UserInterfaceSettings } from '../../src/settings/UserInterfaceSettings'; import type { Theme } from '../../src/utils/theme'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -8,7 +8,7 @@ import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { const setUiSettings = jest.fn(); const setUp = (ui?: UiSettings) => renderWithEvents( - ({ ui })} setUiSettings={setUiSettings} />, + , ); afterEach(jest.clearAllMocks); diff --git a/test/settings/VisitsSettings.test.tsx b/test/settings/VisitsSettings.test.tsx index 3326b75e..1bc729f4 100644 --- a/test/settings/VisitsSettings.test.tsx +++ b/test/settings/VisitsSettings.test.tsx @@ -1,5 +1,5 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { Settings } from '../../src/settings/reducers/settings'; import { VisitsSettings } from '../../src/settings/VisitsSettings'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -7,7 +7,7 @@ import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { const setVisitsSettings = jest.fn(); const setUp = (settings: Partial = {}) => renderWithEvents( - (settings)} setVisitsSettings={setVisitsSettings} />, + , ); afterEach(jest.clearAllMocks); @@ -21,10 +21,10 @@ describe('', () => { }); it.each([ - [Mock.all(), 'Last 30 days'], - [Mock.of({ visits: {} }), 'Last 30 days'], + [fromPartial({}), 'Last 30 days'], + [fromPartial({ visits: {} }), 'Last 30 days'], [ - Mock.of({ + fromPartial({ visits: { defaultInterval: 'last7Days', }, @@ -32,7 +32,7 @@ describe('', () => { 'Last 7 days', ], [ - Mock.of({ + fromPartial({ visits: { defaultInterval: 'today', }, @@ -63,17 +63,17 @@ describe('', () => { it.each([ [ - Mock.all(), + fromPartial({}), /The visits coming from potential bots will be included.$/, /The visits coming from potential bots will be excluded.$/, ], [ - Mock.of({ visits: { excludeBots: false } }), + fromPartial({ visits: { excludeBots: false } }), /The visits coming from potential bots will be included.$/, /The visits coming from potential bots will be excluded.$/, ], [ - Mock.of({ visits: { excludeBots: true } }), + fromPartial({ visits: { excludeBots: true } }), /The visits coming from potential bots will be excluded.$/, /The visits coming from potential bots will be included.$/, ], diff --git a/test/settings/helpers/index.test.ts b/test/settings/helpers/index.test.ts index 6b7c188f..e69fb899 100644 --- a/test/settings/helpers/index.test.ts +++ b/test/settings/helpers/index.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkState } from '../../../src/container/types'; import { migrateDeprecatedSettings } from '../../../src/settings/helpers'; @@ -9,7 +9,7 @@ describe('settings-helpers', () => { }); it('updates settings as expected', () => { - const state = Mock.of({ + const state = fromPartial({ settings: { visits: { defaultInterval: 'last180days' as any, diff --git a/test/short-urls/CreateShortUrl.test.tsx b/test/short-urls/CreateShortUrl.test.tsx index 68a3dbbc..55a2c3be 100644 --- a/test/short-urls/CreateShortUrl.test.tsx +++ b/test/short-urls/CreateShortUrl.test.tsx @@ -1,6 +1,5 @@ import { render, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { Settings } from '../../src/settings/reducers/settings'; +import { fromPartial } from '@total-typescript/shoehorn'; import { CreateShortUrl as createShortUrlsCreator } from '../../src/short-urls/CreateShortUrl'; import type { ShortUrlCreation } from '../../src/short-urls/reducers/shortUrlCreation'; @@ -8,7 +7,7 @@ describe('', () => { const ShortUrlForm = () => ShortUrlForm; const CreateShortUrlResult = () => CreateShortUrlResult; const shortUrlCreation = { validateUrls: true }; - const shortUrlCreationResult = Mock.all(); + const shortUrlCreationResult = fromPartial({}); const createShortUrl = jest.fn(async () => Promise.resolve()); const CreateShortUrl = createShortUrlsCreator(ShortUrlForm, CreateShortUrlResult); const setUp = () => render( @@ -17,7 +16,7 @@ describe('', () => { createShortUrl={createShortUrl} selectedServer={null} resetCreateShortUrl={() => {}} - settings={Mock.of({ shortUrlCreation })} + settings={fromPartial({ shortUrlCreation })} />, ); diff --git a/test/short-urls/EditShortUrl.test.tsx b/test/short-urls/EditShortUrl.test.tsx index 77767c47..f1efdcba 100644 --- a/test/short-urls/EditShortUrl.test.tsx +++ b/test/short-urls/EditShortUrl.test.tsx @@ -1,8 +1,6 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; -import type { Settings } from '../../src/settings/reducers/settings'; -import type { ShortUrl } from '../../src/short-urls/data'; import { EditShortUrl as createEditShortUrl } from '../../src/short-urls/EditShortUrl'; import type { ShortUrlDetail } from '../../src/short-urls/reducers/shortUrlDetail'; import type { ShortUrlEdition } from '../../src/short-urls/reducers/shortUrlEdition'; @@ -13,10 +11,10 @@ describe('', () => { const setUp = (detail: Partial = {}, edition: Partial = {}) => render( ({ shortUrlCreation })} + settings={fromPartial({ shortUrlCreation })} selectedServer={null} - shortUrlDetail={Mock.of(detail)} - shortUrlEdition={Mock.of(edition)} + shortUrlDetail={fromPartial(detail)} + shortUrlEdition={fromPartial(edition)} getShortUrlDetail={jest.fn()} editShortUrl={jest.fn(async () => Promise.resolve())} /> @@ -38,7 +36,7 @@ describe('', () => { }); it('renders form when detail properly loads', () => { - setUp({ shortUrl: Mock.of({ meta: {} }) }); + setUp({ shortUrl: fromPartial({ meta: {} }) }); expect(screen.getByText('ShortUrlForm')).toBeInTheDocument(); expect(screen.queryByText('Loading...')).not.toBeInTheDocument(); diff --git a/test/short-urls/Paginator.test.tsx b/test/short-urls/Paginator.test.tsx index 36f215f8..cde9462c 100644 --- a/test/short-urls/Paginator.test.tsx +++ b/test/short-urls/Paginator.test.tsx @@ -1,12 +1,12 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ShlinkPaginator } from '../../src/api/types'; import { Paginator } from '../../src/short-urls/Paginator'; import { ELLIPSIS } from '../../src/utils/helpers/pagination'; describe('', () => { - const buildPaginator = (pagesCount?: number) => Mock.of({ pagesCount, currentPage: 1 }); + const buildPaginator = (pagesCount?: number) => fromPartial({ pagesCount, currentPage: 1 }); const setUp = (paginator?: ShlinkPaginator, currentQueryString?: string) => render( diff --git a/test/short-urls/ShortUrlForm.test.tsx b/test/short-urls/ShortUrlForm.test.tsx index da31944d..7d94b956 100644 --- a/test/short-urls/ShortUrlForm.test.tsx +++ b/test/short-urls/ShortUrlForm.test.tsx @@ -1,7 +1,7 @@ import { screen } from '@testing-library/react'; import type { UserEvent } from '@testing-library/user-event/setup/setup'; +import { fromPartial } from '@total-typescript/shoehorn'; import { formatISO } from 'date-fns'; -import { Mock } from 'ts-mockery'; import type { ReachableServer, SelectedServer } from '../../src/servers/data'; import type { Mode } from '../../src/short-urls/ShortUrlForm'; import { ShortUrlForm as createShortUrlForm } from '../../src/short-urls/ShortUrlForm'; @@ -51,7 +51,7 @@ describe('', () => { ios: 'https://ios.com', }, }, - Mock.of({ version: '3.5.0' }), + fromPartial({ version: '3.5.0' }), ], ])('saves short URL with data set in form controls', async (extraFields, extraExpectedValues, selectedServer) => { const { user } = setUp(selectedServer); @@ -102,7 +102,7 @@ describe('', () => { [undefined, false, undefined], ['old title', false, null], ])('sends expected title based on original and new values', async (originalTitle, withNewTitle, expectedSentTitle) => { - const { user } = setUp(Mock.of({ version: '2.6.0' }), 'create', originalTitle); + const { user } = setUp(fromPartial({ version: '2.6.0' }), 'create', originalTitle); await user.type(screen.getByPlaceholderText('URL to be shortened'), 'https://long-domain.com/foo/bar'); await user.clear(screen.getByPlaceholderText('Title')); @@ -117,10 +117,10 @@ describe('', () => { }); it.each([ - [Mock.of({ version: '3.0.0' }), false], - [Mock.of({ version: '3.4.0' }), false], - [Mock.of({ version: '3.5.0' }), true], - [Mock.of({ version: '3.6.0' }), true], + [fromPartial({ version: '3.0.0' }), false], + [fromPartial({ version: '3.4.0' }), false], + [fromPartial({ version: '3.5.0' }), true], + [fromPartial({ version: '3.6.0' }), true], ])('shows device-specific long URLs only for servers supporting it', (selectedServer, fieldsExist) => { setUp(selectedServer); const placeholders = ['Android-specific redirection', 'iOS-specific redirection', 'Desktop-specific redirection']; diff --git a/test/short-urls/ShortUrlsFilteringBar.test.tsx b/test/short-urls/ShortUrlsFilteringBar.test.tsx index 3c89587f..24f00e63 100644 --- a/test/short-urls/ShortUrlsFilteringBar.test.tsx +++ b/test/short-urls/ShortUrlsFilteringBar.test.tsx @@ -1,9 +1,8 @@ import { screen, waitFor } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { endOfDay, formatISO, startOfDay } from 'date-fns'; import { MemoryRouter, useLocation, useNavigate } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ReachableServer, SelectedServer } from '../../src/servers/data'; -import type { Settings } from '../../src/settings/reducers/settings'; import { ShortUrlsFilteringBar as filteringBarCreator } from '../../src/short-urls/ShortUrlsFilteringBar'; import { formatDate } from '../../src/utils/helpers/date'; import type { DateRange } from '../../src/utils/helpers/dateIntervals'; @@ -28,10 +27,10 @@ describe('', () => { return renderWithEvents( ()} + selectedServer={selectedServer ?? fromPartial({})} order={{}} handleOrderBy={handleOrderBy} - settings={Mock.of({ visits: {} })} + settings={fromPartial({ visits: {} })} /> , ); @@ -74,12 +73,12 @@ describe('', () => { }); it.each([ - ['tags=foo,bar,baz', Mock.of({ version: '3.0.0' }), true], - ['tags=foo,bar', Mock.of({ version: '3.1.0' }), true], - ['tags=foo', Mock.of({ version: '3.0.0' }), false], - ['', Mock.of({ version: '3.0.0' }), false], - ['tags=foo,bar,baz', Mock.of({ version: '2.10.0' }), false], - ['', Mock.of({ version: '2.10.0' }), false], + ['tags=foo,bar,baz', fromPartial({ version: '3.0.0' }), true], + ['tags=foo,bar', fromPartial({ version: '3.1.0' }), true], + ['tags=foo', fromPartial({ version: '3.0.0' }), false], + ['', fromPartial({ version: '3.0.0' }), false], + ['tags=foo,bar,baz', fromPartial({ version: '2.10.0' }), false], + ['', fromPartial({ version: '2.10.0' }), false], ])( 'renders tags mode toggle if the server supports it and there is more than one tag selected', (search, selectedServer, shouldHaveComponent) => { @@ -98,7 +97,7 @@ describe('', () => { ['&tagsMode=all', 'With all the tags.'], ['&tagsMode=any', 'With any of the tags.'], ])('expected tags mode tooltip title', async (initialTagsMode, expectedToggleText) => { - const { user } = setUp(`tags=foo,bar${initialTagsMode}`, Mock.of({ version: '3.0.0' })); + const { user } = setUp(`tags=foo,bar${initialTagsMode}`, fromPartial({ version: '3.0.0' })); await user.hover(screen.getByLabelText('Change tags mode')); expect(await screen.findByRole('tooltip')).toHaveTextContent(expectedToggleText); @@ -109,7 +108,7 @@ describe('', () => { ['&tagsMode=all', 'tagsMode=any'], ['&tagsMode=any', 'tagsMode=all'], ])('redirects to first page when tags mode changes', async (initialTagsMode, expectedRedirectTagsMode) => { - const { user } = setUp(`tags=foo,bar${initialTagsMode}`, Mock.of({ version: '3.0.0' })); + const { user } = setUp(`tags=foo,bar${initialTagsMode}`, fromPartial({ version: '3.0.0' })); expect(navigate).not.toHaveBeenCalled(); await user.click(screen.getByLabelText('Change tags mode')); @@ -127,7 +126,7 @@ describe('', () => { ['excludePastValidUntil=false', /Exclude enabled in the past/, 'excludePastValidUntil=true'], ['excludePastValidUntil=true', /Exclude enabled in the past/, 'excludePastValidUntil=false'], ])('allows to toggle filters through filtering dropdown', async (search, menuItemName, expectedQuery) => { - const { user } = setUp(search, Mock.of({ version: '3.4.0' })); + const { user } = setUp(search, fromPartial({ version: '3.4.0' })); const toggleFilter = async (name: RegExp) => { await user.click(screen.getByRole('button', { name: 'Filters' })); await waitFor(() => screen.findByRole('menu')); diff --git a/test/short-urls/ShortUrlsList.test.tsx b/test/short-urls/ShortUrlsList.test.tsx index 38ddef0e..09b40042 100644 --- a/test/short-urls/ShortUrlsList.test.tsx +++ b/test/short-urls/ShortUrlsList.test.tsx @@ -1,10 +1,9 @@ import { screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter, useNavigate } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub'; -import type { ReachableServer } from '../../src/servers/data'; import type { Settings } from '../../src/settings/reducers/settings'; -import type { ShortUrl, ShortUrlsOrder } from '../../src/short-urls/data'; +import type { ShortUrlsOrder } from '../../src/short-urls/data'; import type { ShortUrlsList as ShortUrlsListModel } from '../../src/short-urls/reducers/shortUrlsList'; import { ShortUrlsList as createShortUrlsList } from '../../src/short-urls/ShortUrlsList'; import type { ShortUrlsTableType } from '../../src/short-urls/ShortUrlsTable'; @@ -22,15 +21,15 @@ describe('', () => { const ShortUrlsFilteringBar = () => ShortUrlsFilteringBar; const listShortUrlsMock = jest.fn(); const navigate = jest.fn(); - const shortUrlsList = Mock.of({ + const shortUrlsList = fromPartial({ shortUrls: { data: [ - Mock.of({ + { shortCode: 'testShortCode', shortUrl: 'https://www.example.com/testShortUrl', longUrl: 'https://www.example.com/testLongUrl', tags: ['test tag'], - }), + }, ], pagination: { pagesCount: 3 }, }, @@ -39,11 +38,11 @@ describe('', () => { const setUp = (settings: Partial = {}, version: SemVer = '3.0.0') => renderWithEvents( ({ mercureInfo: { loading: true } })} + {...fromPartial({ mercureInfo: { loading: true } })} listShortUrls={listShortUrlsMock} shortUrlsList={shortUrlsList} - selectedServer={Mock.of({ id: '1', version })} - settings={Mock.of(settings)} + selectedServer={fromPartial({ id: '1', version })} + settings={fromPartial(settings)} /> , ); @@ -81,9 +80,9 @@ describe('', () => { }); it.each([ - [Mock.of({ field: 'visits', dir: 'ASC' }), 'visits', 'ASC'], - [Mock.of({ field: 'title', dir: 'DESC' }), 'title', 'DESC'], - [Mock.all(), undefined, undefined], + [fromPartial({ field: 'visits', dir: 'ASC' }), 'visits', 'ASC'], + [fromPartial({ field: 'title', dir: 'DESC' }), 'title', 'DESC'], + [fromPartial({}), undefined, undefined], ])('has expected initial ordering based on settings', (defaultOrdering, field, dir) => { setUp({ shortUrlsList: { defaultOrdering } }); expect(listShortUrlsMock).toHaveBeenCalledWith(expect.objectContaining({ @@ -92,23 +91,23 @@ describe('', () => { }); it.each([ - [Mock.of({ + [fromPartial({ shortUrlsList: { defaultOrdering: { field: 'visits', dir: 'ASC' }, }, }), '3.3.0' as SemVer, { field: 'visits', dir: 'ASC' }], - [Mock.of({ + [fromPartial({ shortUrlsList: { defaultOrdering: { field: 'visits', dir: 'ASC' }, }, visits: { excludeBots: true }, }), '3.3.0' as SemVer, { field: 'visits', dir: 'ASC' }], - [Mock.of({ + [fromPartial({ shortUrlsList: { defaultOrdering: { field: 'visits', dir: 'ASC' }, }, }), '3.4.0' as SemVer, { field: 'visits', dir: 'ASC' }], - [Mock.of({ + [fromPartial({ shortUrlsList: { defaultOrdering: { field: 'visits', dir: 'ASC' }, }, diff --git a/test/short-urls/ShortUrlsTable.test.tsx b/test/short-urls/ShortUrlsTable.test.tsx index e083d71a..23d07a57 100644 --- a/test/short-urls/ShortUrlsTable.test.tsx +++ b/test/short-urls/ShortUrlsTable.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { ReachableServer, SelectedServer } from '../../src/servers/data'; +import { fromPartial } from '@total-typescript/shoehorn'; +import type { SelectedServer } from '../../src/servers/data'; import type { ShortUrlsOrderableFields } from '../../src/short-urls/data'; import { SHORT_URLS_ORDERABLE_FIELDS } from '../../src/short-urls/data'; import type { ShortUrlsList } from '../../src/short-urls/reducers/shortUrlsList'; @@ -8,7 +8,7 @@ import { ShortUrlsTable as shortUrlsTableCreator } from '../../src/short-urls/Sh import { renderWithEvents } from '../__helpers__/setUpTest'; describe('', () => { - const shortUrlsList = Mock.all(); + const shortUrlsList = fromPartial({}); const orderByColumn = jest.fn(); const ShortUrlsTable = shortUrlsTableCreator(() => ShortUrlsRow); const setUp = (server: SelectedServer = null) => renderWithEvents( @@ -56,7 +56,7 @@ describe('', () => { }); it('should render composed title column', () => { - setUp(Mock.of({ version: '2.0.0' })); + setUp(fromPartial({ version: '2.0.0' })); const { innerHTML } = screen.getAllByRole('columnheader')[2]; diff --git a/test/short-urls/helpers/CreateShortUrlResult.test.tsx b/test/short-urls/helpers/CreateShortUrlResult.test.tsx index 0c07b109..3293f822 100644 --- a/test/short-urls/helpers/CreateShortUrlResult.test.tsx +++ b/test/short-urls/helpers/CreateShortUrlResult.test.tsx @@ -1,6 +1,5 @@ import { screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { ShortUrl } from '../../../src/short-urls/data'; +import { fromPartial } from '@total-typescript/shoehorn'; import { CreateShortUrlResult as createResult } from '../../../src/short-urls/helpers/CreateShortUrlResult'; import type { ShortUrlCreation } from '../../../src/short-urls/reducers/shortUrlCreation'; import type { TimeoutToggle } from '../../../src/utils/helpers/hooks'; @@ -28,14 +27,14 @@ describe('', () => { it('renders a result message when result is provided', () => { setUp( - { result: Mock.of({ shortUrl: 'https://s.test/abc123' }), saving: false, saved: true, error: false }, + { result: fromPartial({ shortUrl: 'https://s.test/abc123' }), saving: false, saved: true, error: false }, ); expect(screen.getByText(/The short URL is/)).toHaveTextContent('Great! The short URL is https://s.test/abc123'); }); it('Invokes tooltip timeout when copy to clipboard button is clicked', async () => { const { user } = setUp( - { result: Mock.of({ shortUrl: 'https://s.test/abc123' }), saving: false, saved: true, error: false }, + { result: fromPartial({ shortUrl: 'https://s.test/abc123' }), saving: false, saved: true, error: false }, ); expect(copyToClipboard).not.toHaveBeenCalled(); diff --git a/test/short-urls/helpers/DeleteShortUrlModal.test.tsx b/test/short-urls/helpers/DeleteShortUrlModal.test.tsx index fbff806c..35671459 100644 --- a/test/short-urls/helpers/DeleteShortUrlModal.test.tsx +++ b/test/short-urls/helpers/DeleteShortUrlModal.test.tsx @@ -1,6 +1,6 @@ import { screen, waitFor } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { InvalidShortUrlDeletion, ProblemDetailsError } from '../../../src/api/types/errors'; +import { fromPartial } from '@total-typescript/shoehorn'; +import type { InvalidShortUrlDeletion } from '../../../src/api/types/errors'; import { ErrorTypeV2, ErrorTypeV3 } from '../../../src/api/types/errors'; import type { ShortUrl } from '../../../src/short-urls/data'; import { DeleteShortUrlModal } from '../../../src/short-urls/helpers/DeleteShortUrlModal'; @@ -9,7 +9,7 @@ import { renderWithEvents } from '../../__helpers__/setUpTest'; import { TestModalWrapper } from '../../__helpers__/TestModalWrapper'; describe('', () => { - const shortUrl = Mock.of({ + const shortUrl = fromPartial({ tags: [], shortCode: 'abc123', longUrl: 'https://long-domain.com/foo/bar', @@ -22,7 +22,7 @@ describe('', () => { (shortUrlDeletion)} + shortUrlDeletion={fromPartial(shortUrlDeletion)} deleteShortUrl={deleteShortUrl} shortUrlDeleted={shortUrlDeleted} resetDeleteShortUrl={jest.fn()} @@ -38,7 +38,7 @@ describe('', () => { loading: false, error: true, shortCode: 'abc123', - errorData: Mock.of({ type: 'OTHER_ERROR' }), + errorData: fromPartial({ type: 'OTHER_ERROR' }), }); expect(screen.getByText('Something went wrong while deleting the URL :(').parentElement).not.toHaveClass( 'bg-warning', @@ -46,8 +46,8 @@ describe('', () => { }); it.each([ - [Mock.of({ type: ErrorTypeV3.INVALID_SHORT_URL_DELETION })], - [Mock.of({ type: ErrorTypeV2.INVALID_SHORT_URL_DELETION })], + [fromPartial({ type: ErrorTypeV3.INVALID_SHORT_URL_DELETION })], + [fromPartial({ type: ErrorTypeV2.INVALID_SHORT_URL_DELETION })], ])('shows specific error when threshold error occurs', (errorData) => { setUp({ loading: false, error: true, shortCode: 'abc123', errorData }); expect(screen.getByText('Something went wrong while deleting the URL :(').parentElement).toHaveClass('bg-warning'); diff --git a/test/short-urls/helpers/ExportShortUrlsBtn.test.tsx b/test/short-urls/helpers/ExportShortUrlsBtn.test.tsx index 6f335c62..0724215b 100644 --- a/test/short-urls/helpers/ExportShortUrlsBtn.test.tsx +++ b/test/short-urls/helpers/ExportShortUrlsBtn.test.tsx @@ -1,8 +1,8 @@ import { screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ReportExporter } from '../../../src/common/services/ReportExporter'; -import type { NotFoundServer, ReachableServer, SelectedServer } from '../../../src/servers/data'; +import type { NotFoundServer, SelectedServer } from '../../../src/servers/data'; import { ExportShortUrlsBtn as createExportShortUrlsBtn } from '../../../src/short-urls/helpers/ExportShortUrlsBtn'; import { renderWithEvents } from '../../__helpers__/setUpTest'; @@ -10,11 +10,11 @@ describe('', () => { const listShortUrls = jest.fn(); const buildShlinkApiClient = jest.fn().mockReturnValue({ listShortUrls }); const exportShortUrls = jest.fn(); - const reportExporter = Mock.of({ exportShortUrls }); + const reportExporter = fromPartial({ exportShortUrls }); const ExportShortUrlsBtn = createExportShortUrlsBtn(buildShlinkApiClient, reportExporter); const setUp = (amount?: number, selectedServer?: SelectedServer) => renderWithEvents( - ()} amount={amount} /> + , ); @@ -31,7 +31,7 @@ describe('', () => { it.each([ [null], - [Mock.of()], + [fromPartial({})], ])('does nothing on click if selected server is not reachable', async (selectedServer) => { const { user } = setUp(0, selectedServer); @@ -49,7 +49,7 @@ describe('', () => { [385, 20], ])('loads proper amount of pages based on the amount of results', async (amount, expectedPageLoads) => { listShortUrls.mockResolvedValue({ data: [] }); - const { user } = setUp(amount, Mock.of({ id: '123' })); + const { user } = setUp(amount, fromPartial({ id: '123' })); await user.click(screen.getByRole('button')); diff --git a/test/short-urls/helpers/QrCodeModal.test.tsx b/test/short-urls/helpers/QrCodeModal.test.tsx index 9dc25726..2a43b638 100644 --- a/test/short-urls/helpers/QrCodeModal.test.tsx +++ b/test/short-urls/helpers/QrCodeModal.test.tsx @@ -1,21 +1,18 @@ import { fireEvent, screen } from '@testing-library/react'; -import { Mock } from 'ts-mockery'; -import type { ImageDownloader } from '../../../src/common/services/ImageDownloader'; -import type { ReachableServer } from '../../../src/servers/data'; -import type { ShortUrl } from '../../../src/short-urls/data'; +import { fromPartial } from '@total-typescript/shoehorn'; import { QrCodeModal as createQrCodeModal } from '../../../src/short-urls/helpers/QrCodeModal'; import type { SemVer } from '../../../src/utils/helpers/version'; import { renderWithEvents } from '../../__helpers__/setUpTest'; describe('', () => { const saveImage = jest.fn().mockReturnValue(Promise.resolve()); - const QrCodeModal = createQrCodeModal(Mock.of({ saveImage })); + const QrCodeModal = createQrCodeModal(fromPartial({ saveImage })); const shortUrl = 'https://s.test/abc123'; const setUp = (version: SemVer = '2.8.0') => renderWithEvents( ({ shortUrl })} - selectedServer={Mock.of({ version })} + shortUrl={fromPartial({ shortUrl })} + selectedServer={fromPartial({ version })} toggle={() => {}} />, ); diff --git a/test/short-urls/helpers/ShortUrlDetailLink.test.tsx b/test/short-urls/helpers/ShortUrlDetailLink.test.tsx index 04187148..5a8bb352 100644 --- a/test/short-urls/helpers/ShortUrlDetailLink.test.tsx +++ b/test/short-urls/helpers/ShortUrlDetailLink.test.tsx @@ -1,6 +1,6 @@ import { render, screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { NotFoundServer, ReachableServer } from '../../../src/servers/data'; import type { ShortUrl } from '../../../src/short-urls/data'; import type { LinkSuffix } from '../../../src/short-urls/helpers/ShortUrlDetailLink'; @@ -10,11 +10,11 @@ describe('', () => { it.each([ [undefined, undefined], [null, null], - [Mock.of({ id: '1' }), null], - [Mock.of({ id: '1' }), undefined], - [Mock.of(), Mock.all()], - [null, Mock.all()], - [undefined, Mock.all()], + [fromPartial({ id: '1' }), null], + [fromPartial({ id: '1' }), undefined], + [fromPartial({}), fromPartial({})], + [null, fromPartial({})], + [undefined, fromPartial({})], ])('only renders a plain span when either server or short URL are not set', (selectedServer, shortUrl) => { render( @@ -28,26 +28,26 @@ describe('', () => { it.each([ [ - Mock.of({ id: '1' }), - Mock.of({ shortCode: 'abc123' }), + fromPartial({ id: '1' }), + fromPartial({ shortCode: 'abc123' }), 'visits' as LinkSuffix, '/server/1/short-code/abc123/visits', ], [ - Mock.of({ id: '3' }), - Mock.of({ shortCode: 'def456', domain: 'example.com' }), + fromPartial({ id: '3' }), + fromPartial({ shortCode: 'def456', domain: 'example.com' }), 'visits' as LinkSuffix, '/server/3/short-code/def456/visits?domain=example.com', ], [ - Mock.of({ id: '1' }), - Mock.of({ shortCode: 'abc123' }), + fromPartial({ id: '1' }), + fromPartial({ shortCode: 'abc123' }), 'edit' as LinkSuffix, '/server/1/short-code/abc123/edit', ], [ - Mock.of({ id: '3' }), - Mock.of({ shortCode: 'def456', domain: 'example.com' }), + fromPartial({ id: '3' }), + fromPartial({ shortCode: 'def456', domain: 'example.com' }), 'edit' as LinkSuffix, '/server/3/short-code/def456/edit?domain=example.com', ], diff --git a/test/short-urls/helpers/ShortUrlStatus.test.tsx b/test/short-urls/helpers/ShortUrlStatus.test.tsx index 1c5ea483..7755bfc8 100644 --- a/test/short-urls/helpers/ShortUrlStatus.test.tsx +++ b/test/short-urls/helpers/ShortUrlStatus.test.tsx @@ -1,6 +1,6 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShlinkVisitsSummary } from '../../../src/api/types'; import type { ShortUrl, ShortUrlMeta } from '../../../src/short-urls/data'; import { ShortUrlStatus } from '../../../src/short-urls/helpers/ShortUrlStatus'; @@ -13,35 +13,35 @@ describe('', () => { it.each([ [ - Mock.of({ validSince: '2099-01-01T10:30:15' }), + fromPartial({ validSince: '2099-01-01T10:30:15' }), {}, 'This short URL will start working on 2099-01-01 10:30.', ], [ - Mock.of({ validUntil: '2020-01-01T10:30:15' }), + fromPartial({ validUntil: '2020-01-01T10:30:15' }), {}, 'This short URL cannot be visited since 2020-01-01 10:30.', ], [ - Mock.of({ maxVisits: 10 }), - Mock.of({ total: 10 }), + fromPartial({ maxVisits: 10 }), + fromPartial({ total: 10 }), 'This short URL cannot be currently visited because it has reached the maximum amount of 10 visits.', ], [ - Mock.of({ maxVisits: 1 }), - Mock.of({ total: 1 }), + fromPartial({ maxVisits: 1 }), + fromPartial({ total: 1 }), 'This short URL cannot be currently visited because it has reached the maximum amount of 1 visit.', ], [{}, {}, 'This short URL can be visited normally.'], - [Mock.of({ validUntil: '2099-01-01T10:30:15' }), {}, 'This short URL can be visited normally.'], - [Mock.of({ validSince: '2020-01-01T10:30:15' }), {}, 'This short URL can be visited normally.'], + [fromPartial({ validUntil: '2099-01-01T10:30:15' }), {}, 'This short URL can be visited normally.'], + [fromPartial({ validSince: '2020-01-01T10:30:15' }), {}, 'This short URL can be visited normally.'], [ - Mock.of({ maxVisits: 10 }), - Mock.of({ total: 1 }), + fromPartial({ maxVisits: 10 }), + fromPartial({ total: 1 }), 'This short URL can be visited normally.', ], ])('shows expected tooltip', async (meta, visitsSummary, expectedTooltip) => { - const { user } = setUp(Mock.of({ meta, visitsSummary })); + const { user } = setUp(fromPartial({ meta, visitsSummary })); await user.hover(screen.getByRole('img', { hidden: true })); await waitFor(() => expect(screen.getByRole('tooltip')).toHaveTextContent(expectedTooltip)); diff --git a/test/short-urls/helpers/ShortUrlVisitsCount.test.tsx b/test/short-urls/helpers/ShortUrlVisitsCount.test.tsx index 8fa8141c..b810fa6e 100644 --- a/test/short-urls/helpers/ShortUrlVisitsCount.test.tsx +++ b/test/short-urls/helpers/ShortUrlVisitsCount.test.tsx @@ -1,6 +1,6 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShortUrl } from '../../../src/short-urls/data'; import { ShortUrlVisitsCount } from '../../../src/short-urls/helpers/ShortUrlVisitsCount'; @@ -14,7 +14,7 @@ describe('', () => { it.each([undefined, {}])('just returns visits when no limits are provided', (meta) => { const visitsCount = 45; - const { container } = setUp(visitsCount, Mock.of({ meta })); + const { container } = setUp(visitsCount, fromPartial({ meta })); expect(container.firstChild).toHaveTextContent(`${visitsCount}`); expect(container.querySelector('.short-urls-visits-count__max-visits-control')).not.toBeInTheDocument(); @@ -24,7 +24,7 @@ describe('', () => { const visitsCount = 45; const maxVisits = 500; const meta = { maxVisits }; - const { container } = setUp(visitsCount, Mock.of({ meta })); + const { container } = setUp(visitsCount, fromPartial({ meta })); expect(container.firstChild).toHaveTextContent(`/ ${maxVisits}`); }); @@ -44,7 +44,7 @@ describe('', () => { 'This short URL will not accept visits after 2023-05-05 15:30', ], { validSince: '2023-01-01T10:00:00', validUntil: '2023-05-05T15:30:30', maxVisits: 100 }], ])('displays proper amount of tooltip list items', async (expectedListItems, meta) => { - const { user } = setUp(100, Mock.of({ meta })); + const { user } = setUp(100, fromPartial({ meta })); await user.hover(screen.getByRole('img', { hidden: true })); await waitFor(() => expect(screen.getByRole('list'))); diff --git a/test/short-urls/helpers/ShortUrlsRow.test.tsx b/test/short-urls/helpers/ShortUrlsRow.test.tsx index f4482422..1d2cd884 100644 --- a/test/short-urls/helpers/ShortUrlsRow.test.tsx +++ b/test/short-urls/helpers/ShortUrlsRow.test.tsx @@ -1,8 +1,8 @@ import { screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { addDays, formatISO, subDays } from 'date-fns'; import { last } from 'ramda'; import { MemoryRouter, useLocation } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ReachableServer } from '../../../src/servers/data'; import type { Settings } from '../../../src/settings/reducers/settings'; import type { ShortUrl, ShortUrlMeta } from '../../../src/short-urls/data'; @@ -28,7 +28,7 @@ jest.mock('react-router-dom', () => ({ describe('', () => { const timeoutToggle = jest.fn(() => true); const useTimeoutToggle = jest.fn(() => [false, timeoutToggle]) as TimeoutToggle; - const server = Mock.of({ url: 'https://s.test' }); + const server = fromPartial({ url: 'https://s.test' }); const shortUrl: ShortUrl = { shortCode: 'abc123', shortUrl: 'https://s.test/abc123', @@ -60,7 +60,7 @@ describe('', () => { selectedServer={server} shortUrl={{ ...shortUrl, title, tags, meta: { ...shortUrl.meta, ...meta } }} onTagClick={() => null} - settings={Mock.of(settings)} + settings={fromPartial(settings)} /> @@ -118,13 +118,13 @@ describe('', () => { it.each([ [{}, '', shortUrl.visitsSummary?.total], - [Mock.of({ visits: { excludeBots: false } }), '', shortUrl.visitsSummary?.total], - [Mock.of({ visits: { excludeBots: true } }), '', shortUrl.visitsSummary?.nonBots], - [Mock.of({ visits: { excludeBots: false } }), 'excludeBots=true', shortUrl.visitsSummary?.nonBots], - [Mock.of({ visits: { excludeBots: true } }), 'excludeBots=true', shortUrl.visitsSummary?.nonBots], + [fromPartial({ visits: { excludeBots: false } }), '', shortUrl.visitsSummary?.total], + [fromPartial({ visits: { excludeBots: true } }), '', shortUrl.visitsSummary?.nonBots], + [fromPartial({ visits: { excludeBots: false } }), 'excludeBots=true', shortUrl.visitsSummary?.nonBots], + [fromPartial({ visits: { excludeBots: true } }), 'excludeBots=true', shortUrl.visitsSummary?.nonBots], [{}, 'excludeBots=true', shortUrl.visitsSummary?.nonBots], - [Mock.of({ visits: { excludeBots: true } }), 'excludeBots=false', shortUrl.visitsSummary?.total], - [Mock.of({ visits: { excludeBots: false } }), 'excludeBots=false', shortUrl.visitsSummary?.total], + [fromPartial({ visits: { excludeBots: true } }), 'excludeBots=false', shortUrl.visitsSummary?.total], + [fromPartial({ visits: { excludeBots: false } }), 'excludeBots=false', shortUrl.visitsSummary?.total], [{}, 'excludeBots=false', shortUrl.visitsSummary?.total], ])('renders visits count in fifth row', (settings, search, expectedAmount) => { setUp({ settings }, search); diff --git a/test/short-urls/helpers/ShortUrlsRowMenu.test.tsx b/test/short-urls/helpers/ShortUrlsRowMenu.test.tsx index ba64ff51..c78ec61b 100644 --- a/test/short-urls/helpers/ShortUrlsRowMenu.test.tsx +++ b/test/short-urls/helpers/ShortUrlsRowMenu.test.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; +import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router-dom'; -import { Mock } from 'ts-mockery'; import type { ReachableServer } from '../../../src/servers/data'; import type { ShortUrl } from '../../../src/short-urls/data'; import { ShortUrlsRowMenu as createShortUrlsRowMenu } from '../../../src/short-urls/helpers/ShortUrlsRowMenu'; @@ -8,8 +8,8 @@ import { renderWithEvents } from '../../__helpers__/setUpTest'; describe('', () => { const ShortUrlsRowMenu = createShortUrlsRowMenu(() => DeleteShortUrlModal, () => QrCodeModal); - const selectedServer = Mock.of({ id: 'abc123' }); - const shortUrl = Mock.of({ + const selectedServer = fromPartial({ id: 'abc123' }); + const shortUrl = fromPartial({ shortCode: 'abc123', shortUrl: 'https://s.test/abc123', }); diff --git a/test/short-urls/helpers/index.test.ts b/test/short-urls/helpers/index.test.ts index bc33c1d5..6f252950 100644 --- a/test/short-urls/helpers/index.test.ts +++ b/test/short-urls/helpers/index.test.ts @@ -1,4 +1,4 @@ -import { Mock } from 'ts-mockery'; +import { fromPartial } from '@total-typescript/shoehorn'; import type { ShortUrl } from '../../../src/short-urls/data'; import { shortUrlDataFromShortUrl, urlDecodeShortCode, urlEncodeShortCode } from '../../../src/short-urls/helpers'; @@ -8,7 +8,7 @@ describe('helpers', () => { [undefined, { validateUrls: true }, { longUrl: '', validateUrl: true }], [undefined, undefined, { longUrl: '', validateUrl: false }], [ - Mock.of({ meta: {} }), + fromPartial({ meta: {} }), { validateUrls: false }, { longUrl: undefined,