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 { 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(); expect(screen.getByText("Loading tasks...")).toBeInTheDocument(); }); it("fetches tasks and renders summary stats", async (): Promise => { render(); 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 => { render(); 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 => { render(); await finishWidgetLoad(); expect(screen.getAllByText(/Due:/).length).toBe(3); }); it("shows empty state when API returns no tasks", async (): Promise => { vi.mocked(fetchTasks).mockResolvedValueOnce([]); render(); await finishWidgetLoad(); expect(screen.getByText("No tasks yet")).toBeInTheDocument(); }); });