Files
Florian-netz/tests/e2e/admin-brigade-provision.spec.ts
Matthias Hochmeister e97e16d254 Workstream 6: Admin-Panel — Taxonomie & Bereitstellung (Phase 4)
Platform-Admin-only Oberflächen und Domänenlogik:

- codes.ts erweitert um allradCode/normalizeCode/codesMatch (Allrad-Infix
  kanonisch; Suche importiert weiterhin expandNameQuery). Pure-Unit-Tests.
- slug.ts (Idempotenz-Key-Erzeugung) + Tests.
- audit.ts: writeAudit mit EINER Signatur und optionalem typisierten tx.
- provisioning.ts: createBrigadeWithFirstAdmin (Geocoding inline, argon2id,
  Audit brigade.create/user.create) + resetUserPassword (Audit user.reset).
- Zod-Validierung: merkmal/template/equipment-category/brigade (+ Tests).
- Server Actions (jede mit Guard als erster Anweisung, default-deny):
  merkmale (CRUD, Delete blockiert bei Referenz), proposals (promote/merge mit
  Typ-Kompatibilität), templates (Merkmale/Vorgabewerte/Aliasse), equipment-
  categories, brigades (Bereitstellung/Reset). Audit in allen Schreib-Actions.
- (admin)-Route-Group: Layout mit requirePlatformAdmin als erster Zeile,
  AdminNav, DataTable, loading/error; Seiten für Merkmale (+Editor), Vorschläge
  (Merge), Vorlagen (+Detail mit Merkmal-/Alias-Editor und Allrad-Hinweis),
  Geräte-Kategorien (+Detail), Wehren (Liste/neu/Detail mit Passwort-Reset),
  paginierter Audit-Viewer mit Filter. Jede Seite ruft zusätzlich den Guard.
- i18n: admin-Strings in zentraler de.ts.
- Playwright-Specs (deferred, nicht ausgeführt): admin-gating,
  admin-merkmal-proposal, admin-brigade-provision.

Schema NICHT neu definiert — nur importiert. codes.ts ist hier Eigentümer.

Offline-Verifikation: tsc --noEmit grün; eslint grün; vitest run grün
(119 passed, 7 DB-roundtrip skipped); next build Exit 0; drizzle-kit check ok.
DB-/Server-/Browser-abhängige Schritte deferred (kein Postgres/Server im
Sandbox).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:30:52 +02:00

44 lines
1.5 KiB
TypeScript

import { test, expect } from "@playwright/test";
/**
* Admin-Bereitstellung: Wehr anlegen (Workstream 6).
*
* NICHT in der Sandbox ausführbar (kein Server/DB) — deferred. Erwartet einen
* platform_admin-storageState (Test-Workstream-Fixture) sowie ein erreichbares
* Nominatim für die Geokodierung (sonst „nicht geokodiert"-Hinweis).
*
* Verifiziert (Plan WS6, Punkt 10):
* - Formular legt Brigade + ersten wehr_admin (local, argon2id) an.
* - Einmal-Passwort wird genau einmal angezeigt.
* - Audit `brigade.create` + `user.create` (über provisioning.ts).
*/
test.skip(
!process.env.E2E_PLATFORM_ADMIN_STATE,
"benötigt platform_admin-Fixture (Test-Workstream)",
);
test.use({
storageState:
process.env.E2E_PLATFORM_ADMIN_STATE ?? { cookies: [], origins: [] },
});
test("Wehr anlegen zeigt Einmal-Passwort", async ({ page }) => {
await page.goto("/admin/wehren/neu");
const stamp = Date.now();
await page.getByLabel("Name").first().fill(`FF Testdorf ${stamp}`);
await page.getByLabel("Straße").fill("Hauptstraße 1");
await page.getByLabel("PLZ").fill("3100");
await page.getByLabel("Ort").fill("St. Pölten");
await page.getByLabel("Telefon").fill("+43 2742 12345");
await page.getByLabel("Admin-Name").fill("Test Admin");
await page.getByLabel("Admin-E-Mail").fill(`admin-${stamp}@test.at`);
await page.getByRole("button", { name: "Wehr anlegen" }).click();
await expect(page.locator("code")).toBeVisible();
const pw = await page.locator("code").innerText();
expect(pw.trim().length).toBeGreaterThan(6);
});