mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-13 19:13:46 +00:00
Set everything up to use hooks for reduc actions and state
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { changeThemeInMarkup, getSystemPreferredTheme } from '@shlinkio/shlink-frontend-kit';
|
import { changeThemeInMarkup, getSystemPreferredTheme } from '@shlinkio/shlink-frontend-kit';
|
||||||
import type { Settings } from '@shlinkio/shlink-web-component/settings';
|
import type { Settings as AppSettings } from '@shlinkio/shlink-web-component/settings';
|
||||||
import { clsx } from 'clsx';
|
import { clsx } from 'clsx';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
@@ -9,12 +9,13 @@ import { NotFound } from '../common/NotFound';
|
|||||||
import type { FCWithDeps } from '../container/utils';
|
import type { FCWithDeps } from '../container/utils';
|
||||||
import { componentFactory, useDependencies } from '../container/utils';
|
import { componentFactory, useDependencies } from '../container/utils';
|
||||||
import type { ServersMap } from '../servers/data';
|
import type { ServersMap } from '../servers/data';
|
||||||
|
import { Settings } from '../settings/Settings';
|
||||||
import { forceUpdate } from '../utils/helpers/sw';
|
import { forceUpdate } from '../utils/helpers/sw';
|
||||||
|
|
||||||
type AppProps = {
|
type AppProps = {
|
||||||
fetchServers: () => void;
|
fetchServers: () => void;
|
||||||
servers: ServersMap;
|
servers: ServersMap;
|
||||||
settings: Settings;
|
settings: AppSettings;
|
||||||
resetAppUpdate: () => void;
|
resetAppUpdate: () => void;
|
||||||
appUpdated: boolean;
|
appUpdated: boolean;
|
||||||
};
|
};
|
||||||
@@ -25,7 +26,6 @@ type AppDeps = {
|
|||||||
ShlinkWebComponentContainer: FC;
|
ShlinkWebComponentContainer: FC;
|
||||||
CreateServer: FC;
|
CreateServer: FC;
|
||||||
EditServer: FC;
|
EditServer: FC;
|
||||||
Settings: FC;
|
|
||||||
ManageServers: FC;
|
ManageServers: FC;
|
||||||
ShlinkVersionsContainer: FC;
|
ShlinkVersionsContainer: FC;
|
||||||
};
|
};
|
||||||
@@ -39,7 +39,6 @@ const App: FCWithDeps<AppProps, AppDeps> = (
|
|||||||
ShlinkWebComponentContainer,
|
ShlinkWebComponentContainer,
|
||||||
CreateServer,
|
CreateServer,
|
||||||
EditServer,
|
EditServer,
|
||||||
Settings,
|
|
||||||
ManageServers,
|
ManageServers,
|
||||||
ShlinkVersionsContainer,
|
ShlinkVersionsContainer,
|
||||||
} = useDependencies(App);
|
} = useDependencies(App);
|
||||||
@@ -105,7 +104,6 @@ export const AppFactory = componentFactory(App, [
|
|||||||
'ShlinkWebComponentContainer',
|
'ShlinkWebComponentContainer',
|
||||||
'CreateServer',
|
'CreateServer',
|
||||||
'EditServer',
|
'EditServer',
|
||||||
'Settings',
|
|
||||||
'ManageServers',
|
'ManageServers',
|
||||||
'ShlinkVersionsContainer',
|
'ShlinkVersionsContainer',
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { provideServices as provideApiServices } from '../api/services/provideSe
|
|||||||
import { provideServices as provideAppServices } from '../app/services/provideServices';
|
import { provideServices as provideAppServices } from '../app/services/provideServices';
|
||||||
import { provideServices as provideCommonServices } from '../common/services/provideServices';
|
import { provideServices as provideCommonServices } from '../common/services/provideServices';
|
||||||
import { provideServices as provideServersServices } from '../servers/services/provideServices';
|
import { provideServices as provideServersServices } from '../servers/services/provideServices';
|
||||||
import { provideServices as provideSettingsServices } from '../settings/services/provideServices';
|
|
||||||
import { provideServices as provideUtilsServices } from '../utils/services/provideServices';
|
import { provideServices as provideUtilsServices } from '../utils/services/provideServices';
|
||||||
import type { ConnectDecorator } from './types';
|
import type { ConnectDecorator } from './types';
|
||||||
|
|
||||||
@@ -39,4 +38,3 @@ provideCommonServices(bottle, connect);
|
|||||||
provideApiServices(bottle);
|
provideApiServices(bottle);
|
||||||
provideServersServices(bottle, connect);
|
provideServersServices(bottle, connect);
|
||||||
provideUtilsServices(bottle);
|
provideUtilsServices(bottle);
|
||||||
provideSettingsServices(bottle, connect);
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { configureStore } from '@reduxjs/toolkit';
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
import type { IContainer } from 'bottlejs';
|
|
||||||
import type { RLSOptions } from 'redux-localstorage-simple';
|
import type { RLSOptions } from 'redux-localstorage-simple';
|
||||||
import { load, save } from 'redux-localstorage-simple';
|
import { load, save } from 'redux-localstorage-simple';
|
||||||
import { initReducers } from '../reducers';
|
import { initReducers } from '../reducers';
|
||||||
@@ -13,11 +12,11 @@ const localStorageConfig: RLSOptions = {
|
|||||||
namespaceSeparator: '.',
|
namespaceSeparator: '.',
|
||||||
debounce: 300,
|
debounce: 300,
|
||||||
};
|
};
|
||||||
const preloadedState = migrateDeprecatedSettings(load(localStorageConfig) as ShlinkState);
|
const getStateFromLocalStorage = () => migrateDeprecatedSettings(load(localStorageConfig) as ShlinkState);
|
||||||
|
|
||||||
export const setUpStore = (container: IContainer) => configureStore({
|
export const setUpStore = (preloadedState = getStateFromLocalStorage()) => configureStore({
|
||||||
devTools: !isProduction,
|
devTools: !isProduction,
|
||||||
reducer: initReducers(container),
|
reducer: initReducers(),
|
||||||
preloadedState,
|
preloadedState,
|
||||||
middleware: (defaultMiddlewaresIncludingReduxThunk) =>
|
middleware: (defaultMiddlewaresIncludingReduxThunk) =>
|
||||||
defaultMiddlewaresIncludingReduxThunk({ immutableCheck: false, serializableCheck: false }) // State is too big for these
|
defaultMiddlewaresIncludingReduxThunk({ immutableCheck: false, serializableCheck: false }) // State is too big for these
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { setUpStore } from './container/store';
|
|||||||
import { register as registerServiceWorker } from './serviceWorkerRegistration';
|
import { register as registerServiceWorker } from './serviceWorkerRegistration';
|
||||||
import './tailwind.css';
|
import './tailwind.css';
|
||||||
|
|
||||||
const store = setUpStore(container);
|
const store = setUpStore();
|
||||||
const { App, ScrollToTop, ErrorHandler, appUpdateAvailable } = container;
|
const { App, ScrollToTop, ErrorHandler, appUpdateAvailable } = container;
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { combineReducers } from '@reduxjs/toolkit';
|
import { combineReducers } from '@reduxjs/toolkit';
|
||||||
import type { IContainer } from 'bottlejs';
|
|
||||||
import { appUpdatesReducer } from '../app/reducers/appUpdates';
|
import { appUpdatesReducer } from '../app/reducers/appUpdates';
|
||||||
|
import { selectedServerReducer } from '../servers/reducers/selectedServer';
|
||||||
import { serversReducer } from '../servers/reducers/servers';
|
import { serversReducer } from '../servers/reducers/servers';
|
||||||
import { settingsReducer } from '../settings/reducers/settings';
|
import { settingsReducer } from '../settings/reducers/settings';
|
||||||
|
|
||||||
export const initReducers = (container: IContainer) => combineReducers({
|
export const initReducers = () => combineReducers({
|
||||||
appUpdated: appUpdatesReducer,
|
appUpdated: appUpdatesReducer,
|
||||||
servers: serversReducer,
|
servers: serversReducer,
|
||||||
selectedServer: container.selectedServerReducer,
|
selectedServer: selectedServerReducer,
|
||||||
settings: settingsReducer,
|
settings: settingsReducer,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,14 +56,17 @@ export const selectServer = (buildShlinkApiClient: ShlinkApiClientBuilder) => cr
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
type SelectServerThunk = ReturnType<typeof selectServer>;
|
const { reducer } = createSlice({
|
||||||
|
|
||||||
export const selectedServerReducerCreator = (selectServerThunk: SelectServerThunk) => createSlice({
|
|
||||||
name: REDUCER_PREFIX,
|
name: REDUCER_PREFIX,
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {},
|
reducers: {},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder.addCase(resetSelectedServer, () => initialState);
|
builder.addCase(resetSelectedServer, () => initialState);
|
||||||
builder.addCase(selectServerThunk.fulfilled, (_, { payload }) => payload as any);
|
builder.addCase(
|
||||||
|
`${REDUCER_PREFIX}/selectServer/fulfilled`,
|
||||||
|
(_, { payload }: { payload: SelectedServer }) => payload,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const selectedServerReducer = reducer;
|
||||||
|
|||||||
@@ -11,11 +11,7 @@ import { ManageServersFactory } from '../ManageServers';
|
|||||||
import { ManageServersRowFactory } from '../ManageServersRow';
|
import { ManageServersRowFactory } from '../ManageServersRow';
|
||||||
import { ManageServersRowDropdownFactory } from '../ManageServersRowDropdown';
|
import { ManageServersRowDropdownFactory } from '../ManageServersRowDropdown';
|
||||||
import { fetchServers } from '../reducers/remoteServers';
|
import { fetchServers } from '../reducers/remoteServers';
|
||||||
import {
|
import { resetSelectedServer, selectServer } from '../reducers/selectedServer';
|
||||||
resetSelectedServer,
|
|
||||||
selectedServerReducerCreator,
|
|
||||||
selectServer,
|
|
||||||
} from '../reducers/selectedServer';
|
|
||||||
import { createServers, deleteServer, editServer, setAutoConnect } from '../reducers/servers';
|
import { createServers, deleteServer, editServer, setAutoConnect } from '../reducers/servers';
|
||||||
import { ServersDropdown } from '../ServersDropdown';
|
import { ServersDropdown } from '../ServersDropdown';
|
||||||
import { ServersExporter } from './ServersExporter';
|
import { ServersExporter } from './ServersExporter';
|
||||||
@@ -66,8 +62,4 @@ export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
|||||||
bottle.serviceFactory('fetchServers', fetchServers, 'HttpClient');
|
bottle.serviceFactory('fetchServers', fetchServers, 'HttpClient');
|
||||||
|
|
||||||
bottle.serviceFactory('resetSelectedServer', () => resetSelectedServer);
|
bottle.serviceFactory('resetSelectedServer', () => resetSelectedServer);
|
||||||
|
|
||||||
// Reducers
|
|
||||||
bottle.serviceFactory('selectedServerReducerCreator', selectedServerReducerCreator, 'selectServer');
|
|
||||||
bottle.serviceFactory('selectedServerReducer', (obj) => obj.reducer, 'selectedServerReducerCreator');
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
import type { Settings as AppSettings } from '@shlinkio/shlink-web-component/settings';
|
|
||||||
import { ShlinkWebSettings } from '@shlinkio/shlink-web-component/settings';
|
import { ShlinkWebSettings } from '@shlinkio/shlink-web-component/settings';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { NoMenuLayout } from '../common/NoMenuLayout';
|
import { NoMenuLayout } from '../common/NoMenuLayout';
|
||||||
import { DEFAULT_SHORT_URLS_ORDERING } from './reducers/settings';
|
import { DEFAULT_SHORT_URLS_ORDERING, useSettings } from './reducers/settings';
|
||||||
|
|
||||||
export type SettingsProps = {
|
export const Settings: FC = () => {
|
||||||
settings: AppSettings;
|
const { settings, setSettings } = useSettings();
|
||||||
setSettings: (newSettings: AppSettings) => void;
|
|
||||||
|
return (
|
||||||
|
<NoMenuLayout>
|
||||||
|
<ShlinkWebSettings
|
||||||
|
settings={settings}
|
||||||
|
onUpdateSettings={setSettings}
|
||||||
|
defaultShortUrlsListOrdering={DEFAULT_SHORT_URLS_ORDERING}
|
||||||
|
/>
|
||||||
|
</NoMenuLayout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Settings: FC<SettingsProps> = ({ settings, setSettings }) => (
|
|
||||||
<NoMenuLayout>
|
|
||||||
<ShlinkWebSettings
|
|
||||||
settings={settings}
|
|
||||||
onUpdateSettings={setSettings}
|
|
||||||
defaultShortUrlsListOrdering={DEFAULT_SHORT_URLS_ORDERING}
|
|
||||||
/>
|
|
||||||
</NoMenuLayout>
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import { createSlice } from '@reduxjs/toolkit';
|
|||||||
import { mergeDeepRight } from '@shlinkio/data-manipulation';
|
import { mergeDeepRight } from '@shlinkio/data-manipulation';
|
||||||
import { getSystemPreferredTheme } from '@shlinkio/shlink-frontend-kit';
|
import { getSystemPreferredTheme } from '@shlinkio/shlink-frontend-kit';
|
||||||
import type { Settings, ShortUrlsListSettings } from '@shlinkio/shlink-web-component/settings';
|
import type { Settings, ShortUrlsListSettings } from '@shlinkio/shlink-web-component/settings';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import type { ShlinkState } from '../../container/types';
|
||||||
import type { Defined } from '../../utils/types';
|
import type { Defined } from '../../utils/types';
|
||||||
|
|
||||||
type ShortUrlsOrder = Defined<ShortUrlsListSettings['defaultOrdering']>;
|
type ShortUrlsOrder = Defined<ShortUrlsListSettings['defaultOrdering']>;
|
||||||
@@ -41,3 +44,11 @@ const { reducer, actions } = createSlice({
|
|||||||
export const { setSettings } = actions;
|
export const { setSettings } = actions;
|
||||||
|
|
||||||
export const settingsReducer = reducer;
|
export const settingsReducer = reducer;
|
||||||
|
|
||||||
|
export const useSettings = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const setSettings = useCallback((settings: Settings) => dispatch(actions.setSettings(settings)), [dispatch]);
|
||||||
|
const settings = useSelector((state: ShlinkState) => state.settings);
|
||||||
|
|
||||||
|
return { settings, setSettings };
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import type Bottle from 'bottlejs';
|
|
||||||
import type { ConnectDecorator } from '../../container/types';
|
|
||||||
import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer';
|
|
||||||
import { setSettings } from '../reducers/settings';
|
|
||||||
import { Settings } from '../Settings';
|
|
||||||
|
|
||||||
export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
|
||||||
// Components
|
|
||||||
bottle.serviceFactory('Settings', () => Settings);
|
|
||||||
bottle.decorator('Settings', withoutSelectedServer);
|
|
||||||
bottle.decorator('Settings', connect(['settings'], ['setSettings', 'resetSelectedServer']));
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
bottle.serviceFactory('setSettings', () => setSettings);
|
|
||||||
};
|
|
||||||
@@ -8,7 +8,5 @@
|
|||||||
:root {
|
:root {
|
||||||
--footer-height: 2.3rem;
|
--footer-height: 2.3rem;
|
||||||
--footer-margin: .8rem;
|
--footer-margin: .8rem;
|
||||||
/* FIXME Remove this once updated to shlink-web-component 0.15.1 */
|
|
||||||
--header-height: 52px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import { render } from '@testing-library/react';
|
|
||||||
import userEvent from '@testing-library/user-event';
|
|
||||||
import type { ReactElement } from 'react';
|
|
||||||
|
|
||||||
export const renderWithEvents = (element: ReactElement) => ({
|
|
||||||
user: userEvent.setup(),
|
|
||||||
...render(element),
|
|
||||||
});
|
|
||||||
28
test/__helpers__/setUpTest.tsx
Normal file
28
test/__helpers__/setUpTest.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import type { RenderOptions } from '@testing-library/react';
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import type { PropsWithChildren, ReactElement } from 'react';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { setUpStore } from '../../src/container/store';
|
||||||
|
import type { ShlinkState } from '../../src/container/types';
|
||||||
|
|
||||||
|
export const renderWithEvents = (element: ReactElement, options?: RenderOptions) => ({
|
||||||
|
user: userEvent.setup(),
|
||||||
|
...render(element, options),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type RenderOptionsWithState = Omit<RenderOptions, 'wrapper'> & {
|
||||||
|
initialState?: Partial<ShlinkState>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const renderWithStore = (
|
||||||
|
element: ReactElement,
|
||||||
|
{ initialState = {}, ...options }: RenderOptionsWithState = {},
|
||||||
|
) => {
|
||||||
|
const Wrapper = ({ children }: PropsWithChildren) => (
|
||||||
|
<Provider store={setUpStore(initialState)}>
|
||||||
|
{children}
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
return renderWithEvents(element, { ...options, wrapper: Wrapper });
|
||||||
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { act, render, screen } from '@testing-library/react';
|
import { act, screen } from '@testing-library/react';
|
||||||
import { fromPartial } from '@total-typescript/shoehorn';
|
import { fromPartial } from '@total-typescript/shoehorn';
|
||||||
import { MemoryRouter } from 'react-router';
|
import { MemoryRouter } from 'react-router';
|
||||||
import { AppFactory } from '../../src/app/App';
|
import { AppFactory } from '../../src/app/App';
|
||||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||||
|
import { renderWithStore } from '../__helpers__/setUpTest';
|
||||||
|
|
||||||
describe('<App />', () => {
|
describe('<App />', () => {
|
||||||
const App = AppFactory(
|
const App = AppFactory(
|
||||||
@@ -12,12 +13,11 @@ describe('<App />', () => {
|
|||||||
ShlinkWebComponentContainer: () => <>ShlinkWebComponentContainer</>,
|
ShlinkWebComponentContainer: () => <>ShlinkWebComponentContainer</>,
|
||||||
CreateServer: () => <>CreateServer</>,
|
CreateServer: () => <>CreateServer</>,
|
||||||
EditServer: () => <>EditServer</>,
|
EditServer: () => <>EditServer</>,
|
||||||
Settings: () => <>SettingsComp</>,
|
|
||||||
ManageServers: () => <>ManageServers</>,
|
ManageServers: () => <>ManageServers</>,
|
||||||
ShlinkVersionsContainer: () => <>ShlinkVersions</>,
|
ShlinkVersionsContainer: () => <>ShlinkVersions</>,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const setUp = async (activeRoute = '/') => act(() => render(
|
const setUp = async (activeRoute = '/') => act(() => renderWithStore(
|
||||||
<MemoryRouter initialEntries={[{ pathname: activeRoute }]}>
|
<MemoryRouter initialEntries={[{ pathname: activeRoute }]}>
|
||||||
<App
|
<App
|
||||||
fetchServers={() => {}}
|
fetchServers={() => {}}
|
||||||
@@ -39,8 +39,8 @@ describe('<App />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
['/settings/foo', 'SettingsComp'],
|
['/settings/general', 'User interface'],
|
||||||
['/settings/bar', 'SettingsComp'],
|
['/settings/short-urls', 'Short URLs form'],
|
||||||
['/manage-servers', 'ManageServers'],
|
['/manage-servers', 'ManageServers'],
|
||||||
['/server/create', 'CreateServer'],
|
['/server/create', 'CreateServer'],
|
||||||
['/server/abc123/edit', 'EditServer'],
|
['/server/abc123/edit', 'EditServer'],
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
MAX_FALLBACK_VERSION,
|
MAX_FALLBACK_VERSION,
|
||||||
MIN_FALLBACK_VERSION,
|
MIN_FALLBACK_VERSION,
|
||||||
resetSelectedServer,
|
resetSelectedServer,
|
||||||
selectedServerReducerCreator,
|
selectedServerReducer as reducer,
|
||||||
selectServer as selectServerCreator,
|
selectServer as selectServerCreator,
|
||||||
} from '../../../src/servers/reducers/selectedServer';
|
} from '../../../src/servers/reducers/selectedServer';
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ describe('selectedServerReducer', () => {
|
|||||||
const health = vi.fn();
|
const health = vi.fn();
|
||||||
const buildApiClient = vi.fn().mockReturnValue(fromPartial<ShlinkApiClient>({ health }));
|
const buildApiClient = vi.fn().mockReturnValue(fromPartial<ShlinkApiClient>({ health }));
|
||||||
const selectServer = selectServerCreator(buildApiClient);
|
const selectServer = selectServerCreator(buildApiClient);
|
||||||
const { reducer } = selectedServerReducerCreator(selectServer);
|
|
||||||
|
|
||||||
describe('reducer', () => {
|
describe('reducer', () => {
|
||||||
it('returns default when action is RESET_SELECTED_SERVER', () =>
|
it('returns default when action is RESET_SELECTED_SERVER', () =>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { render } from '@testing-library/react';
|
|
||||||
import { MemoryRouter } from 'react-router';
|
import { MemoryRouter } from 'react-router';
|
||||||
import { Settings } from '../../src/settings/Settings';
|
import { Settings } from '../../src/settings/Settings';
|
||||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||||
|
import { renderWithStore } from '../__helpers__/setUpTest';
|
||||||
|
|
||||||
describe('<Settings />', () => {
|
describe('<Settings />', () => {
|
||||||
const setUp = () => render(
|
const setUp = () => renderWithStore(
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<Settings settings={{}} setSettings={vi.fn()} />
|
<Settings />
|
||||||
</MemoryRouter>,
|
</MemoryRouter>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user