// @vitest-environment happy-dom import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, fireEvent, waitFor, cleanup } from "@testing-library/react"; import { MemoryRouter, Routes, Route } from "react-router-dom"; import { Login } from "./Login"; vi.mock("@/auth/useAuth", () => ({ useAuth: vi.fn() })); import { useAuth } from "@/auth/useAuth"; function setup() { const login = vi.fn(); (useAuth as unknown as ReturnType).mockReturnValue({ user: null, status: "unauthenticated", login, logout: vi.fn(), refresh: vi.fn(), }); return { login }; } describe("Login page", () => { beforeEach(() => { vi.resetAllMocks(); cleanup(); }); it("submits username + password", async () => { const { login } = setup(); login.mockResolvedValue(undefined); const { getByLabelText, getByRole } = render( } /> HOME} /> ); fireEvent.change(getByLabelText(/username/i), { target: { value: "alice" }, }); fireEvent.change(getByLabelText(/password/i), { target: { value: "hunter2hunter2" }, }); fireEvent.click(getByRole("button", { name: /sign in/i })); await waitFor(() => expect(login).toHaveBeenCalledWith("alice", "hunter2hunter2") ); }); it("shows error on failed login", async () => { const { login } = setup(); login.mockRejectedValue( Object.assign(new Error("401"), { code: "invalid_credentials" }) ); const { getByLabelText, getByRole, getByText } = render( } /> ); fireEvent.change(getByLabelText(/username/i), { target: { value: "alice" }, }); fireEvent.change(getByLabelText(/password/i), { target: { value: "wrong" }, }); fireEvent.click(getByRole("button", { name: /sign in/i })); await waitFor(() => expect(getByText(/username or password is incorrect/i)).toBeTruthy() ); }); it("redirects to `next` query param on success", async () => { const { login } = setup(); login.mockResolvedValue(undefined); const { getByLabelText, getByRole, getByText } = render( } /> CLAIMS} /> ); fireEvent.change(getByLabelText(/username/i), { target: { value: "alice" }, }); fireEvent.change(getByLabelText(/password/i), { target: { value: "hunter2hunter2" }, }); fireEvent.click(getByRole("button", { name: /sign in/i })); await waitFor(() => expect(getByText("CLAIMS")).toBeTruthy()); }); });