fix(detail): validate route-param UUID and align e2e storageState

Detailseiten & Kontakt (WS8) – zwei BLOCKING-Befunde behoben:

- UUID-Validierung an der Grenze (Querschnittsstandard 4): Die drei
  Detailseiten (fahrzeuge/geraete/wehren [id]) gaben den Route-Param `id`
  ungeprüft an die DB (Postgres `uuid`). Ein malformter Pfad wie
  /fahrzeuge/abc erzeugte `invalid input syntax for type uuid` -> 500.
  Jetzt: uuidSchema.safeParse(id) -> notFound() (deutsche 404) vor dem
  Query-Aufruf.

- e2e-Harness: detail-auth.spec.ts nutzte storageState
  "tests/e2e/.auth/wehr-read.json" (existiert nicht, ENOENT -> ganzer
  'Eingeloggt'-Block errort). Auf Projektkonvention umgestellt:
  storageState: process.env.E2E_WEHR_READ_STATE ?? { cookies, origins }
  + test.skip ohne Fixture (analog verwaltung-scoping.spec.ts).
  Zusätzlich nicht-UUID-Fall (/fahrzeuge/abc -> deutsche 404) abgesichert.

Verifiziert (offline): tsc --noEmit OK, vitest detail-Unit-Tests OK,
next build "Compiled successfully" + Typecheck OK. Build-Page-Data-Phase
und e2e deferred (kein Postgres/Server in der Sandbox).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthias Hochmeister
2026-06-09 11:50:01 +02:00
parent 44050c7278
commit 6975679c4e
4 changed files with 35 additions and 4 deletions

View File

@@ -42,7 +42,13 @@ test.describe("Default-deny: Detailseiten (anonym)", () => {
});
test.describe("Eingeloggt: Detail-Inhalte", () => {
test.use({ storageState: "tests/e2e/.auth/wehr-read.json" });
test.skip(
!process.env.E2E_WEHR_READ_STATE,
"benötigt wehr_read-Fixture (Test-Workstream)",
);
test.use({
storageState: process.env.E2E_WEHR_READ_STATE ?? { cookies: [], origins: [] },
});
test("Fahrzeug-Detail zeigt Eckdaten, Beladung-Links und Wehr-Kontakt", async ({
page,
@@ -80,4 +86,14 @@ test.describe("Eingeloggt: Detail-Inhalte", () => {
await page.goto(`/fahrzeuge/${UNGUELTIGE_ID}`);
await expect(page.getByText("Nicht gefunden.")).toBeVisible();
});
test("malformter (nicht-UUID) Fahrzeug-Pfad -> deutsche 404-Seite (kein 500)", async ({
page,
}) => {
// Route-Param ist Nutzereingabe an der Grenze: eine nicht-UUID darf nicht
// als `invalid input syntax for type uuid` bis zur error.tsx (500) laufen,
// sondern muss sauber `notFound()` (deutsche 404) liefern.
await page.goto(`/fahrzeuge/abc`);
await expect(page.getByText("Nicht gefunden.")).toBeVisible();
});
});