Files
stack/apps/web/src/components/widgets/__tests__/TasksWidget.test.tsx
Jason Woltje 5b77774d91
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
fix(web): remove mock data from dashboard telemetry/tasks/calendar (#656)
Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
2026-03-02 14:19:27 +00:00

125 lines
3.5 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import { TaskStatus, TaskPriority, type Task } from "@mosaic/shared";
import { TasksWidget } from "../TasksWidget";
import { fetchTasks } from "@/lib/api/tasks";
vi.mock("@/lib/api/tasks", () => ({
fetchTasks: vi.fn(),
}));
const mockTasks: Task[] = [
{
id: "task-1",
title: "API task one",
description: null,
status: TaskStatus.IN_PROGRESS,
priority: TaskPriority.HIGH,
dueDate: new Date("2026-02-03T09:00:00Z"),
creatorId: "user-1",
assigneeId: "user-1",
workspaceId: "workspace-1",
projectId: null,
parentId: null,
sortOrder: 0,
metadata: {},
completedAt: null,
createdAt: new Date("2026-02-01T09:00:00Z"),
updatedAt: new Date("2026-02-01T09:00:00Z"),
},
{
id: "task-2",
title: "API task two",
description: null,
status: TaskStatus.NOT_STARTED,
priority: TaskPriority.MEDIUM,
dueDate: new Date("2026-02-04T09:00:00Z"),
creatorId: "user-1",
assigneeId: "user-1",
workspaceId: "workspace-1",
projectId: null,
parentId: null,
sortOrder: 1,
metadata: {},
completedAt: null,
createdAt: new Date("2026-02-01T09:00:00Z"),
updatedAt: new Date("2026-02-01T09:00:00Z"),
},
{
id: "task-3",
title: "API task three",
description: null,
status: TaskStatus.COMPLETED,
priority: TaskPriority.LOW,
dueDate: new Date("2026-02-05T09:00:00Z"),
creatorId: "user-1",
assigneeId: "user-1",
workspaceId: "workspace-1",
projectId: null,
parentId: null,
sortOrder: 2,
metadata: {},
completedAt: new Date("2026-02-02T09:00:00Z"),
createdAt: new Date("2026-02-01T09:00:00Z"),
updatedAt: new Date("2026-02-02T09:00:00Z"),
},
];
async function finishWidgetLoad(): Promise<void> {
await waitFor(() => {
expect(screen.queryByText("Loading tasks...")).not.toBeInTheDocument();
});
}
describe("TasksWidget", (): void => {
beforeEach((): void => {
vi.clearAllMocks();
vi.mocked(fetchTasks).mockResolvedValue(mockTasks);
});
it("renders loading state initially", (): void => {
render(<TasksWidget id="tasks-1" />);
expect(screen.getByText("Loading tasks...")).toBeInTheDocument();
});
it("fetches tasks and renders summary stats", async (): Promise<void> => {
render(<TasksWidget id="tasks-1" />);
await finishWidgetLoad();
expect(fetchTasks).toHaveBeenCalledTimes(1);
expect(screen.getByText("Total")).toBeInTheDocument();
expect(screen.getByText("In Progress")).toBeInTheDocument();
expect(screen.getByText("Done")).toBeInTheDocument();
expect(screen.getByText("3")).toBeInTheDocument();
});
it("renders task rows from API response", async (): Promise<void> => {
render(<TasksWidget id="tasks-1" />);
await finishWidgetLoad();
expect(screen.getByText("API task one")).toBeInTheDocument();
expect(screen.getByText("API task two")).toBeInTheDocument();
expect(screen.getByText("API task three")).toBeInTheDocument();
});
it("shows due date labels for each task", async (): Promise<void> => {
render(<TasksWidget id="tasks-1" />);
await finishWidgetLoad();
expect(screen.getAllByText(/Due:/).length).toBe(3);
});
it("shows empty state when API returns no tasks", async (): Promise<void> => {
vi.mocked(fetchTasks).mockResolvedValueOnce([]);
render(<TasksWidget id="tasks-1" />);
await finishWidgetLoad();
expect(screen.getByText("No tasks yet")).toBeInTheDocument();
});
});