Files
AfiS-Aktensystem/web/tests/thema-vorab.test.ts
T
Harlekin e0b03ea336
Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
Gedankenstriche durch Bindestriche ersetzt
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die
README; an keiner Stelle Bedeutung, nur Zeichensetzung.
2026-09-04 08:54:52 +02:00

47 lines
2.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
/**
* Das Skript, das das Thema vor dem ersten Malen setzt, hängt an drei Dingen,
* die zusammenpassen müssen. Fällt eines weg, merkt es niemand sofort:
*
* 1. **Der Nonce.** Ohne ihn blockiert die Inhaltsrichtlinie das Skript, und
* beim Laden blitzt das falsche Thema auf. Sichtbar, aber leicht als
* Kleinigkeit abgetan.
* 2. **`suppressHydrationWarning`.** Der Browser leert das Nonce-Attribut
* nach dem Parsen, React vergleicht es beim Hydrieren trotzdem und meldet
* einen Unterschied, den es nicht gibt. Die Meldung steht nur in der
* Konsole des Entwicklungsservers - im Produktionsbau meldet React sie
* nicht, ein e2e-Lauf kann sie also nicht auffangen. Deshalb hier auf der
* Ebene der Quelle.
* 3. **Der Schlüssel im Speicher**, derselbe wie im Umschalter. Weichen sie
* ab, wird die Wahl bei jedem Laden vergessen.
*/
const layout = readFileSync(join(process.cwd(), 'app/layout.tsx'), 'utf8')
describe('Thema vor dem ersten Malen', () => {
it('gibt dem Skript einen Nonce und nimmt es aus dem Hydrierungsvergleich', () => {
const tag = layout.slice(layout.indexOf('<script'), layout.indexOf('THEME_SCRIPT }} />'))
expect(tag).toContain('nonce={nonce}')
expect(tag).toContain('suppressHydrationWarning')
})
it('benutzt denselben Speicherschlüssel wie der Umschalter', () => {
const toggle = readFileSync(join(process.cwd(), 'components/ThemeToggle.tsx'), 'utf8')
// Der Schlüssel wird importiert, nicht abgeschrieben - genau das prüft das
// hier: eine zweite, abgeschriebene Zeichenkette wäre der Fehler.
expect(toggle).toMatch(/export const THEME_KEY = '([^']+)'/)
expect(layout).toContain("import { THEME_KEY } from '@/components/ThemeToggle'")
expect(layout).toContain('JSON.stringify(THEME_KEY)')
})
it('setzt nur die beiden ausdrücklichen Themen, nie „wie das System"', () => {
// "system" darf kein data-theme setzen, sonst gewinnt es über die
// Medienabfrage und der Nutzer sitzt im falschen Thema.
expect(layout).toContain("t==='dark'||t==='light'")
})
})