import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, waitFor } from "@testing-library/react"; import { MemoryRouter, Routes, Route } from "react-router-dom"; import { FluentProvider, webLightTheme } from "@fluentui/react-components"; import { SetupGuard } from "../SetupGuard"; // Mock the setup API module so tests never hit a real network. vi.mock("../../api/setup", () => ({ getSetupStatus: vi.fn(), })); import { getSetupStatus } from "../../api/setup"; const mockedGetSetupStatus = vi.mocked(getSetupStatus); function renderGuard() { return render(
Protected
} /> Setup Page} />
, ); } describe("SetupGuard", () => { beforeEach(() => { vi.clearAllMocks(); }); it("shows a spinner while the setup status is loading", () => { // getSetupStatus resolves eventually — spinner should show immediately. mockedGetSetupStatus.mockReturnValue(new Promise(() => {})); renderGuard(); expect(screen.getByRole("progressbar")).toBeInTheDocument(); }); it("renders children when setup is complete", async () => { mockedGetSetupStatus.mockResolvedValue({ completed: true }); renderGuard(); await waitFor(() => { expect(screen.getByTestId("protected-content")).toBeInTheDocument(); }); }); it("redirects to /setup when setup is not complete", async () => { mockedGetSetupStatus.mockResolvedValue({ completed: false }); renderGuard(); await waitFor(() => { expect(screen.getByTestId("setup-page")).toBeInTheDocument(); }); expect(screen.queryByTestId("protected-content")).not.toBeInTheDocument(); }); it("redirects to /setup when the API call fails", async () => { // Task 0.3: a failed check must redirect to /setup, not allow through. mockedGetSetupStatus.mockRejectedValue(new Error("Network error")); renderGuard(); await waitFor(() => { expect(screen.getByTestId("setup-page")).toBeInTheDocument(); }); expect(screen.queryByTestId("protected-content")).not.toBeInTheDocument(); }); });