import { screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { beforeEach, describe, expect, it, vi } from "vitest"; import LoginPage from "@/app/login/page"; import RegisterPage from "@/app/register/page"; import { renderWithQueryClient } from "./test-utils"; vi.mock("next/navigation", () => ({ useRouter: () => ({ push: vi.fn(), replace: vi.fn() }), useSearchParams: () => new URLSearchParams(), })); beforeEach(() => { vi.stubGlobal( "fetch", vi.fn().mockResolvedValue({ ok: false, status: 401, json: async () => ({ detail: "Not authenticated" }), }), ); }); describe("LoginPage", () => { it("shows validation errors for an empty submission", async () => { const user = userEvent.setup(); renderWithQueryClient(); await user.click(await screen.findByRole("button", { name: /sign in/i })); expect(await screen.findByText(/enter a valid email address/i)).toBeInTheDocument(); expect(await screen.findByText(/enter your password/i)).toBeInTheDocument(); }); it("links to the register page", async () => { renderWithQueryClient(); expect(await screen.findByRole("link", { name: /create one/i })).toHaveAttribute( "href", "/register", ); }); }); describe("RegisterPage", () => { it("rejects a weak password before submitting", async () => { const user = userEvent.setup(); renderWithQueryClient(); await user.type(screen.getByLabelText(/full name/i), "Ada Lovelace"); await user.type(screen.getByLabelText(/^email$/i), "ada@example.com"); await user.type(screen.getByLabelText(/^password$/i), "allletters"); await user.click(screen.getByRole("button", { name: /create account/i })); await waitFor(() => { expect( screen.getByText(/must contain at least one letter and one digit/i), ).toBeInTheDocument(); }); }); it("links to the login page", async () => { renderWithQueryClient(); expect(await screen.findByRole("link", { name: /sign in/i })).toHaveAttribute("href", "/login"); }); });