import { readFileSync, readdirSync, statSync } from "node:fs"; import path from "node:path"; import { describe, expect, it } from "vitest"; /** * Struktureller Test (#004, Muster aus Laufzettel): jede Seite und jeder Route Handler * prueft selbst, wer zugreift. Die Ausnahmen stehen hier namentlich mit Begruendung – ein * neuer ungepruefter Handler soll jemanden zwingen, sie aufzuschreiben. */ const AUSNAHMEN: Record = { "src/app/anmelden/page.tsx": "Anmeldeseite selbst", "src/app/anmelden/totp/page.tsx": "nur mit Einrichtungs-Cookie aus richtigem Passwort erreichbar", "src/app/anmelden/passwort/page.tsx": "nur mit Cookie aus richtigem Einmal-Passwort erreichbar (#035)", "src/app/api/auth/abmelden/route.ts": "Abmelden braucht keine Pruefung", "src/app/api/auth/oidc/start/route.ts": "Beginn der Anmeldung", "src/app/api/auth/oidc/rueckruf/route.ts": "Ende der Anmeldung; prueft state, nonce und PKCE", "src/app/api/gesundheit/route.ts": "Healthcheck, verraet nur die Version", }; const PRUEFUNGEN = /sitzungErforderlich\(|rechtErforderlich\(|totpEinrichtungLesen\(/; function dateien(verzeichnis: string): string[] { return readdirSync(verzeichnis).flatMap((name) => { const pfad = path.join(verzeichnis, name); if (statSync(pfad).isDirectory()) return dateien(pfad); return /^(page\.tsx|route\.ts)$/.test(name) ? [pfad] : []; }); } describe("Zugangspruefung", () => { const alle = dateien("src/app").map((p) => p.split(path.sep).join("/")); it("findet Seiten und Handler", () => { expect(alle.length).toBeGreaterThan(10); }); it.each(alle)("%s prueft selbst oder steht in den Ausnahmen", (datei) => { if (AUSNAHMEN[datei]) return; const inhalt = readFileSync(datei, "utf8"); expect(PRUEFUNGEN.test(inhalt), `${datei} prueft keine Sitzung`).toBe(true); }); it("listet keine Ausnahme fuer eine Datei, die es nicht mehr gibt", () => { for (const datei of Object.keys(AUSNAHMEN)) expect(alle).toContain(datei); }); });