import { render, screen, waitFor } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; const { checkKillSwitchMock, logoutMock, refreshStoredAuthSessionMock, replaceMock, useAuthMock } = vi.hoisted(() => ({ checkKillSwitchMock: vi.fn(async () => ({ disabled: false, message: "" })), logoutMock: vi.fn(), refreshStoredAuthSessionMock: vi.fn(async () => true), replaceMock: vi.fn(), useAuthMock: vi.fn(() => ({ isAuthenticated: true, isLoading: false, logout: logoutMock })), })); vi.mock("next/navigation", () => ({ useRouter: () => ({ replace: replaceMock }), })); vi.mock("@/lib/auth", () => ({ useAuth: useAuthMock, })); vi.mock("@/lib/auth-session", () => ({ refreshStoredAuthSession: refreshStoredAuthSessionMock, })); vi.mock("@/lib/kill-switch", () => ({ checkKillSwitch: checkKillSwitchMock, })); import { AuthGuard } from "./AuthGuard"; describe("AuthGuard", () => { beforeEach(() => { vi.clearAllMocks(); useAuthMock.mockReturnValue({ isAuthenticated: true, isLoading: false, logout: logoutMock }); refreshStoredAuthSessionMock.mockResolvedValue(true); checkKillSwitchMock.mockResolvedValue({ disabled: false, message: "" }); }); it("redirects unauthenticated users to login", async () => { useAuthMock.mockReturnValue({ isAuthenticated: false, isLoading: false, logout: logoutMock }); render(
Private app
); await waitFor(() => expect(replaceMock).toHaveBeenCalledWith("/login")); expect(screen.queryByText("Private app")).not.toBeInTheDocument(); }); it("refreshes an expired stored session before showing protected content", async () => { render(
Private app
); await waitFor(() => expect(refreshStoredAuthSessionMock).toHaveBeenCalledOnce()); expect(await screen.findByText("Private app")).toBeInTheDocument(); expect(logoutMock).not.toHaveBeenCalled(); }); it("logs out and redirects when session refresh fails", async () => { refreshStoredAuthSessionMock.mockResolvedValue(false); render(
Private app
); await waitFor(() => expect(logoutMock).toHaveBeenCalledOnce()); expect(replaceMock).toHaveBeenCalledWith("/login"); expect(screen.queryByText("Private app")).not.toBeInTheDocument(); }); it("keeps protected content hidden when the kill switch is active", async () => { checkKillSwitchMock.mockResolvedValue({ disabled: true, message: "Maintenance window" }); render(
Private app
); expect(await screen.findByText("Maintenance window")).toBeInTheDocument(); expect(screen.queryByText("Private app")).not.toBeInTheDocument(); }); it("shows a platform-down state when readiness cannot be checked", async () => { checkKillSwitchMock.mockRejectedValue(new Error("HTTP 503 Service Unavailable")); render(
Private app
); expect(await screen.findByText("Platform services are unavailable")).toBeInTheDocument(); expect(screen.queryByText("Private app")).not.toBeInTheDocument(); }); });