Files
home-automation/frontend/src/test-utils.tsx
T

84 lines
2.6 KiB
TypeScript
Raw Normal View History

/**
* Shared test utilities — wraps components in the providers they need.
*
* Usage:
* import { renderWithProviders } from '../test-utils'
* renderWithProviders(<LoginPage />, { initialPath: '/login' })
*/
import type { ReactNode } from 'react'
import { render } from '@testing-library/react'
import { MantineProvider } from '@mantine/core'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MemoryRouter, Routes, Route } from 'react-router-dom'
// ---------------------------------------------------------------------------
// Provider wrapper
// ---------------------------------------------------------------------------
interface RenderOptions {
/** Initial URL path (default: '/'). */
initialPath?: string
/**
* Extra routes to register alongside the component under test.
* Useful for asserting navigation (e.g. render a /home sentinel and check
* that the component navigates there after login).
*/
routes?: Array<{ path: string; element: ReactNode }>
/**
* React-router initial entries (overrides initialPath when provided).
* Use when you need to seed location.state (e.g. from-path for redirect-after-login).
*/
initialEntries?: Array<string | { pathname: string; state?: unknown }>
}
/**
* Render `ui` inside MantineProvider + a fresh QueryClientProvider + MemoryRouter.
* SessionProvider is NOT included — tests that need session state should mock
* `GET /api/session` via vi.fn() on the apiClient or use MSW.
*/
export function renderWithProviders(ui: ReactNode, options: RenderOptions = {}) {
const { initialPath = '/', routes = [], initialEntries } = options
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
})
const entries = initialEntries ?? [initialPath]
function Wrapper() {
return (
<MantineProvider>
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={entries}>
<Routes>
<Route path={initialPath} element={ui} />
{routes.map(({ path, element }) => (
<Route key={path} path={path} element={element} />
))}
</Routes>
</MemoryRouter>
</QueryClientProvider>
</MantineProvider>
)
}
return render(<Wrapper />)
}
/**
* Create a minimal SessionProvider-less wrapper that just supplies the
* query and router context. Returns the queryClient so tests can prime it.
*/
export function createTestQueryClient() {
return new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
})
}