waffensachkunde

Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.

/ app tests theme.test.ts

5,9 KB Rohdatei
app/tests/theme.test.ts — 151 Zeilen
1 import { describe, expect, it } from 'vitest';
2
3 import {
4 farbschemaFuer,
5 istThemeAuswahl,
6 startfarbeFuer,
7 themeAufloesen,
8 umschaltAnsage,
9 type SystemAnzeigeSignale,
10 } from '../src/shared/theme';
11
12 function signale(teil: Partial<SystemAnzeigeSignale> = {}): SystemAnzeigeSignale {
13 return {
14 bevorzugtDunkel: false,
15 erzwungeneFarben: false,
16 bevorzugtMehrKontrast: false,
17 ...teil,
18 };
19 }
20
21 describe('themeAufloesen', () => {
22 it('folgt bei "system" der hellen Systemvorgabe', () => {
23 expect(themeAufloesen('system', signale())).toBe('hell');
24 });
25
26 it('folgt bei "system" der dunklen Systemvorgabe', () => {
27 expect(themeAufloesen('system', signale({ bevorzugtDunkel: true }))).toBe('dunkel');
28 });
29
30 it('wählt bei "system" und prefers-contrast: more den hohen Kontrast', () => {
31 expect(themeAufloesen('system', signale({ bevorzugtMehrKontrast: true }))).toBe('hochkontrast');
32 });
33
34 it('respektiert die manuelle Auswahl gegen die Systemvorgabe', () => {
35 expect(themeAufloesen('hell', signale({ bevorzugtDunkel: true }))).toBe('hell');
36 expect(themeAufloesen('dunkel', signale())).toBe('dunkel');
37 });
38
39 it('lässt erzwungene Farben jede Auswahl überstimmen', () => {
40 for (const auswahl of ['system', 'hell', 'dunkel', 'hochkontrast'] as const) {
41 expect(themeAufloesen(auswahl, signale({ erzwungeneFarben: true }))).toBe('hochkontrast');
42 }
43 });
44 });
45
46 describe('istThemeAuswahl', () => {
47 it('erkennt gültige Werte', () => {
48 expect(istThemeAuswahl('hochkontrast')).toBe(true);
49 });
50
51 it('weist unbekannte oder falsch typisierte Werte ab', () => {
52 expect(istThemeAuswahl('neon')).toBe(false);
53 expect(istThemeAuswahl(null)).toBe(false);
54 expect(istThemeAuswahl(42)).toBe(false);
55 expect(istThemeAuswahl(undefined)).toBe(false);
56 });
57 });
58
59 describe('farbschemaFuer', () => {
60 it('stimmt mit den color-scheme-Angaben in tokens.css überein', () => {
61 expect(farbschemaFuer('hell')).toBe('light');
62 expect(farbschemaFuer('dunkel')).toBe('dark');
63 // Hoher Kontrast ist weiße Schrift auf Schwarz – also ebenfalls dark.
64 expect(farbschemaFuer('hochkontrast')).toBe('dark');
65 });
66
67 /*
68 Beim Windows-Kontrastdesign sagt `hochkontrast` nur, dass die Farben von
69 aussen kommen. Es gibt auch helle Kontrastdesigns; bis 0.24.1 stellte die
70 Anwendung dort Scrollbalken und Formularelemente unbedingt auf dunkel.
71 `startfarbeFuer` macht es seit jeher richtig – hier fehlte die
72 Entsprechung.
73 */
74 it('überlässt bei erzwungenen Farben dem System, ob hell oder dunkel', () => {
75 expect(farbschemaFuer('hochkontrast', signale({ erzwungeneFarben: true }))).toBe('light');
76 expect(
77 farbschemaFuer('hochkontrast', signale({ erzwungeneFarben: true, bevorzugtDunkel: true })),
78 ).toBe('dark');
79 });
80
81 it('bleibt dieselbe Aussage wie startfarbeFuer', () => {
82 /* Zwei Funktionen, eine Frage – sie dürfen nicht auseinanderlaufen. */
83 for (const dunkel of [false, true]) {
84 const s = signale({ erzwungeneFarben: true, bevorzugtDunkel: dunkel });
85 const hellSchema = farbschemaFuer('hochkontrast', s) === 'light';
86 expect(startfarbeFuer('hochkontrast', s)).toBe(hellSchema ? '#ffffff' : '#000000');
87 }
88 });
89 });
90
91 describe('startfarbeFuer', () => {
92 /*
93 Die Farbe, die das Fenster zeigt, bevor der Renderer das erste Bild
94 liefert. Bis 0.21.0 fragte `fenster.ts` dafür nur `nativeTheme` – wer
95 „Dunkel“ eingestellt hatte, während Windows hell läuft, sah bei jedem
96 Start kurz eine helle Fläche. Seither entscheidet die gespeicherte Wahl.
97 */
98 it('folgt der gespeicherten Wahl und nicht dem Systemdesign', () => {
99 expect(startfarbeFuer('dunkel', signale())).toBe('#14161a');
100 expect(startfarbeFuer('hell', signale({ bevorzugtDunkel: true }))).toBe('#f7f7f5');
101 expect(startfarbeFuer('hochkontrast', signale())).toBe('#000000');
102 });
103
104 it('überlässt bei „system“ dem Betriebssystem die Entscheidung', () => {
105 expect(startfarbeFuer('system', signale())).toBe('#f7f7f5');
106 expect(startfarbeFuer('system', signale({ bevorzugtDunkel: true }))).toBe('#14161a');
107 });
108
109 it('nimmt bei erzwungenen Farben die Farben des Betriebssystems', () => {
110 /* Dort greift tokens.css auf `Canvas` zurück; ein helles Kontrastdesign
111 ist weiß. Eine eigene Farbe wäre hier falsch – auch dann, wenn jemand
112 „Dunkel“ eingestellt hat. */
113 expect(startfarbeFuer('dunkel', signale({ erzwungeneFarben: true }))).toBe('#ffffff');
114 expect(startfarbeFuer('hell', signale({ erzwungeneFarben: true, bevorzugtDunkel: true }))).toBe(
115 '#000000',
116 );
117 });
118
119 /* Dass diese drei Farben mit `--farbe-grund` in tokens.css übereinstimmen,
120 prüft `tests/token-kontraste.test.ts` – dort liegt der Leser für die
121 CSS-Datei bereits. */
122 });
123
124 describe('umschaltAnsage', () => {
125 it('nennt bei "system" das tatsächlich aktive Theme', () => {
126 expect(umschaltAnsage('system', 'dunkel')).toContain('Systemvorgabe');
127 expect(umschaltAnsage('system', 'dunkel')).toContain('Dunkel');
128 });
129
130 it('nennt bei manueller Wahl die gewählte Darstellung', () => {
131 expect(umschaltAnsage('hochkontrast', 'hochkontrast')).toBe(
132 'Darstellung umgestellt auf Hoher Kontrast.',
133 );
134 });
135
136 /*
137 Läuft das Windows-Kontrastdesign, hat `themeAufloesen` unbedingten
138 Vorrang: Die Wahl wird gespeichert, sichtbar wird sie nicht. Bis 0.24.1
139 meldete die Ansage trotzdem „Darstellung umgestellt auf Dunkel“ – für
140 jemanden, der die Umstellung nicht sehen kann, die irreführendste
141 Auskunft, die dort stehen kann.
142 */
143 it('behauptet bei erzwungenen Farben keine Umstellung, die nicht stattfindet', () => {
144 const ansage = umschaltAnsage('dunkel', 'hochkontrast', signale({ erzwungeneFarben: true }));
145
146 expect(ansage).not.toContain('umgestellt');
147 expect(ansage).toContain('gespeichert');
148 expect(ansage).toContain('Kontrastdesign');
149 expect(ansage).toContain('Dunkel');
150 });
151 });