/* 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("