Files
Salon/frontend/src/pages/LoginPage.test.jsx
T

61 lines
1.9 KiB
React

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(
<AuthProvider>
<BrowserRouter>
<LoginPage />
</BrowserRouter>
</AuthProvider>
);
}
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();
});
});
});