import React, { type ReactElement } from 'react'; import { render, type RenderOptions } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { I18nextProvider } from 'react-i18next'; import i18n from '../i18n'; // Adjust path to your i18n config /** * Test conventions — distilled from the SmartStack.app corpus (see the * `/test-conventions` skill, references/frontend-vitest.md). Apply them in every * `*.test.tsx`: * * • `vi.mock(...)` is HOISTED — declare each mock ABOVE the import of the module * it mocks (the page/hook under test), never after. * • For unit component/hook tests, MOCK `react-i18next` * (`useTranslation: () => ({ t: (k) => k, i18n: {…} })`) instead of relying on * a real instance — avoids the NO_I18NEXT_INSTANCE warning and lets assertions * match on the i18n key. (The provider below is for integration-style page tests.) * • Testing Library queries: `getByRole` / `findByRole` / `queryByTestId`. * • Router: `MemoryRouter` with `initialEntries` — never `BrowserRouter`. * • Random ids: `crypto.randomUUID()` — never a hardcoded literal. * • API is mocked with MSW (see `msw/handlers.ts` + `server.use(...)` per test) — * this harness keeps the MSW approach rather than mocking the api client. */ /** * AuthContext mock for tests. * Provides a default authenticated user with admin permissions. */ const mockAuthContext = { user: { id: 'test-user-id', email: 'test-admin@smartstack.io', name: 'Test Admin', role: 'Administrator', }, isAuthenticated: true, isLoading: false, login: async () => {}, logout: async () => {}, hasPermission: () => true, refreshPermissions: async () => {}, }; /** * Wraps components with all necessary providers for testing. * Includes: MemoryRouter, React Query, i18n. */ function AllProviders({ children }: { children: React.ReactNode }) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, staleTime: Infinity } }, }); return ( {children} ); } /** * Custom render function that wraps components with test providers. * Use this instead of @testing-library/react's render. * * @example * import { renderWithProviders, screen } from '@/test/test-utils'; * renderWithProviders(); * expect(screen.getByText('Hello')).toBeInTheDocument(); */ function renderWithProviders( ui: ReactElement, options?: Omit ) { return render(ui, { wrapper: AllProviders, ...options }); } // Re-export everything from testing-library export * from '@testing-library/react'; export { renderWithProviders }; export { mockAuthContext };