# Tests und Abnahme Stand 27.09.2026. Alle aufgeführten Läufe sind lokal ausgeführt und bestanden. ## Automatisierte Tests `pnpm test` umfasst 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 Termin 08.05.2027 fällt die letzte Rate auf den 08.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 `/admin` zur 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 `totalCents` wird ignoriert. - Sicherheitsheader (CSP mit Nonce, HSTS, X-Frame-Options) sind gesetzt. - Der Standalone-Build läuft mit Datenbank. Worker-Lauf und `admin:create` funktionieren, 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 - **Echte Stripe-Testbuchung** gegen die Stripe-API: Ein Stripe-Testschlüssel lag nicht vor. Die Stripe-Logik ist gegen eine Attrappe mit Stripe-Semantik getestet (Idempotenz, Session-Zustände, Rechnungen des Ratenplans), die Webhook-Signatur mit der echten Stripe-Bibliothek. Mit Schlüssel: Anleitung in der README (`stripe listen`, Testkarten). - **Docker-Image und Cluster:** Auf dem Entwicklungsrechner gibt es kein Docker und keinen Cluster-Zugang. Das Dockerfile ist nicht gebaut und nicht im Cluster ausgerollt. Geprüft sind der Standalone-Build und das Rendern der Manifeste. - **SMTP-Versand:** nur über den Datei-Testausgang geprüft. - **Referenzseite:** nur über eine Textzusammenfassung ausgewertet (siehe ARCHITEKTUR.md).