Skip to content

Commit 3f59f07

Browse files
committed
test(NowView): remove redundant test and add AvailableTasks and FocusedTask tests
- Removed the redundant test for rendering the main content in NowView. - Introduced new unit tests for AvailableTasks and FocusedTask components, covering rendering, task selection, and accessibility features. - Enhanced overall test coverage for task management functionality in the Now view.
1 parent 5c290a0 commit 3f59f07

File tree

3 files changed

+268
-6
lines changed

3 files changed

+268
-6
lines changed

packages/web/src/views/Now/NowView.test.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,4 @@ describe("NowView", () => {
3434
expect(screen.getByText("2")).toBeInTheDocument();
3535
expect(screen.getByText("3")).toBeInTheDocument();
3636
});
37-
38-
it("renders the main content", () => {
39-
render(<NowView />);
40-
41-
expect(screen.getByText("Now View - Coming Soon")).toBeInTheDocument();
42-
});
4337
});
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import "@testing-library/jest-dom";
2+
import { render, screen } from "@testing-library/react";
3+
import userEvent from "@testing-library/user-event";
4+
import { Task } from "@web/views/Day/task.types";
5+
import { AvailableTasks } from "./AvailableTasks";
6+
7+
describe("AvailableTasks", () => {
8+
const mockOnSelectTask = jest.fn();
9+
10+
const mockTask1: Task = {
11+
id: "task-1",
12+
title: "First Task",
13+
status: "todo",
14+
createdAt: "2025-11-15T10:00:00Z",
15+
};
16+
17+
const mockTask2: Task = {
18+
id: "task-2",
19+
title: "Second Task",
20+
status: "todo",
21+
createdAt: "2025-11-15T11:00:00Z",
22+
};
23+
24+
beforeEach(() => {
25+
jest.clearAllMocks();
26+
mockOnSelectTask.mockClear();
27+
});
28+
29+
it("renders empty state when no tasks are provided", () => {
30+
render(<AvailableTasks tasks={[]} onSelectTask={mockOnSelectTask} />);
31+
32+
expect(screen.getByText("No tasks available")).toBeInTheDocument();
33+
expect(
34+
screen.getByText("Create tasks in the Day view to focus on them here"),
35+
).toBeInTheDocument();
36+
expect(
37+
screen.queryByText("Select a task to focus on"),
38+
).not.toBeInTheDocument();
39+
});
40+
41+
it("renders heading and task list when tasks are provided", () => {
42+
render(
43+
<AvailableTasks
44+
tasks={[mockTask1, mockTask2]}
45+
onSelectTask={mockOnSelectTask}
46+
/>,
47+
);
48+
49+
expect(screen.getByText("Select a task to focus on")).toBeInTheDocument();
50+
expect(screen.getByText("First Task")).toBeInTheDocument();
51+
expect(screen.getByText("Second Task")).toBeInTheDocument();
52+
expect(screen.queryByText("No tasks available")).not.toBeInTheDocument();
53+
});
54+
55+
it("renders all tasks in the list", () => {
56+
const tasks = [mockTask1, mockTask2];
57+
render(<AvailableTasks tasks={tasks} onSelectTask={mockOnSelectTask} />);
58+
59+
const taskButtons = screen.getAllByRole("button");
60+
expect(taskButtons).toHaveLength(2);
61+
expect(screen.getByText("First Task")).toBeInTheDocument();
62+
expect(screen.getByText("Second Task")).toBeInTheDocument();
63+
});
64+
65+
it("calls onSelectTask when a task is clicked", async () => {
66+
const user = userEvent.setup();
67+
render(
68+
<AvailableTasks
69+
tasks={[mockTask1, mockTask2]}
70+
onSelectTask={mockOnSelectTask}
71+
/>,
72+
);
73+
74+
const firstTask = screen.getByText("First Task").closest('[role="button"]');
75+
expect(firstTask).toBeInTheDocument();
76+
77+
await user.click(firstTask!);
78+
79+
expect(mockOnSelectTask).toHaveBeenCalledWith("task-1");
80+
expect(mockOnSelectTask).toHaveBeenCalledTimes(1);
81+
});
82+
83+
it("calls onSelectTask with correct task ID for each task", async () => {
84+
const user = userEvent.setup();
85+
render(
86+
<AvailableTasks
87+
tasks={[mockTask1, mockTask2]}
88+
onSelectTask={mockOnSelectTask}
89+
/>,
90+
);
91+
92+
const firstTask = screen.getByText("First Task").closest('[role="button"]');
93+
const secondTask = screen
94+
.getByText("Second Task")
95+
.closest('[role="button"]');
96+
97+
await user.click(firstTask!);
98+
expect(mockOnSelectTask).toHaveBeenCalledWith("task-1");
99+
100+
await user.click(secondTask!);
101+
expect(mockOnSelectTask).toHaveBeenCalledWith("task-2");
102+
expect(mockOnSelectTask).toHaveBeenCalledTimes(2);
103+
});
104+
105+
it("calls onSelectTask when Enter key is pressed on a task", async () => {
106+
const user = userEvent.setup();
107+
render(
108+
<AvailableTasks tasks={[mockTask1]} onSelectTask={mockOnSelectTask} />,
109+
);
110+
111+
const taskButton = screen
112+
.getByText("First Task")
113+
.closest('[role="button"]');
114+
expect(taskButton).toBeInTheDocument();
115+
116+
(taskButton as HTMLElement).focus();
117+
await user.keyboard("{Enter}");
118+
119+
expect(mockOnSelectTask).toHaveBeenCalledWith("task-1");
120+
expect(mockOnSelectTask).toHaveBeenCalledTimes(1);
121+
});
122+
123+
it("calls onSelectTask when Space key is pressed on a task", async () => {
124+
const user = userEvent.setup();
125+
render(
126+
<AvailableTasks tasks={[mockTask1]} onSelectTask={mockOnSelectTask} />,
127+
);
128+
129+
const taskButton = screen
130+
.getByText("First Task")
131+
.closest('[role="button"]');
132+
expect(taskButton).toBeInTheDocument();
133+
134+
(taskButton as HTMLElement).focus();
135+
await user.keyboard(" ");
136+
137+
expect(mockOnSelectTask).toHaveBeenCalledWith("task-1");
138+
expect(mockOnSelectTask).toHaveBeenCalledTimes(1);
139+
});
140+
141+
it("does not call onSelectTask when other keys are pressed", async () => {
142+
const user = userEvent.setup();
143+
render(
144+
<AvailableTasks tasks={[mockTask1]} onSelectTask={mockOnSelectTask} />,
145+
);
146+
147+
const taskButton = screen
148+
.getByText("First Task")
149+
.closest('[role="button"]');
150+
expect(taskButton).toBeInTheDocument();
151+
152+
(taskButton as HTMLElement).focus();
153+
await user.keyboard("{Escape}");
154+
155+
expect(mockOnSelectTask).not.toHaveBeenCalled();
156+
});
157+
158+
it("renders tasks with correct accessibility attributes", () => {
159+
render(
160+
<AvailableTasks tasks={[mockTask1]} onSelectTask={mockOnSelectTask} />,
161+
);
162+
163+
const taskButton = screen
164+
.getByText("First Task")
165+
.closest('[role="button"]');
166+
expect(taskButton).toHaveAttribute("role", "button");
167+
expect(taskButton).toHaveAttribute("tabIndex", "0");
168+
});
169+
170+
it("handles single task correctly", () => {
171+
render(
172+
<AvailableTasks tasks={[mockTask1]} onSelectTask={mockOnSelectTask} />,
173+
);
174+
175+
expect(screen.getByText("Select a task to focus on")).toBeInTheDocument();
176+
expect(screen.getByText("First Task")).toBeInTheDocument();
177+
const taskButtons = screen.getAllByRole("button");
178+
expect(taskButtons).toHaveLength(1);
179+
});
180+
});
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import "@testing-library/jest-dom";
2+
import { render, screen } from "@testing-library/react";
3+
import { Task } from "@web/views/Day/task.types";
4+
import { FocusedTask } from "./FocusedTask";
5+
6+
describe("FocusedTask", () => {
7+
const mockTask: Task = {
8+
id: "task-1",
9+
title: "Test Task",
10+
status: "todo",
11+
createdAt: "2025-11-15T10:00:00Z",
12+
};
13+
14+
const mockCompletedTask: Task = {
15+
id: "task-2",
16+
title: "Completed Task",
17+
status: "completed",
18+
createdAt: "2025-11-15T11:00:00Z",
19+
};
20+
21+
it("renders the task title", () => {
22+
render(<FocusedTask task={mockTask} />);
23+
24+
expect(screen.getByText("Test Task")).toBeInTheDocument();
25+
});
26+
27+
it("renders the task title in a heading", () => {
28+
render(<FocusedTask task={mockTask} />);
29+
30+
const heading = screen.getByRole("heading", { level: 2 });
31+
expect(heading).toBeInTheDocument();
32+
expect(heading).toHaveTextContent("Test Task");
33+
});
34+
35+
it("renders task with completed status", () => {
36+
render(<FocusedTask task={mockCompletedTask} />);
37+
38+
expect(screen.getByText("Completed Task")).toBeInTheDocument();
39+
const heading = screen.getByRole("heading", { level: 2 });
40+
expect(heading).toHaveTextContent("Completed Task");
41+
});
42+
43+
it("renders task with long title", () => {
44+
const longTitleTask: Task = {
45+
id: "task-3",
46+
title: "This is a very long task title that might wrap to multiple lines",
47+
status: "todo",
48+
createdAt: "2025-11-15T12:00:00Z",
49+
};
50+
51+
render(<FocusedTask task={longTitleTask} />);
52+
53+
expect(
54+
screen.getByText(
55+
"This is a very long task title that might wrap to multiple lines",
56+
),
57+
).toBeInTheDocument();
58+
});
59+
60+
it("renders task with special characters in title", () => {
61+
const specialCharTask: Task = {
62+
id: "task-4",
63+
title: "Task with @#$%^&*() special chars!",
64+
status: "todo",
65+
createdAt: "2025-11-15T13:00:00Z",
66+
};
67+
68+
render(<FocusedTask task={specialCharTask} />);
69+
70+
expect(
71+
screen.getByText("Task with @#$%^&*() special chars!"),
72+
).toBeInTheDocument();
73+
});
74+
75+
it("renders task with empty title", () => {
76+
const emptyTitleTask: Task = {
77+
id: "task-5",
78+
title: "",
79+
status: "todo",
80+
createdAt: "2025-11-15T14:00:00Z",
81+
};
82+
83+
render(<FocusedTask task={emptyTitleTask} />);
84+
85+
const heading = screen.getByRole("heading", { level: 2 });
86+
expect(heading).toHaveTextContent("");
87+
});
88+
});

0 commit comments

Comments
 (0)