import type { ShlinkApiClient } from '@shlinkio/shlink-js-sdk'; import { fromPartial } from '@total-typescript/shoehorn'; import type { PropsWithChildren, ReactElement } from 'react'; import { Provider } from 'react-redux'; import type { RenderOptions } from 'vitest-browser-react'; import { render as vitestRender } from 'vitest-browser-react'; import { userEvent } from 'vitest/browser'; import { ContainerProvider } from '../../src/container/context'; import type { RootState } from '../../src/store'; import { setUpStore } from '../../src/store'; export const render = vitestRender; export const renderWithEvents = async (element: ReactElement, options?: RenderOptions) => ({ user: userEvent.setup(), ...(await render(element, options)), }); export type RenderOptionsWithState = Omit & { /** Initial state for the redux store */ initialState?: Partial; /** * If provided, it will set this as the `buildShlinkApiClient` dependency in the `ContainerProvider`. * If more dependencies are needed, then explicitly define your own `ContainerProvider` and make sure it includes a * `buildShlinkApiClient` service. * * Defaults to vi.fn() */ buildShlinkApiClient?: () => ShlinkApiClient; }; /** * Render provided ReactElement wrapped in a redux `Provider` and a `ContainerProvider` with a single * `buildShlinkApiClient` dependency. */ export const renderWithStore = async ( element: ReactElement, { initialState = {}, buildShlinkApiClient = vi.fn(), ...options }: RenderOptionsWithState = {}, ) => { const store = setUpStore(initialState); const Wrapper = ({ children }: PropsWithChildren) => ( {children} ); return { store, ...(await renderWithEvents(element, { ...options, wrapper: Wrapper })), }; };