import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { vi } from "vitest"; import { BrowserRouter } from "react-router-dom"; import LoginPage from "./LoginPage"; import { AuthProvider } from "../contexts/AuthContext"; import i18n from "../i18n"; vi.mock("../api/client", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, apiPost: vi.fn() }; }); const { apiPost } = await import("../api/client"); function renderLogin() { return render( ); } describe("LoginPage", () => { beforeEach(async () => { vi.clearAllMocks(); await i18n.changeLanguage("en"); }); it("renders phone input and send code button", () => { renderLogin(); expect(screen.getByLabelText(/phone number/i)).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Send code" })).toBeInTheDocument(); }); it("shows verify step after successful OTP request", async () => { apiPost.mockResolvedValueOnce({ request_id: "abc-123", expires_at: "2025-01-01T12:00:00Z" }); renderLogin(); fireEvent.change(screen.getByLabelText(/phone number/i), { target: { value: "+966512345678" } }); fireEvent.click(screen.getByRole("button", { name: "Send code" })); await waitFor(() => { expect(screen.getByLabelText(/verification code/i)).toBeInTheDocument(); }); }); it("shows error when OTP request fails", async () => { apiPost.mockRejectedValueOnce(new Error("Rate limited")); renderLogin(); fireEvent.change(screen.getByLabelText(/phone number/i), { target: { value: "+966512345678" } }); fireEvent.click(screen.getByRole("button", { name: "Send code" })); await waitFor(() => { expect(screen.getByText("Rate limited")).toBeInTheDocument(); }); }); });