/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { describe, it, expect } from "vitest"; import { render, screen } from "@testing-library/react"; import { TaskItem } from "./TaskItem"; import { TaskStatus, TaskPriority, type Task } from "@mosaic/shared"; describe("TaskItem", (): void => { const baseTask: Task = { id: "task-1", title: "Test task", description: "Task description", status: TaskStatus.IN_PROGRESS, priority: TaskPriority.MEDIUM, dueDate: new Date("2026-01-29"), creatorId: "user-1", assigneeId: "user-1", workspaceId: "workspace-1", projectId: null, parentId: null, sortOrder: 0, metadata: {}, completedAt: null, createdAt: new Date("2026-01-28"), updatedAt: new Date("2026-01-28"), }; it("should render task title", (): void => { render(); expect(screen.getByText("Test task")).toBeInTheDocument(); }); it("should render task description when present", (): void => { render(); expect(screen.getByText("Task description")).toBeInTheDocument(); }); it("should show status indicator for active task", (): void => { render(); expect(screen.getByText("🟢")).toBeInTheDocument(); }); it("should show status indicator for not started task", (): void => { render(); expect(screen.getByText("⚪")).toBeInTheDocument(); }); it("should show status indicator for paused task", (): void => { render(); expect(screen.getByText("⏸️")).toBeInTheDocument(); }); it("should display priority badge", (): void => { render(); expect(screen.getByText("High priority")).toBeInTheDocument(); }); it("should not use demanding language", (): void => { const { container } = render(); const text = container.textContent; expect(text).not.toMatch(/overdue/i); expect(text).not.toMatch(/urgent/i); expect(text).not.toMatch(/must/i); expect(text).not.toMatch(/critical/i); }); it("should show 'Target passed' for past due dates", (): void => { const pastTask = { ...baseTask, dueDate: new Date("2026-01-27"), // Past date }; render(); expect(screen.getByText(/target passed/i)).toBeInTheDocument(); }); it("should show 'Approaching target' for near due dates", (): void => { const soonTask = { ...baseTask, dueDate: new Date(Date.now() + 12 * 60 * 60 * 1000), // 12 hours from now }; render(); expect(screen.getByText(/approaching target/i)).toBeInTheDocument(); }); describe("error states", (): void => { it("should handle task with missing title", (): void => { const taskWithoutTitle = { ...baseTask, title: "", }; const { container } = render(); // Should render without crashing, even with empty title expect(container.querySelector(".bg-white")).toBeInTheDocument(); }); it("should handle task with missing description", (): void => { const taskWithoutDescription = { ...baseTask, description: null, }; render(); expect(screen.getByText("Test task")).toBeInTheDocument(); // Description paragraph should not be rendered when null expect(screen.queryByText("Task description")).not.toBeInTheDocument(); }); it("should handle task with invalid status", (): void => { const taskWithInvalidStatus = { ...baseTask, // eslint-disable-next-line @typescript-eslint/no-explicit-any status: "invalid-status" as any, }; const { container } = render(); // Should render without crashing even with invalid status expect(container.querySelector(".bg-white")).toBeInTheDocument(); expect(screen.getByText("Test task")).toBeInTheDocument(); }); it("should handle task with invalid priority", (): void => { const taskWithInvalidPriority = { ...baseTask, // eslint-disable-next-line @typescript-eslint/no-explicit-any priority: "invalid-priority" as any, }; const { container } = render(); // Should render without crashing even with invalid priority expect(container.querySelector(".bg-white")).toBeInTheDocument(); expect(screen.getByText("Test task")).toBeInTheDocument(); }); it("should handle task with missing dueDate", (): void => { const taskWithoutDueDate = { ...baseTask, dueDate: null, }; // eslint-disable-next-line @typescript-eslint/no-explicit-any render(); expect(screen.getByText("Test task")).toBeInTheDocument(); }); it("should handle task with invalid dueDate", (): void => { const taskWithInvalidDate = { ...baseTask, dueDate: new Date("invalid-date"), }; const { container } = render(); expect(container.querySelector(".bg-white")).toBeInTheDocument(); expect(screen.getByText("Test task")).toBeInTheDocument(); }); it("should handle task with very long title", (): void => { const longTitle = "A".repeat(500); const taskWithLongTitle = { ...baseTask, title: longTitle, }; render(); expect(screen.getByText(longTitle)).toBeInTheDocument(); }); it("should handle task with special characters in title", (): void => { const taskWithSpecialChars = { ...baseTask, title: '', }; const { container } = render(); // Should render escaped HTML entities, not execute // React escapes to <img... > which is safe expect(container.innerHTML).toContain("<img"); expect(container.innerHTML).not.toContain("/)).toBeInTheDocument(); }); it("should handle task with HTML in description", (): void => { const taskWithHtmlDesc = { ...baseTask, description: 'Bold text', }; const { container } = render(); // Should render as text, not HTML - React escapes by default expect(container.innerHTML).not.toContain("