import { test, expect } from "@playwright/test"; /** * Detailseiten-Auth & -Inhalt (Workstream 8, Phase 5). * * NICHT in der Sandbox ausführbar (kein Server/DB) — deferred. Wird über * `npm run test:e2e` gegen einen laufenden Server mit Seed-Daten ausgeführt. * * Garantien: * - Default-deny (Querschnittsstandard 1): anonyme Aufrufe der Detailseiten * leiten auf /login um (das `(app)`-Layout-Gate + `requireSession()` je Seite). * - Eingeloggt: Eckdaten, Beladung-Links (`/geraete/`), Wehr-Kontakt * (`tel:`/`mailto:`) sind sichtbar. * - Ungültige IDs -> deutsche 404-Seite (not-found). * * Negativ-Probe (manuell/CI): Entfernen von `requireSession()` aus einer der * Detailseiten ODER aus `(app)/layout.tsx` muss die Default-deny-Tests rot * machen. * * Platzhalter-IDs: zur Laufzeit gegen echte Seed-UUIDs ersetzen * (Env `E2E_FAHRZEUG_ID` etc.) oder per Suchseite ermitteln. */ const FAHRZEUG_ID = process.env.E2E_FAHRZEUG_ID ?? "00000000-0000-0000-0000-000000000001"; const GERAET_ID = process.env.E2E_GERAET_ID ?? "00000000-0000-0000-0000-000000000002"; const WEHR_ID = process.env.E2E_WEHR_ID ?? "00000000-0000-0000-0000-000000000003"; const UNGUELTIGE_ID = "ffffffff-ffff-ffff-ffff-ffffffffffff"; const DETAIL_PAGES = [ `/fahrzeuge/${FAHRZEUG_ID}`, `/geraete/${GERAET_ID}`, `/wehren/${WEHR_ID}`, ]; test.describe("Default-deny: Detailseiten (anonym)", () => { for (const path of DETAIL_PAGES) { test(`anonymer Aufruf von ${path} leitet auf /login um`, async ({ page }) => { await page.goto(path); await expect(page).toHaveURL(/\/login/); }); } }); test.describe("Eingeloggt: Detail-Inhalte", () => { test.use({ storageState: "tests/e2e/.auth/wehr-read.json" }); test("Fahrzeug-Detail zeigt Eckdaten, Beladung-Links und Wehr-Kontakt", async ({ page, }) => { await page.goto(`/fahrzeuge/${FAHRZEUG_ID}`); await expect(page.getByRole("heading", { name: "Eckdaten" })).toBeVisible(); // Beladung verlinkt auf Gerät-Detailseiten. const beladungLink = page.locator('a[href^="/geraete/"]').first(); await expect(beladungLink).toBeVisible(); // Out-of-band Kontakt: tel:/mailto:-Link vorhanden. const kontaktLink = page.locator('a[href^="tel:"], a[href^="mailto:"]').first(); await expect(kontaktLink).toBeVisible(); }); test("Gerät-Detail verlinkt Fahrzeug oder zeigt „im Gerätehaus“", async ({ page, }) => { await page.goto(`/geraete/${GERAET_ID}`); const hatFahrzeug = await page.locator('a[href^="/fahrzeuge/"]').count(); if (hatFahrzeug === 0) { await expect(page.getByText("im Gerätehaus")).toBeVisible(); } else { await expect(page.locator('a[href^="/fahrzeuge/"]').first()).toBeVisible(); } }); test("Wehr-Detail listet Fuhrpark und Kontakt", async ({ page }) => { await page.goto(`/wehren/${WEHR_ID}`); await expect(page.getByRole("heading", { name: "Fahrzeuge" })).toBeVisible(); const kontaktLink = page.locator('a[href^="tel:"], a[href^="mailto:"]').first(); await expect(kontaktLink).toBeVisible(); }); test("ungültige Fahrzeug-ID -> deutsche 404-Seite", async ({ page }) => { await page.goto(`/fahrzeuge/${UNGUELTIGE_ID}`); await expect(page.getByText("Nicht gefunden.")).toBeVisible(); }); });