README mit Projektstand (Links auf Issues #33, #32), fehlenden Befehlen und CI-Gate. BETRIEB: sha-gepinnte Manifeste, DB-Sicherung, Rollout per set image, Label-Selector im pg_dump-Befehl, Storage Box. k8s/README: Schritt 09, Warnung vor delete namespace. TESTS, OFFENE-PUNKTE, ARCHITEKTUR (ADR-8, ADR-9) aktualisiert; Kommentare in .env.example und Worker-CronJob korrigiert. Refs #31 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
6.5 KiB
Tests und Abnahme
Stand 16.10.2026. Die Abschnitte unten sind chronologisch gewachsen; der aktuelle Stand steht hier oben.
Aktuell: pnpm test umfasst 10 Testdateien (rund 130 Tests; 132 beim lokalen Lauf am 14.10.2026 zu Commit f29dbcf, seither kam mit 9785eb2 ein Regressionstest hinzu). Seit 0421d7d (14.10.2026) laufen lint mit pnpm audit, typecheck und test bei jedem Push auf main in der CI; der Test-Job nutzt PostgreSQL 18.6 als Service (TEST_DATABASE_URL). Letzter CI-Lauf (9785eb2, 15.10.2026): lint, typecheck und test grün, nur der Image-Build schlug fehl (Issue #20). Die Playwright-Tests (pnpm test:e2e, 3 Tests je Profil) laufen nur lokal.
Seit dem ersten Stand hinzugekommene Testdateien: client-ip.test.ts (Client-IP hinter Traefik und Cloudflare, IPv6 je /64, Proxy um NextRequest), contact.integration.test.ts (Formular „Erstgespräch“), email-outbox.integration.test.ts (Postausgang, endgültige und vorübergehende SMTP-Fehler), review-format.test.ts (Google-Rezensionen).
Automatisierte Tests
Stand 27.09.2026: pnpm test umfasste 72 Tests in 6 Dateien. Sie laufen gegen eine echte, frisch gestartete PostgreSQL-18-Instanz, damit Zeilensperren und Trigger mitgetestet werden.
| Geschäftsrisiko | Datei |
|---|---|
| Alle vier Gesamtpreise, 28 % statt 30 % | tests/pricing.test.ts |
| Alle zwölf Ratenbeträge exakt, einschließlich 1.237,50 € | tests/payment-plan.test.ts |
| Zeitgrenzen 01.11.2026 und 01.01.2027 in Europe/Berlin, Sommerzeit | tests/pricing.test.ts, booking.integration.test.ts |
| Ungültige, inaktive, abgelaufene, noch nicht gültige, fremd gebundene und ausgeschöpfte Gutscheine | booking.integration.test.ts |
| Gleichzeitige Einlösung eines begrenzten Codes (7 parallel, 2 erlaubt) und Gesamtkontingent | booking.integration.test.ts |
| Gleichzeitige Buchungen bei knapper Kapazität (8 parallel, 2 Plätze) | booking.integration.test.ts |
| Abgelaufene Reservierungen, verzögerte Zahlung (SEPA), verspätete Zahlung mit und ohne freien Platz, verlorener Webhook | payments.integration.test.ts |
| Doppelte und ungeordnete Stripe-Events, Livemodus-Event im Testbetrieb, Signaturprüfung | payments.integration.test.ts |
| Zahlungserfolg, Abbruch, Fehler, Teilzahlung, Authentifizierung, Erstattung | payments.integration.test.ts, admin.integration.test.ts |
| Sperre aller Live-Checkout-Zugänge ohne Freigabe, Vorschauphase | sales-gate.test.ts, booking.integration.test.ts |
| Keine weitere Abbuchung nach der letzten Rate oder nach Stornierung, Zahlungsmethode getrennt | payments.integration.test.ts, admin.integration.test.ts |
| Unveränderlicher Preis-Snapshot (DB-Trigger), Idempotenz bei Doppelklick | booking.integration.test.ts |
End-to-End und Sicht
pnpm test:e2e umfasst 9 Tests auf den Profilen Smartphone (Pixel 7), Tablet (820 × 1180) und Desktop (1440 × 900):
- axe-Prüfung WCAG 2.1 AA ohne Verstöße
- kein horizontales Scrollen
- keine öffentliche Platzzahl
- Buchungsdialog: Pflichtfelder, Gutschein, Ratenplan 3 × 660 €, Erklärungen, Fokus beim Öffnen und Schließen per Escape
- Admin-Weiterleitung, Export mit gefälschtem Cookie ergibt 401, Statusseite mit
noindex
Bildschirmfotos aller drei Größen wurden visuell geprüft.
Letzter Lauf 01.10.2026 nach Einbau von Team, Villa-Bildern und bestätigtem Termin: 81/81 Unit- und Integrationstests, 9/9 E2E-Tests, Produktionsbuild grün. Team und Unterkunft wurden zusätzlich per Bildschirmfoto auf Smartphone (390 px) und Desktop (1440 px) geprüft. Mit dem damaligen Termin 08.05.2027 fiel die letzte Rate auf den 08.04.2027; seit dem Termin 03.05.2027 (Migration vom 02.10.2026) ist es der 03.04.2027.
Hinweis: Läuft der Testserver nicht unter der Adresse aus APP_URL, lehnt der Same-Origin-Schutz die Preisabfrage ab (403). Dann hängt der Buchungsdialog bei „Preise werden geladen …“. Server deshalb mit passender APP_URL starten, z. B. APP_URL=http://localhost:3005 PORT=3005 pnpm start und E2E_BASE_URL=http://localhost:3005 pnpm test:e2e.
Manuell über HTTP geprüft
- Admin-Ablauf:
- Öffentliche Registrierung wird mit 400 abgelehnt, ein falsches Passwort mit 401.
- Ohne 2FA leitet
/adminzur Einrichtung um, der Export antwortet 401. - Nach der TOTP-Aktivierung sind Dashboard und CSV mit 200 erreichbar.
- CSRF: Anfragen ohne JSON bekommen 415, fremde Origins 403.
- Preismanipulation: Ein mitgeschicktes
totalCentswird ignoriert. - Sicherheitsheader (CSP mit Nonce, HSTS, X-Frame-Options) sind gesetzt.
- Der Standalone-Build läuft mit Datenbank. Worker-Lauf und
admin:createfunktionieren, eine doppelte Anlage wird abgewiesen. - Build, Typprüfung und ESLint laufen ohne Fehler, Kustomize rendert 17 Ressourcen.
Lauf 06.10.2026 nach Umstellung der Folgeraten auf Stripe Billing (inkl. Anhalten bei Prüfung und Schutz vor doppeltem Plan): 88/88 Unit- und Integrationstests, Typprüfung und ESLint ohne Fehler. Zusätzlich StripeGateway gegen die echte Stripe-Test-API mit Testuhr geprüft: Zeitplan mit zwei Folgeraten erzeugt genau zwei bezahlte Rechnungen (je 700 €, Metadaten bookingId/kind, PaymentIntent mit Charge) und endet danach (completed); abgelehnte Karte ergibt offene Rechnung mit geplantem Wiederholungsversuch und Zahlungslink; Storno setzt den Zeitplan auf canceled und die offene Rechnung auf void, auch wiederholt und vor dem Start.
Nicht ausgeführt / Einschränkungen
- Vollständige Stripe-Testbuchung über die Oberfläche bis zum Webhook: In der Testsuite läuft die Stripe-Logik gegen eine Attrappe mit Stripe-Semantik (Idempotenz, Session-Zustände, Rechnungen des Ratenplans), die Webhook-Signatur mit der echten Stripe-Bibliothek. Gegen die echte Stripe-Test-API geprüft ist bisher nur der Ratenplan (
StripeGatewaymit Testuhr, Lauf vom 06.10.2026). Ein dokumentierter Durchlauf Buchung → Checkout → Webhook → Bestätigungsmail auf dem Cluster fehlt (Issue #27). Anleitung lokal in der README (stripe listen, Testkarten). - Docker-Image und Cluster: Seit dem 27.09.2026 baut die CI beide Images; die Seite läuft im Cluster (zuletzt belegt ausgerollt:
sha-5a88f3d, 13.10.2026). Eine automatisierte Prüfung nach dem Rollout gibt es nicht; der Monitoring-Dienst Gatus im Cluster prüft die Erreichbarkeit. - SMTP-Versand: im Repo nur über den Datei-Testausgang geprüft. Ob im Cluster ein echter SMTP-Zugang eingetragen ist, ist hier nicht dokumentiert.
- E2E-Tests laufen nicht in der CI.
- Referenzseite: nur über eine Textzusammenfassung ausgewertet (siehe ARCHITEKTUR.md).