feat(tests): fix candidate dashboard and apply form tests
This commit is contained in:
parent
812affb803
commit
93ca6d64ef
3 changed files with 74 additions and 22 deletions
|
|
@ -85,7 +85,7 @@ func ValidateJWT(secret, env string) error {
|
|||
// warning is always returned if short.
|
||||
// fatal error is returned if production.
|
||||
// Caller handles logging.
|
||||
return fmt.Errorf(msg)
|
||||
return fmt.Errorf("%s", msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
||||
import { Suspense } from "react";
|
||||
import JobApplicationPage from "./page";
|
||||
import { jobsApi, applicationsApi } from "@/lib/api";
|
||||
import { useNotify } from "@/contexts/notification-context";
|
||||
|
|
@ -40,6 +41,25 @@ jest.mock("@/components/ui/progress", () => ({
|
|||
Progress: () => <div data-testid="progress" />,
|
||||
}));
|
||||
|
||||
jest.mock("framer-motion", () => ({
|
||||
motion: { div: ({ children }: any) => <div>{children}</div> },
|
||||
AnimatePresence: ({ children }: any) => <>{children}</>,
|
||||
}));
|
||||
|
||||
jest.mock("@/components/ui/select", () => ({
|
||||
Select: ({ onValueChange, children }: any) => (
|
||||
<div data-testid="select">
|
||||
<button data-testid="select-option-3k" onClick={() => onValueChange("up-to-3k")}>
|
||||
Select 3k
|
||||
</button>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
SelectTrigger: ({ children }: any) => <button>{children}</button>,
|
||||
SelectValue: ({ placeholder }: any) => <span>{placeholder}</span>,
|
||||
SelectContent: ({ children }: any) => <div>{children}</div>,
|
||||
SelectItem: ({ children }: any) => <div>{children}</div>,
|
||||
}));
|
||||
|
||||
describe("JobApplicationPage", () => {
|
||||
const mockPush = jest.fn();
|
||||
|
|
@ -59,22 +79,34 @@ describe("JobApplicationPage", () => {
|
|||
window.scrollTo = jest.fn();
|
||||
});
|
||||
|
||||
// Since component uses `use(params)`, we need to wrap or pass a promise
|
||||
const params = Promise.resolve({ id: "job-123" });
|
||||
|
||||
it("renders job title and company info", async () => {
|
||||
render(<JobApplicationPage params={params} />);
|
||||
const params: any = Promise.resolve({ id: "job-123" });
|
||||
params.status = "fulfilled";
|
||||
params.value = { id: "job-123" };
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Application: Software Engineer")).toBeInTheDocument();
|
||||
expect(screen.getByText(/Tech Corp/)).toBeInTheDocument();
|
||||
});
|
||||
render(
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<JobApplicationPage params={params} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
expect(await screen.findByText("Application: Software Engineer")).toBeInTheDocument();
|
||||
expect(screen.getByText(/Tech Corp/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("validates step 1 fields", async () => {
|
||||
render(<JobApplicationPage params={params} />);
|
||||
const params: any = Promise.resolve({ id: "job-123" });
|
||||
params.status = "fulfilled";
|
||||
params.value = { id: "job-123" };
|
||||
|
||||
await waitFor(() => expect(screen.getByText("Application: Software Engineer")).toBeInTheDocument());
|
||||
render(
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<JobApplicationPage params={params} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
// Wait for load
|
||||
expect(await screen.findByText("Application: Software Engineer")).toBeInTheDocument();
|
||||
|
||||
// Try next empty
|
||||
const nextBtn = screen.getByRole("button", { name: /Next step/i });
|
||||
|
|
@ -91,19 +123,29 @@ describe("JobApplicationPage", () => {
|
|||
expect(mockNotify.error).toHaveBeenCalledWith("Privacy policy", expect.any(String));
|
||||
|
||||
// Check checkbox
|
||||
// Finding checkbox by ID might be easiest or by label text click
|
||||
const policyLabel = screen.getByText(/I have read and agree to the/i);
|
||||
fireEvent.click(policyLabel); // Should toggle checkbox associated with label
|
||||
fireEvent.click(policyLabel);
|
||||
|
||||
fireEvent.click(nextBtn);
|
||||
|
||||
// Should move to step 2
|
||||
expect(screen.getByText("Resume & Documents")).toBeInTheDocument();
|
||||
await waitFor(() => expect(screen.getByText("Resume (CV) *")).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it("submits application successfully", async () => {
|
||||
render(<JobApplicationPage params={params} />);
|
||||
await waitFor(() => expect(jobsApi.getById).toHaveBeenCalled());
|
||||
const params: any = Promise.resolve({ id: "job-123" });
|
||||
params.status = "fulfilled";
|
||||
params.value = { id: "job-123" };
|
||||
|
||||
render(
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<JobApplicationPage params={params} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
// Wait for load
|
||||
expect(await screen.findByText("Application: Software Engineer")).toBeInTheDocument();
|
||||
await waitFor(() => expect(screen.getByLabelText(/Full name/i)).toBeInTheDocument());
|
||||
|
||||
// Step 1
|
||||
fireEvent.change(screen.getByLabelText(/Full name/i), { target: { value: "John Doe" } });
|
||||
|
|
@ -113,21 +155,23 @@ describe("JobApplicationPage", () => {
|
|||
fireEvent.click(screen.getByRole("button", { name: /Next step/i }));
|
||||
|
||||
// Step 2
|
||||
// Optional fields here or skip
|
||||
// Resume is technically required (Step 2 logic: case 2 returns true currently in the simplified code?
|
||||
// Looking at source: case 2: return true; (lines 122). So no validation on Step 2!)
|
||||
await waitFor(() => expect(screen.getByText("Resume (CV) *")).toBeInTheDocument());
|
||||
fireEvent.click(screen.getByRole("button", { name: /Next step/i }));
|
||||
|
||||
// Wait for Step 3
|
||||
await waitFor(() => expect(screen.getByText("Salary expectation *")).toBeInTheDocument());
|
||||
|
||||
// Step 3
|
||||
// Salary and Experience
|
||||
const trigger = screen.getByText("Select a range");
|
||||
fireEvent.click(trigger);
|
||||
fireEvent.click(screen.getByText("Up to R$ 3,000")); // SelectOption
|
||||
fireEvent.click(screen.getByTestId("select-option-3k"));
|
||||
|
||||
fireEvent.click(screen.getByLabelText("Yes, I do")); // Radio
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /Next step/i }));
|
||||
|
||||
await waitFor(() => expect(screen.getByLabelText(/Why do you want to work/i)).toBeInTheDocument());
|
||||
|
||||
// Step 4
|
||||
// Why Us and Availability
|
||||
fireEvent.change(screen.getByLabelText(/Why do you want to work/i), { target: { value: "Because I like it." } });
|
||||
|
|
|
|||
|
|
@ -49,6 +49,14 @@ jest.mock("@/components/ui/skeleton", () => ({
|
|||
Skeleton: () => <div>Loading...</div>,
|
||||
}))
|
||||
|
||||
jest.mock("@/components/stats-card", () => ({
|
||||
StatsCard: () => <div>StatsCard</div>,
|
||||
}))
|
||||
|
||||
jest.mock("@/components/job-card", () => ({
|
||||
JobCard: () => <div>JobCard</div>,
|
||||
}))
|
||||
|
||||
describe("CandidateDashboard", () => {
|
||||
it("renders welcome message", async () => {
|
||||
render(<CandidateDashboardContent />)
|
||||
|
|
@ -56,6 +64,6 @@ describe("CandidateDashboard", () => {
|
|||
// Assuming dashboard has "Welcome" or similar
|
||||
// Or check for section headers "My Applications", "Recommended Jobs"
|
||||
// Wait for potential async data loading
|
||||
expect(await screen.findByText(/Recommended Jobs/i)).toBeInTheDocument()
|
||||
expect(await screen.findByText("candidate.dashboard.recommended.title")).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue