import { test, describe } from "node:test"; import assert from "node:assert/strict"; import { stripHtml, invertColor, getSomedaySlotCount, DEFAULT_SOMEDAY_SLOT_COUNT, } from "../../src/lib/weekly/format.ts"; import { isAllDayEvent } from "../../src/lib/weekly/date-utils.ts"; import { clampViewDays, MAX_VIEW_DAYS } from "../../src/lib/weekly/device-settings.ts"; import type { Task, CalendarEvent } from "../../src/lib/weekly/types.ts"; /** * Unit-Tests der Darstellungs-Helfer und der Spaltenbegrenzung. * Läuft ohne Browser und ohne Datenbank: `npm run test:unit`. */ // Minimale Aufgabe — nur die Felder, die die getestete Funktion liest. const task = (somedaySlotIndex: number | null): Task => ({ id: "t", title: "t", completed: false, updatedAt: new Date(), order: 0, userId: "u", somedaySlotIndex, }); describe("stripHtml", () => { test("entfernt Tags, behält den Text", () => { assert.equal(stripHtml("

Hallo Welt

"), "Hallo Welt"); }); test("schneidet umgebende Leerzeichen ab", () => { assert.equal(stripHtml("

Text

"), "Text"); }); test("lässt reinen Text unverändert", () => { assert.equal(stripHtml("Einkaufen gehen"), "Einkaufen gehen"); }); test("kommt mit leerer Eingabe zurecht", () => { assert.equal(stripHtml(""), ""); }); }); describe("invertColor", () => { test("invertiert Weiß zu Schwarz", () => { assert.equal(invertColor("#ffffff"), "#000000"); }); test("invertiert Schwarz zu Weiß", () => { assert.equal(invertColor("#000000"), "#ffffff"); }); test("Kurzform wird ausgeschrieben", () => { assert.equal(invertColor("#fff"), "#000000"); }); test("Rautezeichen ist optional", () => { assert.equal(invertColor("ffffff"), "#000000"); }); test("zweimal invertieren ergibt die Ausgangsfarbe", () => { assert.equal(invertColor(invertColor("#3b82f6")), "#3b82f6"); }); test("ungültige Eingaben werden unverändert zurückgegeben", () => { assert.equal(invertColor("keine-farbe"), "keine-farbe"); assert.equal(invertColor(""), ""); }); }); describe("getSomedaySlotCount", () => { test("leere Liste ergibt die Grundanzahl", () => { assert.equal(getSomedaySlotCount([]), DEFAULT_SOMEDAY_SLOT_COUNT); }); test("hält unter der Grundanzahl immer die Grundanzahl", () => { assert.equal(getSomedaySlotCount([task(0), task(1)]), DEFAULT_SOMEDAY_SLOT_COUNT); }); test("wächst mit, sobald der letzte Platz belegt ist", () => { // Anspruch laut Kommentar im Code: unten bleibt immer ein freier Platz. assert.equal(getSomedaySlotCount([task(5)]), 7); }); test("Aufgaben ohne Platznummer verändern nichts", () => { assert.equal(getSomedaySlotCount([task(null), task(null)]), DEFAULT_SOMEDAY_SLOT_COUNT); }); }); describe("isAllDayEvent", () => { // Diese Funktion rief parseCalendarDate auf, ohne es zu importieren — beim Auslagern // aus WeeklyView.tsx übersehen. Der Build meldete nichts, weil ignoreBuildErrors // aktiv war; zur Laufzeit hätte es einen ReferenceError gegeben. Dieser Test hätte // den Fehler sofort gefunden. const ev = (startTime: string, endTime: string): CalendarEvent => ({ id: "e", title: "e", startTime, endTime, source: "google" }); test("reines Datum ohne Uhrzeit gilt als ganztägig", () => { assert.equal(isAllDayEvent(ev("2026-09-07", "2026-09-08")), true); }); test("Termin mit Uhrzeit über eine Stunde ist nicht ganztägig", () => { assert.equal(isAllDayEvent(ev("2026-09-07T10:00:00", "2026-09-07T11:00:00")), false); }); test("Mitternacht bis Mitternacht gilt als ganztägig", () => { assert.equal(isAllDayEvent(ev("2026-09-07T00:00:00", "2026-09-08T00:00:00")), true); }); test("ohne Startzeit nicht ganztägig", () => { assert.equal(isAllDayEvent(ev("", "")), false); }); }); describe("clampViewDays", () => { test("gültige Werte bleiben unverändert", () => { for (const n of [1, 7, 14, 21, 31]) assert.equal(clampViewDays(n), n); }); test("begrenzt nach oben", () => { assert.equal(clampViewDays(999), MAX_VIEW_DAYS); }); test("begrenzt nach unten", () => { assert.equal(clampViewDays(0), 1); assert.equal(clampViewDays(-5), 1); }); test("rundet Kommazahlen", () => { assert.equal(clampViewDays(7.4), 7); assert.equal(clampViewDays(7.6), 8); }); test("fällt bei Unsinn auf 7 zurück", () => { assert.equal(clampViewDays(NaN), 7); assert.equal(clampViewDays(Infinity), 7); }); });