A note with a follow-up date is a task, and the overview is where tasks are looked for. Until now it lived only in the employee file, which is the one place you go when you already know who you are looking for. Follow-ups behave differently from everything else on that card, and the difference is the point: an entry on Monday is over on Tuesday, an unfinished task is not. So there is no lower bound on the date — what was due and never ticked off stays, marked overdue in red, sorted to the top because it is sorted by date. A task that drops out of the list by itself is a forgotten task. Only "Erledigt" removes it. A note without a follow-up date never appears: it is a record, not a task. Checked against the live database — an overdue one and an upcoming one appear, one without a date and one beyond the chosen period do not, and ticking the overdue one off removes exactly it. The probe notes were deleted again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
ANSTEHEND_ARTEN,
|
|
STANDARD_ZEITRAUM,
|
|
istEingeschraenkt,
|
|
parseArten,
|
|
parseZeitraum,
|
|
} from "@/lib/dashboard-filter";
|
|
|
|
// Die Auswahl steht in der Adresse, und dort kann alles stehen: eine
|
|
// veraltete Verknüpfung, ein Tippfehler, ein abgeschnittener Wert. Sie darf
|
|
// die Übersicht weder leeren noch mit einem Zeitraum laden, den niemand
|
|
// gewählt hat.
|
|
|
|
describe("parseZeitraum", () => {
|
|
it("nimmt die angebotenen Zeiträume", () => {
|
|
expect(parseZeitraum("30")).toBe(30);
|
|
expect(parseZeitraum("180")).toBe(180);
|
|
});
|
|
|
|
it("fällt ohne Angabe auf den Standard zurück", () => {
|
|
expect(parseZeitraum(undefined)).toBe(STANDARD_ZEITRAUM);
|
|
expect(parseZeitraum("")).toBe(STANDARD_ZEITRAUM);
|
|
});
|
|
|
|
it("lässt sich keinen beliebigen Zeitraum unterschieben", () => {
|
|
// Sonst liesse sich über die Adresse ein Lesevorgang über Jahre auslösen.
|
|
expect(parseZeitraum("3650")).toBe(STANDARD_ZEITRAUM);
|
|
expect(parseZeitraum("-5")).toBe(STANDARD_ZEITRAUM);
|
|
expect(parseZeitraum("60; drop")).toBe(STANDARD_ZEITRAUM);
|
|
});
|
|
});
|
|
|
|
describe("parseArten", () => {
|
|
const alle = ANSTEHEND_ARTEN.map((a) => a.value);
|
|
|
|
it("versteht eine Auswahl", () => {
|
|
expect(parseArten("hire,exit")).toEqual(["hire", "exit"]);
|
|
});
|
|
|
|
it("liest ohne Angabe alle — eine leere Karte wäre die falsche Antwort", () => {
|
|
expect(parseArten(undefined)).toEqual(alle);
|
|
expect(parseArten("")).toEqual(alle);
|
|
});
|
|
|
|
it("verwirft Unbekanntes und behält den Rest", () => {
|
|
expect(parseArten("hire,unfug")).toEqual(["hire"]);
|
|
});
|
|
|
|
it("führt eine Auswahl aus lauter Unbekanntem auf alle zurück", () => {
|
|
expect(parseArten("unfug,quatsch")).toEqual(alle);
|
|
});
|
|
|
|
it("stört sich nicht an Leerzeichen", () => {
|
|
expect(parseArten(" hire , return ")).toEqual(["hire", "return"]);
|
|
});
|
|
});
|
|
|
|
describe("Wiedervorlagen als eigene Art", () => {
|
|
it("steht in der Auswahl", () => {
|
|
expect(ANSTEHEND_ARTEN.map((a) => a.value)).toContain("note");
|
|
});
|
|
|
|
it("ist ohne Angabe mit dabei", () => {
|
|
// Eine offene Aufgabe mit Termin ist der Grund, warum jemand die Übersicht
|
|
// aufschlägt — sie darf nicht erst nach einem Klick sichtbar werden.
|
|
expect(parseArten(undefined)).toContain("note");
|
|
});
|
|
|
|
it("lässt sich allein auswählen", () => {
|
|
expect(parseArten("note")).toEqual(["note"]);
|
|
});
|
|
});
|
|
|
|
describe("istEingeschraenkt", () => {
|
|
const alle = ANSTEHEND_ARTEN.map((a) => a.value);
|
|
|
|
it("erkennt den unveränderten Zustand", () => {
|
|
expect(istEingeschraenkt(STANDARD_ZEITRAUM, alle)).toBe(false);
|
|
});
|
|
|
|
it("erkennt einen anderen Zeitraum", () => {
|
|
expect(istEingeschraenkt(90, alle)).toBe(true);
|
|
});
|
|
|
|
it("erkennt eine engere Auswahl", () => {
|
|
expect(istEingeschraenkt(STANDARD_ZEITRAUM, ["hire"])).toBe(true);
|
|
});
|
|
});
|