import { describe, expect, it } from "vitest"; import { ONBOARDING_GRUPPEN, ONBOARDING_PUNKTE, fortschritt, istErledigt, punktZu, wertIstGueltig, type AufgabenStand, } from "@/lib/onboarding"; // Die Checkliste kommt von einem Blatt Papier. Was dort ein Kästchen war, ist // hier nicht überall eines: „Prämienanspruch" hatte zwei Kästchen (ja | nein), // und die Grössen waren Felder zum Hineinschreiben. Die Feldart trägt also // eine fachliche Aussage — deshalb wird sie hier festgehalten. function stand(teil: Partial & { item_key: string }): AufgabenStand { return { erledigt: false, wert: null, kommentar: null, updated_at: null, updated_by_name: null, ...teil }; } describe("Das Verzeichnis", () => { it("hat eindeutige Schlüssel — sie stehen in den Daten", () => { const keys = ONBOARDING_PUNKTE.map((p) => p.key); expect(new Set(keys).size).toBe(keys.length); }); it("bildet jeden Punkt aus dem Blatt ab", () => { // 25 vom Blatt, dazu „Firmenfahrzeug" aus dem Workshop. expect(ONBOARDING_PUNKTE).toHaveLength(26); for (const key of ["dienstzettel", "meldezettel", "salmonellenbefund", "willkommensmappe", "webreise", "firmenfahrzeug"]) { expect(punktZu(key), key).toBeDefined(); } }); it("führt Prämienanspruch als Ja/Nein, nicht als Haken", () => { // Zwei Kästchen im Blatt, und das ist kein Zufall: „nein" ist ein // erhobener Befund, „noch nicht gefragt" nicht. expect(punktZu("praemienanspruch")?.art).toBe("janein"); }); it("führt die Grössen als Text", () => { // Abgehakt wäre eine Schuhgrösse wertlos. for (const key of ["groesse_schuhe", "groesse_tshirt", "groesse_hose"]) { expect(punktZu(key)?.art, key).toBe("text"); } }); it("gruppiert vollständig — kein Punkt fällt zwischen die Gruppen", () => { const ausGruppen = ONBOARDING_GRUPPEN.flatMap((g) => g.punkte.map((p) => p.key)); expect(new Set(ausGruppen)).toEqual(new Set(ONBOARDING_PUNKTE.map((p) => p.key))); }); }); describe("istErledigt", () => { const haken = punktZu("meldezettel")!; const janein = punktZu("praemienanspruch")!; const text = punktZu("groesse_schuhe")!; it("zählt einen gesetzten Haken", () => { expect(istErledigt(haken, stand({ item_key: haken.key, erledigt: true }))).toBe(true); expect(istErledigt(haken, stand({ item_key: haken.key }))).toBe(false); }); it("zählt bei Ja/Nein auch ein Nein als erledigt", () => { // Die Aufgabe war, die Frage zu beantworten — nicht, sie zu bejahen. expect(istErledigt(janein, stand({ item_key: janein.key, wert: "nein" }))).toBe(true); expect(istErledigt(janein, stand({ item_key: janein.key, wert: "ja" }))).toBe(true); expect(istErledigt(janein, stand({ item_key: janein.key }))).toBe(false); }); it("zählt bei Text die Angabe selbst, nicht den Haken", () => { expect(istErledigt(text, stand({ item_key: text.key, wert: "43" }))).toBe(true); expect(istErledigt(text, stand({ item_key: text.key, wert: " " }))).toBe(false); // Ein Haken ohne Angabe wäre eine leere Behauptung. expect(istErledigt(text, stand({ item_key: text.key, erledigt: true }))).toBe(false); }); it("hält eine fehlende Zeile für offen", () => { expect(istErledigt(haken, undefined)).toBe(false); }); }); describe("fortschritt", () => { it("ist auf einer leeren Liste vollständig offen", () => { const f = fortschritt([]); expect(f.erledigt).toBe(0); expect(f.gesamt).toBe(ONBOARDING_PUNKTE.length); expect(f.offen).toHaveLength(ONBOARDING_PUNKTE.length); }); it("nennt die offenen Punkte beim Namen, nicht beim Schlüssel", () => { // Die Zahl allein sagt nicht, worauf noch gewartet wird. expect(fortschritt([]).offen).toContain("Meldezettel"); expect(fortschritt([]).offen).not.toContain("meldezettel"); }); it("zählt gemischte Arten zusammen", () => { const f = fortschritt([ stand({ item_key: "meldezettel", erledigt: true }), stand({ item_key: "praemienanspruch", wert: "nein" }), stand({ item_key: "groesse_schuhe", wert: "43" }), ]); expect(f.erledigt).toBe(3); expect(f.offen).not.toContain("Meldezettel"); }); it("stört sich nicht an Zeilen zu Punkten, die es nicht mehr gibt", () => { // Ein gestrichener Punkt lässt seine Antworten stehen — sie sollen die // Zählung weder erhöhen noch zum Absturz führen. const f = fortschritt([stand({ item_key: "gibt_es_nicht_mehr", erledigt: true })]); expect(f.erledigt).toBe(0); expect(f.gesamt).toBe(ONBOARDING_PUNKTE.length); }); }); describe("wertIstGueltig", () => { it("lässt bei Ja/Nein nur ja, nein oder nichts zu", () => { const janein = punktZu("praemienanspruch")!; expect(wertIstGueltig(janein, "ja")).toBe(true); expect(wertIstGueltig(janein, "nein")).toBe(true); expect(wertIstGueltig(janein, null)).toBe(true); expect(wertIstGueltig(janein, "vielleicht")).toBe(false); }); it("lässt bei einem Haken keinen Wert zu", () => { expect(wertIstGueltig(punktZu("meldezettel")!, "irgendwas")).toBe(false); }); it("lässt bei Text alles zu — eine Grösse ist keine Auswahlliste", () => { expect(wertIstGueltig(punktZu("groesse_hose")!, "W32/L34")).toBe(true); }); });