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 { SetupPage } from "../SetupPage"; // Mock the setup API so tests never hit a real network. vi.mock("../../api/setup", () => ({ getSetupStatus: vi.fn(), submitSetup: vi.fn(), })); // Mock the crypto utility — we only need it to resolve without testing SHA256. vi.mock("../../utils/crypto", () => ({ sha256Hex: vi.fn().mockResolvedValue("hashed-password"), })); import { getSetupStatus } from "../../api/setup"; const mockedGetSetupStatus = vi.mocked(getSetupStatus); function renderPage() { return render( } /> Login} /> , ); } describe("SetupPage", () => { beforeEach(() => { vi.clearAllMocks(); }); it("shows a full-screen spinner while the setup status check is in flight", () => { // getSetupStatus never resolves — spinner should be visible immediately. mockedGetSetupStatus.mockReturnValue(new Promise(() => {})); renderPage(); expect(screen.getByRole("progressbar")).toBeInTheDocument(); // Form should NOT be visible yet. expect( screen.queryByRole("heading", { name: /bangui setup/i }), ).not.toBeInTheDocument(); }); it("renders the setup form once the status check resolves (not complete)", async () => { // Task 0.4: form must not flash before the check resolves. mockedGetSetupStatus.mockResolvedValue({ completed: false }); renderPage(); await waitFor(() => { expect( screen.getByRole("heading", { name: /bangui setup/i }), ).toBeInTheDocument(); }); // Spinner should be gone. expect(screen.queryByRole("progressbar")).not.toBeInTheDocument(); }); it("redirects to /login when setup is already complete", async () => { mockedGetSetupStatus.mockResolvedValue({ completed: true }); renderPage(); await waitFor(() => { expect(screen.getByTestId("login-page")).toBeInTheDocument(); }); }); it("renders the form and logs a warning when the status check fails", async () => { // Task 0.4: catch block must log a warning and keep the form visible. const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); mockedGetSetupStatus.mockRejectedValue(new Error("Connection refused")); renderPage(); await waitFor(() => { expect( screen.getByRole("heading", { name: /bangui setup/i }), ).toBeInTheDocument(); }); expect(warnSpy).toHaveBeenCalledOnce(); warnSpy.mockRestore(); }); });