// Akzeptanztest des VDA-ISA-Export-Moduls (Story B7-2, C9 §3). Reine Logik. // Lauf: npx tsx scripts/test-vda-isa.ts (Exit 1 bei Fehler). import { pruefzielOfControl, sortForExport, toCatalogCsv, kennzahlen, type ExportControl } from "../src/lib/export/vda-isa"; let failures = 0; const ok = (c: boolean, m: string) => { console.log(`${c ? "✓" : "✗ FEHLER"} ${m}`); if (!c) failures++; }; const mk = (control: string, reifegrad: number | null, bestaetigt: boolean): ExportControl => ({ control, frage: `Frage ${control}`, reifegrad, bestaetigt, umsetzung: "u", belege: "b", offenePunkte: 0, pruefziel: pruefzielOfControl(control), }); // — Prüfziel-Zuordnung — ok(pruefzielOfControl("4.1.2") === "informationssicherheit", "4.1.2 → Informationssicherheit"); ok(pruefzielOfControl("8.1.1") === "prototypenschutz", "8.1.1 → Prototypenschutz"); ok(pruefzielOfControl("9.2.1") === "datenschutz", "9.2.1 → Datenschutz"); // — Sortierung IS → Proto → DS — { const sorted = sortForExport([mk("9.1.1", 2, true), mk("8.1.1", 1, true), mk("1.1.1", 3, true), mk("2.1.1", 2, true)]); ok(sorted.map((r) => r.control).join(",") === "1.1.1,2.1.1,8.1.1,9.1.1", "Reihenfolge IS→Proto→DS, dann numerisch"); } // — CSV: BOM, Header, Status-Markierung, Semikolon — { const csv = toCatalogCsv([mk("1.1.1", 3, true), mk("1.1.2", null, false)]); ok(csv.charCodeAt(0) === 0xfeff, "CSV beginnt mit UTF-8-BOM"); ok(csv.includes("Control-ID;Kontrollfrage/Ziel;Reifegrad;Status"), "Header vorhanden"); ok(/1\.1\.1;[^;]*;3;bestätigt/.test(csv), "bestätigtes Control mit Reifegrad 3"); ok(/1\.1\.2;[^;]*;na;unbestätigt/.test(csv), "unbestätigt → na + Markierung"); } // — Kennzahlen: „unbestätigt zählt als 0" — { const k = kennzahlen([mk("1.1.1", 3, true), mk("1.1.2", 3, false), mk("8.1.1", 2, true)]); ok(k.total === 3 && k.bestaetigt === 2, "total 3, bestätigt 2"); ok(Math.abs(k.gesamtAvg! - (3 + 0 + 2) / 3) < 1e-9, "Ø gesamt = (3+0+2)/3 (unbestätigt=0)"); const is = k.jePruefziel.find((p) => p.pruefziel === "informationssicherheit")!; ok(is.controls === 2 && is.bestaetigt === 1 && Math.abs(is.avg! - 1.5) < 1e-9, "IS: 2 Controls, 1 bestätigt, Ø 1,5"); ok(k.jePruefziel.some((p) => p.pruefziel === "prototypenschutz"), "Prototyp-Prüfziel vorhanden"); } console.log(failures === 0 ? "\nOK — alle VDA-ISA-Export-Tests grün" : `\nPRUEFEN — ${failures} Fehler`); process.exit(failures === 0 ? 0 : 1);