import { Suspense } from "react"; import { describe, it, expect, vi, beforeEach } from "vitest"; import { screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import "@testing-library/jest-dom/vitest"; import { renderWithProviders } from "../utils/test-utils"; import { useAuthModal } from "../../app/contexts/AuthModalContext"; const { navMock } = vi.hoisted(() => ({ navMock: { pathname: "/", searchParams: new URLSearchParams(), replace: vi.fn(), }, })); vi.mock("next/navigation", () => ({ useRouter: () => ({ replace: navMock.replace, push: vi.fn(), prefetch: vi.fn(), refresh: vi.fn(), back: vi.fn(), forward: vi.fn(), }), usePathname: () => navMock.pathname, useSearchParams: () => navMock.searchParams, })); vi.mock("../../lib/create/api", () => ({ requestMagicLink: vi.fn(), })); vi.mock("../../app/(app)/create/utils/anonymousDraftStorage", async (importOriginal) => { const actual = await importOriginal< typeof import("../../app/(app)/create/utils/anonymousDraftStorage") >(); return { ...actual, setTransferPendingFlag: vi.fn(), }; }); import { requestMagicLink } from "../../lib/create/api"; import { setTransferPendingFlag } from "../../app/(app)/create/utils/anonymousDraftStorage"; function LoginTrigger() { const { openLogin, closeLogin } = useAuthModal(); return (
); } describe("AuthModalProvider (header overlay)", () => { beforeEach(() => { vi.mocked(requestMagicLink).mockReset(); vi.mocked(setTransferPendingFlag).mockReset(); navMock.replace.mockReset(); navMock.pathname = "/"; navMock.searchParams = new URLSearchParams(); }); it("opens blurred overlay with LoginForm when openLogin is called", async () => { const user = userEvent.setup(); renderWithProviders( , ); await user.click(screen.getByRole("button", { name: /open login modal/i })); await waitFor(() => { expect(screen.getByRole("dialog")).toBeInTheDocument(); }); const backdrop = screen.getByRole("dialog").parentElement; expect(backdrop).toHaveClass("backdrop-blur-md"); expect( screen.getByRole("heading", { name: /log in to communityrule/i }), ).toBeInTheDocument(); expect( screen.getByRole("link", { name: /back to home/i }), ).toBeInTheDocument(); }); it("closes overlay when closeLogin is called", async () => { const user = userEvent.setup(); renderWithProviders( , ); await user.click(screen.getByRole("button", { name: /open login modal/i })); await waitFor(() => { expect(screen.getByRole("dialog")).toBeInTheDocument(); }); await user.click( screen.getByRole("button", { name: /close from outside/i }), ); await waitFor(() => { expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); }); }); it("saveProgress openLogin wires magicLinkNextPath and transfer flag on success", async () => { const user = userEvent.setup(); vi.mocked(requestMagicLink).mockResolvedValue({ ok: true }); renderWithProviders( , ); await user.click( screen.getByRole("button", { name: /open save progress/i }), ); await waitFor(() => { expect(screen.getByRole("dialog")).toBeInTheDocument(); }); await user.type( screen.getByRole("textbox", { name: /email address/i }), "guest@example.com", ); await user.click( screen.getByRole("button", { name: /send me a magic link/i }), ); await waitFor(() => { expect(requestMagicLink).toHaveBeenCalledWith( "guest@example.com", "/create/community-structure?syncDraft=1", ); }); expect(setTransferPendingFlag).toHaveBeenCalled(); }); });