You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.0 KiB
TypeScript

// frontend/tests/tasks/tree.test.ts
import { describe, expect, it } from "vitest";
import {
buildIndex,
dueLabel,
editTree,
findPath,
isSoon,
pct,
stat,
} from "@/lib/tasks/tree";
import type { Folder, Task } from "@/lib/types";
function t(id: string, status: Task["status"], children: Task[] = [], due: string | null = null): Task {
return {
id,
project_id: "biz-report",
parent_id: null,
title: id,
status,
assignee_id: "jiwoo",
due,
prio: "보통",
notes: "",
est: "",
delegated: false,
sort_order: 0,
created_at: "",
updated_at: "",
comments: [],
children,
};
}
describe("tree utils", () => {
it("findPath 무한 중첩 경로", () => {
const tree = [t("k1", "doing", [t("kx7", "doing", [t("kx9", "todo")])])];
const p = findPath(tree, "kx9");
expect(p?.map((n) => n.id)).toEqual(["k1", "kx7", "kx9"]);
});
it("editTree 깊은 노드 갱신 (형제 불변)", () => {
const tree = [t("k1", "doing", [t("a", "todo"), t("b", "todo")])];
const next = editTree(tree, "b", (n) => ({ ...n, status: "done" }));
expect(next[0].children[0].status).toBe("todo"); // a 불변
expect(next[0].children[1].status).toBe("done"); // b 변경
});
it("stat/pct 진행률", () => {
const node = t("k", "doing", [t("a", "done"), t("b", "done"), t("c", "todo")]);
expect(stat(node)).toEqual({ total: 3, done: 2 });
expect(pct(node)).toBe(67);
});
it("dueLabel ISO → 6/8", () => {
expect(dueLabel("2026-06-08")).toBe("6/8");
expect(dueLabel(null)).toBe("—");
});
it("isSoon: due<=8 && !done", () => {
expect(isSoon(t("a", "todo", [], "2026-06-08"))).toBe(true);
expect(isSoon(t("a", "done", [], "2026-06-08"))).toBe(false);
expect(isSoon(t("a", "todo", [], "2026-06-20"))).toBe(false);
});
it("buildIndex isDescendant 필터", () => {
const folders: Folder[] = [
{
id: "work",
name: "업무",
tone: "ink",
icon: "folder",
sort_order: 0,
is_system: true,
projects: [
{
id: "biz",
folder_id: "work",
parent_id: null,
name: "경영",
tone: "coral",
sort_order: 0,
pinned: false,
task_count: 0,
children: [
{
id: "biz-report",
folder_id: "work",
parent_id: "biz",
name: "리포트",
tone: "coral",
sort_order: 0,
pinned: false,
task_count: 0,
children: [],
},
],
},
],
},
];
const ix = buildIndex(folders);
expect(ix.isDescendant("biz-report", "work")).toBe(true);
expect(ix.isDescendant("biz-report", "biz")).toBe(true);
expect(ix.isDescendant("biz", "biz-report")).toBe(false);
expect(ix.pathOf("biz-report").map((r) => r.id)).toEqual(["work", "biz", "biz-report"]);
});
});