Skip to content

Commit

Permalink
Test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
evadecker committed Nov 28, 2024
1 parent a8fc15d commit 51ccc8a
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,6 @@ import { toast } from "sonner";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { EditQuestCostsModal } from "./EditQuestCostsModal";

// Mock the convex mutation hook
vi.mock("convex/react", () => ({
useMutation: vi.fn(),
}));

// Mock toast notifications
vi.mock("sonner", () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
},
}));

describe("EditQuestCostsModal", () => {
const mockQuest = {
_id: "quest123" as Id<"quests">,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,6 @@ import { toast } from "sonner";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { EditQuestTimeRequiredModal } from "./EditQuestTimeRequiredModal";

// Mock the convex mutation hook
vi.mock("convex/react", () => ({
useMutation: vi.fn(),
}));

// Mock toast notifications
vi.mock("sonner", () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
},
}));

describe("EditQuestTimeRequiredModal", () => {
const mockQuest = {
_id: "quest123" as Id<"quests">,
Expand Down Expand Up @@ -72,6 +59,124 @@ describe("EditQuestTimeRequiredModal", () => {
expect(descriptionInput.value).toBe("Depends on court processing time");
});

it("updates max time value", async () => {
const user = userEvent.setup();
mockUpdateTimeRequired.mockResolvedValueOnce(undefined);

render(
<EditQuestTimeRequiredModal
quest={mockQuest}
open={true}
onOpenChange={mockOnOpenChange}
/>,
);

const maxInput = screen
.getAllByLabelText("Est. max time")[0]
.closest("input") as HTMLInputElement;

await user.clear(maxInput);
await user.type(maxInput, "6");

await user.click(screen.getByText("Save"));

expect(mockUpdateTimeRequired).toHaveBeenCalledWith({
timeRequired: {
min: 2,
max: 6,
unit: "weeks",
description: "Depends on court processing time",
},
questId: "quest123",
});
});

it("updates time unit", async () => {
const user = userEvent.setup();
mockUpdateTimeRequired.mockResolvedValueOnce(undefined);

render(
<EditQuestTimeRequiredModal
quest={mockQuest}
open={true}
onOpenChange={mockOnOpenChange}
/>,
);

const unitSelect = screen.getByLabelText("Unit");
await user.click(unitSelect);
await user.click(screen.getByRole("option", { name: "Days" }));

await user.click(screen.getByText("Save"));

expect(mockUpdateTimeRequired).toHaveBeenCalledWith({
timeRequired: {
min: 2,
max: 4,
unit: "days",
description: "Depends on court processing time",
},
questId: "quest123",
});
});

it("updates description", async () => {
const user = userEvent.setup();
mockUpdateTimeRequired.mockResolvedValueOnce(undefined);

render(
<EditQuestTimeRequiredModal
quest={mockQuest}
open={true}
onOpenChange={mockOnOpenChange}
/>,
);

const descriptionInput = screen.getByLabelText("Description");
await user.clear(descriptionInput);
await user.type(descriptionInput, "New description");

await user.click(screen.getByText("Save"));

expect(mockUpdateTimeRequired).toHaveBeenCalledWith({
timeRequired: {
min: 2,
max: 4,
unit: "weeks",
description: "New description",
},
questId: "quest123",
});
});

it("sets description to undefined when empty", async () => {
const user = userEvent.setup();
mockUpdateTimeRequired.mockResolvedValueOnce(undefined);

render(
<EditQuestTimeRequiredModal
quest={mockQuest}
open={true}
onOpenChange={mockOnOpenChange}
/>,
);

const descriptionInput = screen.getByLabelText("Description");
await user.clear(descriptionInput);

await user.click(screen.getByText("Save"));

expect(mockUpdateTimeRequired).toHaveBeenCalledWith({
timeRequired: {
min: 2,
max: 4,
unit: "weeks",
description: undefined,
},
questId: "quest123",
});
});

it("handles successful save", async () => {
const user = userEvent.setup();
mockUpdateTimeRequired.mockResolvedValueOnce(undefined);
Expand Down
20 changes: 14 additions & 6 deletions src/components/quests/QuestCosts/QuestCosts.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import type { Doc, Id } from "@convex/_generated/dataModel";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import { describe, expect, it } from "vitest";
import { QuestCosts } from "./QuestCosts";

// Mock the convex mutation hook
vi.mock("convex/react", () => ({
useMutation: vi.fn(),
}));

describe("QuestCosts", () => {
const mockQuest = {
_id: "quest123" as Id<"quests">,
Expand All @@ -23,6 +18,14 @@ describe("QuestCosts", () => {
costs: [],
} as Partial<Doc<"quests">>;

const mockQuestZeroCost = {
_id: "quest789" as Id<"quests">,
costs: [
{ cost: 0, description: "Free application" },
{ cost: 0, description: "No filing fee" },
],
} as Doc<"quests">;

it("displays costs in a description list with total", async () => {
render(<QuestCosts quest={mockQuest} />);

Expand Down Expand Up @@ -60,6 +63,11 @@ describe("QuestCosts", () => {
expect(screen.getByText("Free")).toBeInTheDocument();
});

it("displays 'Free' when total cost is 0 but costs array is not empty", () => {
render(<QuestCosts quest={mockQuestZeroCost} />);
expect(screen.getByText("Free")).toBeInTheDocument();
});

it("shows edit button when editable prop is true", async () => {
const user = userEvent.setup();
render(<QuestCosts quest={mockQuest} editable={true} />);
Expand Down
93 changes: 93 additions & 0 deletions src/components/quests/QuestTimeRequired/QuestTimeRequired.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { Doc, Id } from "@convex/_generated/dataModel";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it } from "vitest";
import { QuestTimeRequired } from "./QuestTimeRequired";

describe("QuestTimeRequired", () => {
const mockQuest = {
_id: "quest123" as Id<"quests">,
timeRequired: {
min: 2,
max: 4,
unit: "weeks",
description: "Processing time varies by court",
},
} as Doc<"quests">;

const mockQuestNoDescription = {
_id: "quest456" as Id<"quests">,
timeRequired: {
min: 1,
max: 3,
unit: "months",
},
} as Doc<"quests">;

const mockQuestNoTimeRequired = {
_id: "quest789" as Id<"quests">,
} as Doc<"quests">;

it("returns null when quest is undefined", () => {
const { container } = render(
<QuestTimeRequired quest={undefined as unknown as Doc<"quests">} />,
);
expect(container.firstChild).toBeNull();
});

it("formats and displays time required correctly", () => {
render(<QuestTimeRequired quest={mockQuest} />);
expect(screen.getByText("2–4 weeks")).toBeInTheDocument();
});

it("displays 'Unknown' when timeRequired is not set", () => {
render(<QuestTimeRequired quest={mockQuestNoTimeRequired} />);
expect(screen.getByText("Unknown")).toBeInTheDocument();
});

it("shows description in popover when available", async () => {
const user = userEvent.setup();
render(<QuestTimeRequired quest={mockQuest} />);

// Find and click the popover trigger
const popoverTrigger = screen.getByRole("button", {
name: "See details",
});
await user.click(popoverTrigger);

// Check if description is shown
expect(
screen.getByText("Processing time varies by court"),
).toBeInTheDocument();
});

it("does not show description popover when description is not available", () => {
render(<QuestTimeRequired quest={mockQuestNoDescription} />);
expect(
screen.queryByRole("button", { name: "See details" }),
).not.toBeInTheDocument();
});

it("shows edit button when editable prop is true", async () => {
const user = userEvent.setup();
render(<QuestTimeRequired quest={mockQuest} editable={true} />);

// Check if edit button is present
const editButton = screen.getByRole("button", {
name: "Edit time required",
});
expect(editButton).toBeInTheDocument();

// Click edit button and check if modal opens
await user.click(editButton);
const modal = await screen.findByRole("dialog");
expect(modal).toBeInTheDocument();
});

it("hides edit button when editable prop is false", () => {
render(<QuestTimeRequired quest={mockQuest} editable={false} />);
expect(
screen.queryByRole("button", { name: "Edit time required" }),
).not.toBeInTheDocument();
});
});
14 changes: 14 additions & 0 deletions vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
import "@testing-library/jest-dom/vitest";
import { vi } from "vitest";

// Mock the convex mutation hook
vi.mock("convex/react", () => ({
useMutation: vi.fn(),
}));

// Mock toast notifications
vi.mock("sonner", () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
},
}));

0 comments on commit 51ccc8a

Please sign in to comment.