mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-04-19 04:56:17 +00:00
Refactor DI approach for components
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { ErrorHandler as createErrorHandler } from '../../src/common/ErrorHandler';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { ErrorHandler as BaseErrorHandler } from '../../src/common/ErrorHandler';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
const ComponentWithError = () => {
|
||||
@@ -9,18 +10,16 @@ const ComponentWithError = () => {
|
||||
|
||||
describe('<ErrorHandler />', () => {
|
||||
const reload = vi.fn();
|
||||
const window = fromPartial<Window>({
|
||||
location: { reload },
|
||||
});
|
||||
const location = fromPartial<Window['location']>({ reload });
|
||||
const cons = fromPartial<Console>({ error: vi.fn() });
|
||||
const ErrorHandler = createErrorHandler(window, cons);
|
||||
const ErrorHandler = (props: PropsWithChildren) => <BaseErrorHandler console={cons} location={location} {...props} />;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {}); // Silence react errors
|
||||
});
|
||||
|
||||
it('renders children when no error has occurred', () => {
|
||||
render(<ErrorHandler children={<span>Foo</span>} />);
|
||||
render(<ErrorHandler><span>Foo</span></ErrorHandler>);
|
||||
|
||||
expect(screen.getByText('Foo')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Oops! This is awkward :S')).not.toBeInTheDocument();
|
||||
@@ -28,14 +27,14 @@ describe('<ErrorHandler />', () => {
|
||||
});
|
||||
|
||||
it('renders error page when error has occurred', () => {
|
||||
render(<ErrorHandler children={<ComponentWithError />} />);
|
||||
render(<ErrorHandler><ComponentWithError /></ErrorHandler>);
|
||||
|
||||
expect(screen.getByText('Oops! This is awkward :S')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('reloads page on button click', async () => {
|
||||
const { user } = renderWithEvents(<ErrorHandler children={<ComponentWithError />} />);
|
||||
const { user } = renderWithEvents(<ErrorHandler><ComponentWithError /></ErrorHandler>);
|
||||
|
||||
expect(reload).not.toHaveBeenCalled();
|
||||
await user.click(screen.getByRole('button'));
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { MainHeader as createMainHeader } from '../../src/common/MainHeader';
|
||||
import { MainHeaderFactory } from '../../src/common/MainHeader';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
describe('<MainHeader />', () => {
|
||||
const MainHeader = createMainHeader(() => <>ServersDropdown</>);
|
||||
const MainHeader = MainHeaderFactory(fromPartial({
|
||||
ServersDropdown: () => <>ServersDropdown</>,
|
||||
}));
|
||||
const setUp = (pathname = '') => {
|
||||
const history = createMemoryHistory();
|
||||
history.push(pathname);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { ShlinkWebComponentContainer as createContainer } from '../../src/common/ShlinkWebComponentContainer';
|
||||
import { ShlinkWebComponentContainerFactory } from '../../src/common/ShlinkWebComponentContainer';
|
||||
import type { NonReachableServer, NotFoundServer, SelectedServer } from '../../src/servers/data';
|
||||
|
||||
vi.mock('react-router-dom', async () => ({
|
||||
@@ -10,12 +10,12 @@ vi.mock('react-router-dom', async () => ({
|
||||
}));
|
||||
|
||||
describe('<ShlinkWebComponentContainer />', () => {
|
||||
const ShlinkWebComponentContainer = createContainer(
|
||||
vi.fn().mockReturnValue(fromPartial({})),
|
||||
fromPartial({}),
|
||||
() => <>ShlinkWebComponent</>,
|
||||
() => <>ServerError</>,
|
||||
);
|
||||
const ShlinkWebComponentContainer = ShlinkWebComponentContainerFactory(fromPartial({
|
||||
buildShlinkApiClient: vi.fn().mockReturnValue(fromPartial({})),
|
||||
TagColorsStorage: fromPartial({}),
|
||||
ShlinkWebComponent: () => <>ShlinkWebComponent</>,
|
||||
ServerError: () => <>ServerError</>,
|
||||
}));
|
||||
const setUp = (selectedServer: SelectedServer) => render(
|
||||
<ShlinkWebComponentContainer selectServer={vi.fn()} selectedServer={selectedServer} settings={{}} />,
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { CreateServer as createCreateServer } from '../../src/servers/CreateServer';
|
||||
import { CreateServerFactory } from '../../src/servers/CreateServer';
|
||||
import type { ServersMap } from '../../src/servers/data';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
@@ -31,7 +31,10 @@ describe('<CreateServer />', () => {
|
||||
callCount += 1;
|
||||
return result;
|
||||
});
|
||||
const CreateServer = createCreateServer(() => <>ImportServersBtn</>, useTimeoutToggle);
|
||||
const CreateServer = CreateServerFactory(fromPartial({
|
||||
ImportServersBtn: () => <>ImportServersBtn</>,
|
||||
useTimeoutToggle,
|
||||
}));
|
||||
|
||||
return renderWithEvents(<CreateServer createServers={createServersMock} servers={servers} />);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import type { ReactNode } from 'react';
|
||||
import { DeleteServerButton as createDeleteServerButton } from '../../src/servers/DeleteServerButton';
|
||||
import { DeleteServerButtonFactory } from '../../src/servers/DeleteServerButton';
|
||||
import type { DeleteServerModalProps } from '../../src/servers/DeleteServerModal';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
describe('<DeleteServerButton />', () => {
|
||||
const DeleteServerButton = createDeleteServerButton(
|
||||
({ isOpen }) => <>DeleteServerModal {isOpen ? '[Open]' : '[Closed]'}</>,
|
||||
);
|
||||
const DeleteServerButton = DeleteServerButtonFactory(fromPartial({
|
||||
DeleteServerModal: ({ isOpen }: DeleteServerModalProps) => <>DeleteServerModal {isOpen ? '[Open]' : '[Closed]'}</>,
|
||||
}));
|
||||
const setUp = (children?: ReactNode) => renderWithEvents(
|
||||
<DeleteServerButton server={fromPartial({})} textClassName="button">{children}</DeleteServerButton>,
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { fireEvent, screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter, useNavigate } from 'react-router-dom';
|
||||
import type { ReachableServer, SelectedServer } from '../../src/servers/data';
|
||||
import { EditServer as editServerConstruct } from '../../src/servers/EditServer';
|
||||
import { EditServerFactory } from '../../src/servers/EditServer';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
vi.mock('react-router-dom', async () => ({
|
||||
@@ -20,7 +20,7 @@ describe('<EditServer />', () => {
|
||||
url: 'the_url',
|
||||
apiKey: 'the_api_key',
|
||||
});
|
||||
const EditServer = editServerConstruct(ServerError);
|
||||
const EditServer = EditServerFactory(fromPartial({ ServerError }));
|
||||
const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => renderWithEvents(
|
||||
<MemoryRouter>
|
||||
<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={vi.fn()} />
|
||||
|
||||
@@ -2,7 +2,7 @@ import { screen, waitFor } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import type { ServersMap, ServerWithId } from '../../src/servers/data';
|
||||
import { ManageServers as createManageServers } from '../../src/servers/ManageServers';
|
||||
import { ManageServersFactory } from '../../src/servers/ManageServers';
|
||||
import type { ServersExporter } from '../../src/servers/services/ServersExporter';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
@@ -10,12 +10,14 @@ describe('<ManageServers />', () => {
|
||||
const exportServers = vi.fn();
|
||||
const serversExporter = fromPartial<ServersExporter>({ exportServers });
|
||||
const useTimeoutToggle = vi.fn().mockReturnValue([false, vi.fn()]);
|
||||
const ManageServers = createManageServers(
|
||||
serversExporter,
|
||||
() => <span>ImportServersBtn</span>,
|
||||
const ManageServers = ManageServersFactory(fromPartial({
|
||||
ServersExporter: serversExporter,
|
||||
ImportServersBtn: () => <span>ImportServersBtn</span>,
|
||||
useTimeoutToggle,
|
||||
({ hasAutoConnect }) => <tr><td>ManageServersRow {hasAutoConnect ? '[YES]' : '[NO]'}</td></tr>,
|
||||
);
|
||||
ManageServersRow: ({ hasAutoConnect }: { hasAutoConnect: boolean }) => (
|
||||
<tr><td>ManageServersRow {hasAutoConnect ? '[YES]' : '[NO]'}</td></tr>
|
||||
),
|
||||
}));
|
||||
const createServerMock = (value: string, autoConnect = false) => fromPartial<ServerWithId>(
|
||||
{ id: value, name: value, url: value, autoConnect },
|
||||
);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import type { ServerWithId } from '../../src/servers/data';
|
||||
import { ManageServersRow as createManageServersRow } from '../../src/servers/ManageServersRow';
|
||||
import { ManageServersRowFactory } from '../../src/servers/ManageServersRow';
|
||||
|
||||
describe('<ManageServersRow />', () => {
|
||||
const ManageServersRow = createManageServersRow(() => <span>ManageServersRowDropdown</span>);
|
||||
const ManageServersRow = ManageServersRowFactory(fromPartial({
|
||||
ManageServersRowDropdown: () => <span>ManageServersRowDropdown</span>,
|
||||
}));
|
||||
const server: ServerWithId = {
|
||||
name: 'My server',
|
||||
url: 'https://example.com',
|
||||
|
||||
@@ -2,13 +2,15 @@ import { screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import type { ServerWithId } from '../../src/servers/data';
|
||||
import { ManageServersRowDropdown as createManageServersRowDropdown } from '../../src/servers/ManageServersRowDropdown';
|
||||
import { ManageServersRowDropdownFactory } from '../../src/servers/ManageServersRowDropdown';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
describe('<ManageServersRowDropdown />', () => {
|
||||
const ManageServersRowDropdown = createManageServersRowDropdown(
|
||||
({ isOpen }) => <span>DeleteServerModal {isOpen ? '[OPEN]' : '[CLOSED]'}</span>,
|
||||
);
|
||||
const ManageServersRowDropdown = ManageServersRowDropdownFactory(fromPartial({
|
||||
DeleteServerModal: ({ isOpen }: { isOpen: boolean }) => (
|
||||
<span>DeleteServerModal {isOpen ? '[OPEN]' : '[CLOSED]'}</span>
|
||||
),
|
||||
}));
|
||||
const setAutoConnect = vi.fn();
|
||||
const setUp = (autoConnect = false) => {
|
||||
const server = fromPartial<ServerWithId>({ id: 'abc123', autoConnect });
|
||||
|
||||
@@ -3,9 +3,7 @@ import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import type { ServersMap, ServerWithId } from '../../../src/servers/data';
|
||||
import type {
|
||||
ImportServersBtnProps } from '../../../src/servers/helpers/ImportServersBtn';
|
||||
import {
|
||||
ImportServersBtn as createImportServersBtn,
|
||||
} from '../../../src/servers/helpers/ImportServersBtn';
|
||||
import { ImportServersBtnFactory } from '../../../src/servers/helpers/ImportServersBtn';
|
||||
import type { ServersImporter } from '../../../src/servers/services/ServersImporter';
|
||||
import { renderWithEvents } from '../../__helpers__/setUpTest';
|
||||
|
||||
@@ -14,7 +12,7 @@ describe('<ImportServersBtn />', () => {
|
||||
const createServersMock = vi.fn();
|
||||
const importServersFromFile = vi.fn().mockResolvedValue([]);
|
||||
const serversImporterMock = fromPartial<ServersImporter>({ importServersFromFile });
|
||||
const ImportServersBtn = createImportServersBtn(serversImporterMock);
|
||||
const ImportServersBtn = ImportServersBtnFactory(fromPartial({ ServersImporter: serversImporterMock }));
|
||||
const setUp = (props: Partial<ImportServersBtnProps> = {}, servers: ServersMap = {}) => renderWithEvents(
|
||||
<ImportServersBtn
|
||||
servers={servers}
|
||||
|
||||
@@ -2,10 +2,10 @@ import { render, screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import type { NonReachableServer, NotFoundServer } from '../../../src/servers/data';
|
||||
import { ServerError as createServerError } from '../../../src/servers/helpers/ServerError';
|
||||
import { ServerErrorFactory } from '../../../src/servers/helpers/ServerError';
|
||||
|
||||
describe('<ServerError />', () => {
|
||||
const ServerError = createServerError(() => null);
|
||||
const ServerError = ServerErrorFactory(fromPartial({ DeleteServerButton: () => null }));
|
||||
|
||||
it.each([
|
||||
[
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { Settings as createSettings } from '../../src/settings/Settings';
|
||||
import { SettingsFactory } from '../../src/settings/Settings';
|
||||
|
||||
describe('<Settings />', () => {
|
||||
const Settings = createSettings(
|
||||
() => <span>RealTimeUpdates</span>,
|
||||
() => <span>ShortUrlCreation</span>,
|
||||
() => <span>ShortUrlsList</span>,
|
||||
() => <span>UserInterface</span>,
|
||||
() => <span>Visits</span>,
|
||||
() => <span>Tags</span>,
|
||||
);
|
||||
const Settings = SettingsFactory(fromPartial({
|
||||
RealTimeUpdatesSettings: () => <span>RealTimeUpdates</span>,
|
||||
ShortUrlCreationSettings: () => <span>ShortUrlCreation</span>,
|
||||
ShortUrlsListSettings: () => <span>ShortUrlsList</span>,
|
||||
UserInterfaceSettings: () => <span>UserInterface</span>,
|
||||
VisitsSettings: () => <span>Visits</span>,
|
||||
TagsSettings: () => <span>Tags</span>,
|
||||
}));
|
||||
const setUp = (activeRoute = '/') => {
|
||||
const history = createMemoryHistory();
|
||||
history.push(activeRoute);
|
||||
|
||||
Reference in New Issue
Block a user