Kuma/tests/courses/course-days.test.ts
2026-10-01 23:28:32 +02:00

107 lines
4.1 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
addDaysToKey,
berlinDayEnd,
berlinDayStart,
dayKey,
formatDayHeading,
keyToLocalDate,
localDateToKey,
} from "@/src/modules/courses/lib/course-days";
describe("dayKey", () => {
it("ordnet einen Kurs aus dem Datumsfeld seinem Tag zu", () => {
// "2026-10-15" aus dem Formular landet als UTC-Mitternacht in der DB.
expect(dayKey("2026-10-15T00:00:00.000Z")).toBe("2026-10-15");
expect(dayKey("2026-12-01T01:00:00.000Z")).toBe("2026-12-01");
});
it("ordnet einen auf Berliner Mitternacht datierten Kurs dem richtigen Tag zu", () => {
// In UTC wäre es noch der 1. Oktober.
expect(dayKey("2026-10-01T22:00:00.000Z")).toBe("2026-10-02");
// Winterzeit: Mitternacht Berlin = 23:00 UTC am Vortag.
expect(dayKey("2026-12-01T23:00:00.000Z")).toBe("2026-12-02");
});
});
describe("addDaysToKey", () => {
it("überspringt die Zeitumstellung ohne Tag doppelt oder gar nicht zu zählen", () => {
// 25. Oktober 2026: Umstellung auf Winterzeit, der Tag hat 25 Stunden.
expect(addDaysToKey("2026-10-24", 1)).toBe("2026-10-25");
expect(addDaysToKey("2026-10-25", 1)).toBe("2026-10-26");
expect(addDaysToKey("2026-03-28", 2)).toBe("2026-03-30");
});
});
describe("berlinDayStart / berlinDayEnd", () => {
it("liefert Mitternacht Berliner Zeit, im Sommer wie im Winter", () => {
expect(berlinDayStart("2026-10-15").toISOString()).toBe("2026-10-14T22:00:00.000Z");
expect(berlinDayStart("2026-12-01").toISOString()).toBe("2026-11-30T23:00:00.000Z");
expect(berlinDayEnd("2026-10-15").toISOString()).toBe("2026-10-15T21:59:59.999Z");
});
it("stimmt auch an den Tagen der Zeitumstellung", () => {
// Umstellung jeweils um 01:00 UTC - die Mitternacht davor gilt noch die alte Zeit.
expect(berlinDayStart("2026-10-25").toISOString()).toBe("2026-10-24T22:00:00.000Z");
expect(berlinDayEnd("2026-10-25").toISOString()).toBe("2026-10-25T22:59:59.999Z");
expect(berlinDayStart("2026-03-29").toISOString()).toBe("2026-03-28T23:00:00.000Z");
expect(berlinDayEnd("2026-03-29").toISOString()).toBe("2026-03-29T21:59:59.999Z");
});
it("schließt einen Kurs am letzten Tag des Fensters ein", () => {
// Der gemeldete Fall: heute 1.10., Fenster bis einschließlich 15.10. - der
// Kurs liegt als 2026-10-15T00:00Z in der DB und fiel bisher heraus.
const course = new Date("2026-10-15T00:00:00.000Z");
const windowTo = berlinDayEnd(addDaysToKey("2026-10-01", 14));
expect(course <= windowTo).toBe(true);
// "Mehr laden" beginnt direkt danach, ohne Lücke.
expect(new Date(windowTo.getTime() + 1)).toEqual(berlinDayStart("2026-10-16"));
});
});
describe("formatDayHeading", () => {
it("benennt heute und morgen", () => {
expect(formatDayHeading("2026-10-01", "2026-10-01")).toMatch(/^Heute · Donnerstag/);
expect(formatDayHeading("2026-10-02", "2026-10-01")).toMatch(/^Morgen · Freitag/);
expect(formatDayHeading("2026-10-30", "2026-10-01")).toBe("Freitag, 30. Oktober");
});
});
describe("Kalender-Umrechnung", () => {
it("führt einen Tag verlustfrei hin und zurück", () => {
expect(localDateToKey(keyToLocalDate("2026-10-30"))).toBe("2026-10-30");
});
});
import {
durationMinutes,
startOfWeekKey,
weekDayKeys,
} from "@/src/modules/courses/lib/course-days";
describe("Wochen", () => {
it("beginnt montags - auch wenn heute Sonntag ist", () => {
expect(startOfWeekKey("2026-10-01")).toBe("2026-09-28"); // Donnerstag
expect(startOfWeekKey("2026-10-04")).toBe("2026-09-28"); // Sonntag
expect(startOfWeekKey("2026-10-05")).toBe("2026-10-05"); // Montag
});
it("liefert sieben Tage über die Zeitumstellung hinweg", () => {
expect(weekDayKeys("2026-10-19")).toEqual([
"2026-10-19",
"2026-10-20",
"2026-10-21",
"2026-10-22",
"2026-10-23",
"2026-10-24",
"2026-10-25",
]);
});
});
describe("durationMinutes", () => {
it("berechnet die Dauer und verwirft Unsinn", () => {
expect(durationMinutes("07:30", "08:45")).toBe(75);
expect(durationMinutes("08:00", "07:00")).toBeNull();
});
});