// @vitest-environment happy-dom import { describe, it, expect, vi, beforeEach } from "vitest"; import { renderHook, act, waitFor } from "@testing-library/react"; vi.mock("./api", () => ({ authApi: { me: vi.fn(), login: vi.fn(), logout: vi.fn(), }, })); import { authApi } from "./api"; import { AuthProvider, useAuth } from "./AuthProvider"; const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} ); describe("AuthProvider", () => { beforeEach(() => { vi.resetAllMocks(); }); it("loads user on mount", async () => { (authApi.me as unknown as ReturnType).mockResolvedValue({ id: 1, username: "alice", role: "user", }); const { result } = renderHook(() => useAuth(), { wrapper }); await waitFor(() => expect(result.current.status).toBe("authenticated")); expect(result.current.user?.username).toBe("alice"); }); it("status is unauthenticated when /me fails", async () => { (authApi.me as unknown as ReturnType).mockRejectedValue( new Error("401") ); const { result } = renderHook(() => useAuth(), { wrapper }); await waitFor(() => expect(result.current.status).toBe("unauthenticated")); expect(result.current.user).toBeNull(); }); it("login() updates state on success", async () => { (authApi.me as unknown as ReturnType).mockRejectedValue( new Error("401") ); ( authApi.login as unknown as ReturnType ).mockResolvedValue({ id: 1, username: "alice", role: "admin" }); const { result } = renderHook(() => useAuth(), { wrapper }); await waitFor(() => expect(result.current.status).toBe("unauthenticated")); await act(async () => { await result.current.login("alice", "pw"); }); expect(result.current.user?.username).toBe("alice"); expect(result.current.status).toBe("authenticated"); }); it("logout() clears state", async () => { (authApi.me as unknown as ReturnType).mockResolvedValue({ id: 1, username: "alice", role: "user", }); ( authApi.logout as unknown as ReturnType ).mockResolvedValue(undefined); const { result } = renderHook(() => useAuth(), { wrapper }); await waitFor(() => expect(result.current.status).toBe("authenticated")); await act(async () => { await result.current.logout(); }); expect(result.current.user).toBeNull(); expect(result.current.status).toBe("unauthenticated"); }); });