import { act, render } from "@testing-library/react" import { MemoryRouter, Route, Routes } from "react-router-dom" import { afterEach, beforeEach, expect, test, vi } from "vitest" // ProtectedRoute must NOT mount its children while AuthProvider is still // running the initial getProfile() probe — except for the /dashboard/login // path itself. Mounting the protected subtree during the probe would fire // authenticated SWR fetches like /api/v1/setting before auth is confirmed. // Without this contract, a regression in protect.tsx silently re-introduces // pre-auth traffic and a flash of protected UI before redirect. let mockProfile: { id: number; role: number } | undefined let mockLoading = false vi.mock("@/hooks/useAuth", () => ({ useAuth: () => ({ profile: mockProfile, loading: mockLoading }), })) beforeEach(() => { mockProfile = undefined mockLoading = true }) afterEach(() => { document.body.innerHTML = "" }) function renderAtPath(path: string, child: React.ReactNode) { return import("@/routes/protect").then(({ default: ProtectedRoute }) => { return act(async () => { render( {child}} /> {child}} /> , ) }) }) } test("ProtectedRoute does not mount children for protected paths while auth is loading", async () => { await renderAtPath("/dashboard",
protected
) expect(document.querySelector("[data-testid='protected-child']")).toBeNull() }) test("ProtectedRoute renders children on the login page even while auth is loading", async () => { await renderAtPath("/dashboard/login",
login
) expect(document.querySelector("[data-testid='login-child']")).not.toBeNull() }) test("ProtectedRoute redirects unauthenticated users without mounting protected children", async () => { mockLoading = false mockProfile = undefined const { default: ProtectedRoute } = await import("@/routes/protect") await act(async () => { render(
login
} />
protected
} />
, ) }) expect(document.querySelector("[data-testid='protected-child']")).toBeNull() expect(document.querySelector("[data-testid='login-child']")).not.toBeNull() }) test("ProtectedRoute renders children once an authenticated profile resolves", async () => { mockLoading = false mockProfile = { id: 1, role: 0 } await renderAtPath("/dashboard",
protected
) expect(document.querySelector("[data-testid='protected-child']")).not.toBeNull() })