refactor: move from union type to object enum

This commit is contained in:
2026-07-15 02:41:17 +05:00
parent 35465f581f
commit 84f64af62d
30 changed files with 490 additions and 193 deletions
+60 -26
View File
@@ -1,11 +1,16 @@
import { describe, expect, it } from "vitest";
import { Task } from "@/model/task";
import {
TASK_STATUS_META,
TASK_STATUS_ORDER,
TaskStatus,
} from "@/model/taskStatus";
import { buildKanbanBoard } from "./buildKanbanBoard";
function task(partial: Partial<Task> & Pick<Task, "id" | "title">): Task {
return {
description: "",
status: "todo",
status: TaskStatus.TODO,
priority: "medium",
tags: [],
assignee: "",
@@ -15,70 +20,99 @@ function task(partial: Partial<Task> & Pick<Task, "id" | "title">): Task {
};
}
const visibleStatuses = TASK_STATUS_ORDER.filter(
(status) => !TASK_STATUS_META[status].defaultHidden,
);
describe("buildKanbanBoard", () => {
const tasks: Task[] = [
task({
id: "a",
title: "Done one",
status: "done",
status: TaskStatus.DONE,
updated: "2026-01-01T00:00:02.000Z",
}),
task({
id: "b",
title: "Todo older",
status: "todo",
status: TaskStatus.TODO,
updated: "2026-01-01T00:00:01.000Z",
}),
task({
id: "c",
title: "Todo newer",
status: "todo",
status: TaskStatus.TODO,
updated: "2026-01-01T00:00:03.000Z",
}),
task({
id: "d",
title: "In progress",
status: "in-progress",
status: TaskStatus.IN_PROGRESS,
updated: "2026-01-01T00:00:04.000Z",
}),
task({
id: "e",
title: "Backlog item",
status: TaskStatus.BACKLOG,
updated: "2026-01-01T00:00:00.000Z",
}),
task({
id: "f",
title: "Cancelled",
status: TaskStatus.CANCELLED,
updated: "2026-01-01T00:00:05.000Z",
}),
];
it("returns all status columns in fixed order, including empty", () => {
it("hides defaultHidden statuses by default", () => {
const board = buildKanbanBoard(tasks);
const statuses = board.columns.map((col) => col.status);
expect(board.columns.map((col) => col.status)).toEqual([
"todo",
"in-progress",
"done",
"cancelled",
]);
expect(board.columns.map((col) => col.label)).toEqual([
"To Do",
"In Progress",
"Done",
"Cancelled",
]);
expect(board.columns[3].tasks).toEqual([]);
expect(statuses).toEqual(visibleStatuses);
for (const col of board.columns) {
expect(TASK_STATUS_META[col.status].defaultHidden).toBe(false);
expect(col.label).toBe(TASK_STATUS_META[col.status].label);
}
});
it("includes all statuses when showHiddenStatuses is true", () => {
const board = buildKanbanBoard(tasks, { showHiddenStatuses: true });
expect(board.columns.map((col) => col.status)).toEqual(TASK_STATUS_ORDER);
for (const col of board.columns) {
expect(col.label).toBe(TASK_STATUS_META[col.status].label);
}
});
it("places each task into the column matching its status", () => {
const board = buildKanbanBoard(tasks);
const board = buildKanbanBoard(tasks, { showHiddenStatuses: true });
expect(board.columns[0].tasks.map((t) => t.id)).toEqual(["c", "b"]);
expect(board.columns[1].tasks.map((t) => t.id)).toEqual(["d"]);
expect(board.columns[2].tasks.map((t) => t.id)).toEqual(["a"]);
for (const col of board.columns) {
for (const t of col.tasks) {
expect(t.status).toBe(col.status);
}
}
const byStatus = Object.fromEntries(
board.columns.map((col) => [col.status, col.tasks.map((t) => t.id)]),
);
expect(byStatus[TaskStatus.TODO]).toEqual(["c", "b"]);
expect(byStatus[TaskStatus.IN_PROGRESS]).toEqual(["d"]);
expect(byStatus[TaskStatus.DONE]).toEqual(["a"]);
expect(byStatus[TaskStatus.BACKLOG]).toEqual(["e"]);
expect(byStatus[TaskStatus.CANCELLED]).toEqual(["f"]);
});
it("sorts tasks within a column by updated desc", () => {
const board = buildKanbanBoard(tasks);
const todo = board.columns.find((col) => col.status === "todo");
const todo = board.columns.find((col) => col.status === TaskStatus.TODO);
expect(todo?.tasks.map((t) => t.id)).toEqual(["c", "b"]);
});
it("returns empty columns when there are no tasks", () => {
it("returns empty visible columns when there are no tasks", () => {
const board = buildKanbanBoard([]);
expect(board.columns).toHaveLength(4);
expect(board.columns.map((col) => col.status)).toEqual(visibleStatuses);
for (const col of board.columns) {
expect(col.tasks).toEqual([]);
}