import { test, describe } from "node:test"; import assert from "node:assert/strict"; import { getOverdueTasks, groupOverdueByDate } from "../../src/lib/weekly/overdue.ts"; import type { Task } from "../../src/lib/weekly/types.ts"; /** * Erkennung und Gruppierung überfälliger Aufgaben. Beobachtbares Verhalten: eine * unerledigte Aufgabe mit einem Datum vor heute gilt als überfällig, unabhängig vom * Rolling-Status (siehe OverdueTasksManager.tsx für den fachlichen Hintergrund) -- * Someday-Aufgaben und heute fällige Aufgaben zählen bewusst nicht mit. */ const baseTask: Task = { id: "t1", title: "Test task", completed: false, order: 0, updatedAt: new Date(), userId: "u1", }; const now = new Date(2026, 8, 14, 10, 0, 0); // Montag, 14.09.2026, 10 Uhr describe("getOverdueTasks", () => { test("unerledigte Aufgabe mit vergangenem Datum ist überfällig", () => { const task = { ...baseTask, scheduledDate: "2026-09-10" }; assert.deepEqual(getOverdueTasks([task], now), [task]); }); test("erledigte Aufgabe mit vergangenem Datum ist nicht überfällig", () => { const task = { ...baseTask, scheduledDate: "2026-09-10", completed: true }; assert.deepEqual(getOverdueTasks([task], now), []); }); test("heute fällige Aufgabe ist nicht überfällig, auch nachmittags nicht", () => { const task = { ...baseTask, scheduledDate: "2026-09-14" }; assert.deepEqual(getOverdueTasks([task], now), []); }); test("zukünftige Aufgabe ist nicht überfällig", () => { const task = { ...baseTask, scheduledDate: "2026-09-20" }; assert.deepEqual(getOverdueTasks([task], now), []); }); test("Aufgabe ohne Datum ist nicht überfällig", () => { const task = { ...baseTask, scheduledDate: null }; assert.deepEqual(getOverdueTasks([task], now), []); }); test("Someday-Aufgabe zählt nicht mit, selbst mit vergangenem Datum", () => { const task = { ...baseTask, scheduledDate: "2026-09-10", somedayListId: "list1" }; assert.deepEqual(getOverdueTasks([task], now), []); }); test("virtuelle wiederkehrende Instanz mit vergangenem Datum zählt mit", () => { // Der Server materialisiert virtuelle Ids bei jedem PATCH (siehe // VIRTUAL_ID_REGEX in api/tasks/route.ts) -- toggleTask/moveTaskToSlot // funktionieren darauf bereits unverändert. const task = { ...baseTask, id: "virtual-t1-2026-09-10", scheduledDate: "2026-09-10" }; assert.deepEqual(getOverdueTasks([task], now), [task]); }); test("mehrere Aufgaben werden korrekt gefiltert", () => { const overdueTask = { ...baseTask, id: "a", scheduledDate: "2026-09-10" }; const futureTask = { ...baseTask, id: "b", scheduledDate: "2026-09-20" }; const doneTask = { ...baseTask, id: "c", scheduledDate: "2026-09-01", completed: true }; assert.deepEqual(getOverdueTasks([overdueTask, futureTask, doneTask], now), [overdueTask]); }); }); describe("groupOverdueByDate", () => { test("gruppiert nach Datum, älteste Gruppe zuerst", () => { const a = { ...baseTask, id: "a", scheduledDate: "2026-09-12" }; const b = { ...baseTask, id: "b", scheduledDate: "2026-09-10" }; const c = { ...baseTask, id: "c", scheduledDate: "2026-09-12" }; const groups = groupOverdueByDate([a, b, c]); assert.deepEqual( groups.map((g) => g.dateStr), ["2026-09-10", "2026-09-12"], ); assert.deepEqual(groups[0].tasks, [b]); assert.deepEqual(groups[1].tasks, [a, c]); }); test("leere Liste ergibt keine Gruppen", () => { assert.deepEqual(groupOverdueByDate([]), []); }); });