207 lines
7.3 KiB
TypeScript
207 lines
7.3 KiB
TypeScript
|
|
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
|
import PostJobPage from "./page";
|
|
import { toast } from "sonner";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
// Mock dependencies
|
|
jest.mock("@/lib/i18n", () => ({
|
|
useTranslation: () => ({
|
|
t: (key: string) => key,
|
|
locale: "en",
|
|
setLocale: jest.fn(),
|
|
}),
|
|
useI18n: () => ({
|
|
t: (key: string) => key,
|
|
locale: "en",
|
|
setLocale: jest.fn(),
|
|
}),
|
|
}));
|
|
|
|
jest.mock("next/navigation", () => ({
|
|
useRouter: jest.fn(),
|
|
}));
|
|
|
|
jest.mock("sonner", () => ({
|
|
toast: {
|
|
error: jest.fn(),
|
|
success: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
jest.mock("./translations", () => ({
|
|
translations: {
|
|
en: {
|
|
title: "Post a Job",
|
|
buttons: { next: "Next Step", publish: "Publish Job", publishing: "Publishing..." },
|
|
company: {
|
|
name: "Company Name",
|
|
namePlaceholder: "My Company",
|
|
email: "Email",
|
|
password: "Password",
|
|
confirmPassword: "Confirm Password",
|
|
phone: "Phone",
|
|
},
|
|
job: {
|
|
title: "Job Details",
|
|
jobTitle: "Job Title",
|
|
jobTitlePlaceholder: "e.g. Developer",
|
|
description: "Job Description",
|
|
location: "Location",
|
|
salary: "Salary",
|
|
},
|
|
steps: { data: "Data", confirm: "Confirm" },
|
|
cardTitle: { step1: "Step 1", step2: "Step 2" },
|
|
cardDesc: { step1: "Desc 1", step2: "Desc 2" },
|
|
common: { company: "Company", job: "Job", name: "Name", email: "Email", title: "Title" },
|
|
options: {
|
|
period: { hourly: "/hr" },
|
|
contract: { permanent: "Permanent" },
|
|
hours: { fullTime: "Full Time" },
|
|
mode: { remote: "Remote" }
|
|
},
|
|
errors: {
|
|
company_required: "Company required",
|
|
password_mismatch: "Password mismatch",
|
|
password_length: "Password length",
|
|
job_required: "Job required",
|
|
submit_failed: "Submit failed"
|
|
},
|
|
success: {
|
|
job_created: "Job created"
|
|
}
|
|
},
|
|
},
|
|
}));
|
|
|
|
// Mock RichTextEditor component
|
|
jest.mock("@/components/rich-text-editor", () => ({
|
|
RichTextEditor: ({ value, onChange, placeholder }: any) => (
|
|
<textarea
|
|
placeholder={placeholder}
|
|
value={value}
|
|
onChange={(e) => onChange(e.target.value)}
|
|
data-testid="rich-text-editor"
|
|
/>
|
|
),
|
|
}));
|
|
|
|
// Mock LocationPicker component
|
|
jest.mock("@/components/location-picker", () => ({
|
|
LocationPicker: ({ value, onChange }: any) => (
|
|
<input
|
|
value={value}
|
|
onChange={(e) => onChange(e.target.value)}
|
|
placeholder="Location"
|
|
data-testid="location-picker"
|
|
/>
|
|
),
|
|
}));
|
|
|
|
describe("PostJobPage", () => {
|
|
const mockPush = jest.fn();
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
(useRouter as jest.Mock).mockReturnValue({ push: mockPush });
|
|
global.fetch = jest.fn();
|
|
// Mock scroll methods not in test env
|
|
window.scrollTo = jest.fn();
|
|
});
|
|
|
|
it("renders step 1 initially", () => {
|
|
render(<PostJobPage />);
|
|
expect(screen.getByText("Postar uma Vaga")).toBeInTheDocument();
|
|
expect(screen.getByText("Step 1")).toBeInTheDocument();
|
|
expect(screen.getByPlaceholderText("My Company")).toBeInTheDocument();
|
|
});
|
|
|
|
it("validates company fields before proceeding", () => {
|
|
render(<PostJobPage />);
|
|
|
|
// Try next without filling
|
|
fireEvent.click(screen.getByText("Next Step"));
|
|
expect(toast.error).toHaveBeenCalledWith("Preencha os dados obrigatórios da empresa");
|
|
|
|
// Fill password mismatch
|
|
fireEvent.change(screen.getByPlaceholderText("My Company"), { target: { value: "Test Co" } });
|
|
fireEvent.change(screen.getByPlaceholderText("contato@empresa.com"), { target: { value: "test@co.com" } });
|
|
|
|
const passwords = screen.getAllByPlaceholderText("••••••••");
|
|
fireEvent.change(passwords[0], { target: { value: "12345678" } });
|
|
fireEvent.change(passwords[1], { target: { value: "mismatch" } });
|
|
|
|
fireEvent.click(screen.getByText("Next Step"));
|
|
expect(toast.error).toHaveBeenCalledWith("As senhas não coincidem");
|
|
});
|
|
|
|
it("proceeds to step 2 when company info is valid", () => {
|
|
render(<PostJobPage />);
|
|
|
|
fireEvent.change(screen.getByPlaceholderText("My Company"), { target: { value: "Test Co" } });
|
|
fireEvent.change(screen.getByPlaceholderText("contato@empresa.com"), { target: { value: "test@co.com" } });
|
|
|
|
const passwords = screen.getAllByPlaceholderText("••••••••");
|
|
fireEvent.change(passwords[0], { target: { value: "password123" } });
|
|
fireEvent.change(passwords[1], { target: { value: "password123" } });
|
|
|
|
// Need to fill job description as well now
|
|
fireEvent.change(screen.getByPlaceholderText("e.g. Developer"), { target: { value: "Frontend Dev" } });
|
|
const editors = screen.getAllByTestId("rich-text-editor");
|
|
if (editors.length > 1) {
|
|
fireEvent.change(editors[1], { target: { value: "Job Desc" } });
|
|
} else {
|
|
fireEvent.change(editors[0], { target: { value: "Job Desc" } });
|
|
}
|
|
|
|
fireEvent.click(screen.getByText("Next Step"));
|
|
|
|
expect(screen.getByText("Step 2")).toBeInTheDocument();
|
|
});
|
|
|
|
it("submits the form successfully", async () => {
|
|
(global.fetch as jest.Mock)
|
|
.mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => ({ token: "fake-token" }),
|
|
}) // Register
|
|
.mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => ({ id: "job-123" }),
|
|
}); // Create Job
|
|
|
|
render(<PostJobPage />);
|
|
|
|
// Step 1
|
|
fireEvent.change(screen.getByPlaceholderText("My Company"), { target: { value: "Test Co" } });
|
|
fireEvent.change(screen.getByPlaceholderText("contato@empresa.com"), { target: { value: "test@co.com" } });
|
|
|
|
const passwords = screen.getAllByPlaceholderText("••••••••");
|
|
fireEvent.change(passwords[0], { target: { value: "password123" } });
|
|
fireEvent.change(passwords[1], { target: { value: "password123" } });
|
|
|
|
// Fill Job Details (Step 1)
|
|
fireEvent.change(screen.getByPlaceholderText("e.g. Developer"), { target: { value: "Frontend Dev" } });
|
|
|
|
const editors = screen.getAllByTestId("rich-text-editor");
|
|
if (editors.length > 1) {
|
|
fireEvent.change(editors[1], { target: { value: "Job Desc" } });
|
|
} else {
|
|
fireEvent.change(editors[0], { target: { value: "Job Desc" } });
|
|
}
|
|
|
|
fireEvent.click(screen.getByText("Next Step"));
|
|
|
|
// Check we are on Step 2
|
|
expect(screen.getByText("Step 2")).toBeInTheDocument();
|
|
|
|
// Submit
|
|
fireEvent.click(screen.getByText("Publish Job"));
|
|
|
|
await waitFor(() => {
|
|
expect(global.fetch).toHaveBeenCalledTimes(2);
|
|
expect(toast.success).toHaveBeenCalled();
|
|
expect(mockPush).toHaveBeenCalledWith("/dashboard/jobs");
|
|
});
|
|
});
|
|
});
|