mediahub-fe/__tests__/auth/login-form.test.tsx

264 lines
7.4 KiB
TypeScript
Raw Normal View History

import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { LoginForm } from "@/components/auth/login-form";
import { useAuth, useEmailValidation } from "@/hooks/use-auth";
// Mock the hooks
jest.mock("@/hooks/use-auth");
jest.mock("@/service/landing/landing", () => ({
listRole: jest.fn().mockResolvedValue({
data: {
data: [
{ id: 1, name: "Admin" },
{ id: 2, name: "User" },
],
},
}),
}));
// Mock next-intl
jest.mock("next-intl", () => ({
useTranslations: () => (key: string, options?: any) => {
const defaults = {
logInPlease: "Log In Please",
acc: "Acc",
register: "Register",
password: "Password",
rememberMe: "Remember Me",
forgotPass: "Forgot Pass",
next: "Next",
categoryReg: "Category Reg",
selectOne: "Select One",
signIn: "Sign In",
};
return options?.defaultValue || defaults[key] || key;
},
}));
const mockUseAuth = useAuth as jest.MockedFunction<typeof useAuth>;
const mockUseEmailValidation = useEmailValidation as jest.MockedFunction<typeof useEmailValidation>;
describe("LoginForm", () => {
const mockLogin = jest.fn();
const mockValidateEmail = jest.fn();
const mockOnSuccess = jest.fn();
const mockOnError = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
mockUseAuth.mockReturnValue({
login: mockLogin,
logout: jest.fn(),
refreshToken: jest.fn(),
isAuthenticated: false,
user: null,
loading: false,
error: null,
});
mockUseEmailValidation.mockReturnValue({
validateEmail: mockValidateEmail,
loading: false,
error: null,
});
});
it("renders login form with all required fields", () => {
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
expect(screen.getByText("Log In Please")).toBeInTheDocument();
expect(screen.getByLabelText(/username/i)).toBeInTheDocument();
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
expect(screen.getByRole("button", { name: /selanjutnya/i })).toBeInTheDocument();
});
it("shows validation errors for invalid input", async () => {
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const submitButton = screen.getByRole("button", { name: /selanjutnya/i });
fireEvent.click(submitButton);
await waitFor(() => {
expect(screen.getByText("Username is required")).toBeInTheDocument();
expect(screen.getByText("Password is required")).toBeInTheDocument();
});
});
it("handles successful form submission", async () => {
mockValidateEmail.mockResolvedValue("success");
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const usernameInput = screen.getByLabelText(/username/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByRole("button", { name: /selanjutnya/i });
fireEvent.change(usernameInput, { target: { value: "testuser" } });
fireEvent.change(passwordInput, { target: { value: "password123" } });
fireEvent.click(submitButton);
await waitFor(() => {
expect(mockValidateEmail).toHaveBeenCalledWith({
username: "testuser",
password: "password123",
});
});
});
it("handles email validation step", async () => {
mockValidateEmail.mockResolvedValue("setup");
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const usernameInput = screen.getByLabelText(/username/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByRole("button", { name: /selanjutnya/i });
fireEvent.change(usernameInput, { target: { value: "testuser" } });
fireEvent.change(passwordInput, { target: { value: "password123" } });
fireEvent.click(submitButton);
await waitFor(() => {
expect(mockOnError).toHaveBeenCalledWith("Email setup required");
});
});
it("handles OTP step", async () => {
mockValidateEmail.mockResolvedValue("otp");
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const usernameInput = screen.getByLabelText(/username/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByRole("button", { name: /selanjutnya/i });
fireEvent.change(usernameInput, { target: { value: "testuser" } });
fireEvent.change(passwordInput, { target: { value: "password123" } });
fireEvent.click(submitButton);
await waitFor(() => {
expect(mockOnError).toHaveBeenCalledWith("OTP verification required");
});
});
it("toggles password visibility", () => {
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const passwordInput = screen.getByLabelText(/password/i);
const toggleButton = screen.getByLabelText(/show password/i);
expect(passwordInput).toHaveAttribute("type", "password");
fireEvent.click(toggleButton);
expect(passwordInput).toHaveAttribute("type", "text");
expect(screen.getByLabelText(/hide password/i)).toBeInTheDocument();
fireEvent.click(toggleButton);
expect(passwordInput).toHaveAttribute("type", "password");
});
it("handles remember me checkbox", () => {
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const rememberMeCheckbox = screen.getByRole("checkbox", { name: /remember me/i });
expect(rememberMeCheckbox).toBeChecked();
fireEvent.click(rememberMeCheckbox);
expect(rememberMeCheckbox).not.toBeChecked();
});
it("opens registration dialog", () => {
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const registerLink = screen.getByText("Register");
fireEvent.click(registerLink);
expect(screen.getByText("Category Reg")).toBeInTheDocument();
expect(screen.getByText("Select One")).toBeInTheDocument();
expect(screen.getByLabelText("Admin")).toBeInTheDocument();
expect(screen.getByLabelText("User")).toBeInTheDocument();
});
it("handles loading state", async () => {
mockUseEmailValidation.mockReturnValue({
validateEmail: mockValidateEmail,
loading: true,
error: null,
});
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const submitButton = screen.getByRole("button", { name: /processing/i });
expect(submitButton).toBeDisabled();
});
it("handles error state", async () => {
mockValidateEmail.mockRejectedValue(new Error("Validation failed"));
render(
<LoginForm
onSuccess={mockOnSuccess}
onError={mockOnError}
/>
);
const usernameInput = screen.getByLabelText(/username/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByRole("button", { name: /selanjutnya/i });
fireEvent.change(usernameInput, { target: { value: "testuser" } });
fireEvent.change(passwordInput, { target: { value: "password123" } });
fireEvent.click(submitButton);
await waitFor(() => {
expect(mockOnError).toHaveBeenCalledWith("Validation failed");
});
});
});