test: Integrations-, Migrations- und E2E-Tests ergänzen
Der Integrationstest prüft gegen eine echte Datenbank, was Vitest nicht sieht: Eindeutigkeit, Fremdschlüssel, Kaskaden und dass das Protokoll den gelöschten Benutzer überlebt. Er läuft bewusst ohne umschließende Transaktion — er prüft absichtlich Fälle, die scheitern müssen, und ein gescheiterter Befehl bricht in PostgreSQL die ganze Transaktion ab. Stattdessen tragen alle Testdaten dieselbe Kennung und werden am Ende wieder entfernt. Der Migrationstest legt eine Wegwerf-Datenbank an, spielt alle Migrationen ein und vergleicht das Ergebnis mit dem Schema. Dass er Abweichungen wirklich bemerkt, wurde mit einem probeweise ergänzten Feld nachgewiesen. Der E2E-Rauchtest deckt den Weg ab, der in M1 trägt: Umleitung ohne Anmeldung samt gemerktem Ziel, Abweisung falscher Zugangsdaten, erfolgreiche Anmeldung und die Verwaltungsseite. Dafür neu: eine Middleware, die nur den angefragten Pfad als Kopfzeile durchreicht. Ein Layout kennt seinen Pfad nicht, braucht ihn aber für die Rückkehr nach der Anmeldung. Anmeldelogik steht dort bewusst nicht — die Middleware läuft im Edge-Umfeld ohne Prisma. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
24a799d6ba
commit
126ad93301
@@ -0,0 +1,79 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
|
||||
/**
|
||||
* Rauchtest der Anmeldung.
|
||||
*
|
||||
* Prüft den Weg, der in M1 wirklich trägt: Wer nicht angemeldet ist, kommt
|
||||
* nirgends hin; mit richtigem Passwort schon; und die Verwaltungsseite bleibt
|
||||
* verschlossen, wenn die Rolle nicht reicht.
|
||||
*
|
||||
* Voraussetzung: "npm run db:seed" ist gelaufen und ADMIN_EMAIL sowie
|
||||
* ADMIN_PASSWORT sind gesetzt.
|
||||
*/
|
||||
|
||||
const EMAIL = process.env.ADMIN_EMAIL ?? ''
|
||||
const PASSWORT = process.env.ADMIN_PASSWORT ?? ''
|
||||
|
||||
test.describe('Anmeldung', () => {
|
||||
test.skip(
|
||||
!EMAIL || !PASSWORT,
|
||||
'ADMIN_EMAIL und ADMIN_PASSWORT sind nicht gesetzt – ohne sie gibt es kein Testkonto.',
|
||||
)
|
||||
|
||||
test('leitet nicht Angemeldete zur Anmeldeseite', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
await expect(page).toHaveURL(/\/anmelden/)
|
||||
await expect(page.getByRole('heading', { name: 'Planer' })).toBeVisible()
|
||||
})
|
||||
|
||||
test('merkt sich das Ziel und kehrt nach der Anmeldung dorthin zurück', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto('/bereiche')
|
||||
await expect(page).toHaveURL(/\/anmelden\?weiter=%2Fbereiche/)
|
||||
})
|
||||
|
||||
test('weist falsche Zugangsdaten ab, ohne zu verraten warum', async ({ page }) => {
|
||||
await page.goto('/anmelden')
|
||||
await page.getByLabel('E-Mail-Adresse').fill(EMAIL)
|
||||
await page.getByLabel('Passwort').fill('ganz-sicher-falsch-123')
|
||||
await page.getByRole('button', { name: 'Mit Passwort anmelden' }).click()
|
||||
|
||||
await expect(page.getByText('Anmeldung nicht möglich')).toBeVisible()
|
||||
await expect(page).toHaveURL(/\/anmelden/)
|
||||
})
|
||||
|
||||
test('lässt mit richtigem Passwort hinein und wieder hinaus', async ({ page }) => {
|
||||
await page.goto('/anmelden')
|
||||
await page.getByLabel('E-Mail-Adresse').fill(EMAIL)
|
||||
await page.getByLabel('Passwort').fill(PASSWORT)
|
||||
await page.getByRole('button', { name: 'Mit Passwort anmelden' }).click()
|
||||
|
||||
await expect(page.getByRole('heading', { name: /Guten Tag/ })).toBeVisible()
|
||||
await expect(page.getByRole('link', { name: 'Bereiche' })).toBeVisible()
|
||||
|
||||
await page.getByTitle('Abmelden').click()
|
||||
await expect(page).toHaveURL(/\/anmelden/)
|
||||
})
|
||||
|
||||
test('zeigt der Verwaltung das Protokoll', async ({ page }) => {
|
||||
await page.goto('/anmelden')
|
||||
await page.getByLabel('E-Mail-Adresse').fill(EMAIL)
|
||||
await page.getByLabel('Passwort').fill(PASSWORT)
|
||||
await page.getByRole('button', { name: 'Mit Passwort anmelden' }).click()
|
||||
await expect(page.getByRole('heading', { name: /Guten Tag/ })).toBeVisible()
|
||||
|
||||
await page.getByRole('link', { name: 'Protokoll' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Protokoll' })).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test('der Health-Endpunkt antwortet ohne Anmeldung', async ({ request }) => {
|
||||
const antwort = await request.get('/api/health')
|
||||
expect(antwort.ok()).toBe(true)
|
||||
|
||||
const inhalt = (await antwort.json()) as Record<string, unknown>
|
||||
expect(inhalt.status).toBe('ok')
|
||||
expect(inhalt.datenbank).toBe('ok')
|
||||
expect(typeof inhalt.version).toBe('string')
|
||||
})
|
||||
Reference in New Issue
Block a user