lsa-planer

LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.

/ tests ui kaestchennamen.test.ts

5,5 KB Rohdatei
tests/ui/kaestchennamen.test.ts — 126 Zeilen
1 import { afterEach, describe, expect, it } from 'vitest';
2 import { ProjectStore } from '@/app/store';
3 import { RILSA_DEFAULTS } from '@/domain/rilsa/constants';
4 import { createStandardIntersectionProject } from '@/domain/model/factory';
5 import type { Project } from '@/domain/model/project';
6 import { erhoehterZeitbedarfBeschriftung, signalGroupsView } from '@/ui/views/signalGroupsView';
7 import { zugaenglicherName } from './zugaenglicherName';
8
9 /**
10 * Befund 18 zur Fassung 5.10.0 - die beiden Kaestchenspalten der
11 * Signalgruppentabelle.
12 *
13 * "Erhöhter Zeitbedarf" und "Blindenzusatz" entstehen ueber `checkboxCell`,
14 * und das setzt seinen Beschriftungstext unmittelbar als `aria-label`
15 * (src/ui/inputs.ts). `benenneBedienelemente` ueberspringt jedes Feld, das
16 * schon einen Namen traegt (src/ui/dom.ts) - die Benennung aus Spaltenkopf und
17 * Zeilenname erreichte diese beiden Spalten also nie. Jede Furtzeile trug
18 * denselben Erklaersatz als Namen; welche Furt gemeint ist, sagte er nicht.
19 *
20 * Das ist genau das Muster, das Befund M2 in derselben Ansicht ueberall sonst
21 * beseitigt hat (Auswahlfelder ueber `auswahlMitHinweis`, Farbfeld, Mindest-
22 * und Hoechstfreigabezeit, Lastzuganteil), und der Zustand, der zu 1.3.1 als
23 * beseitigt gilt. Die beiden ausgeschriebenen Kopfnamen lagen im
24 * `ausgeschrieben`-Verzeichnis der Ansicht schon bereit und wurden wegen des
25 * festen `aria-label` nie zu einem Feldnamen - toter Text hinter einer Zusage.
26 *
27 * FACHLICHES GEWICHT: `reducedMobility` senkt die Raeumgeschwindigkeit der Furt
28 * von 1,2 auf 1,0 m/s, `blindenzusatz` verlangt die Freigabezeit fuer die ganze
29 * statt fuer die halbe Furt. Am falschen Strom gesetzt oder entfernt, verkuerzt
30 * beides Zwischenzeit oder Freigabezeit - die gefaehrliche Richtung.
31 */
32
33 const STICHTAG = new Date('2026-01-01T00:00:00Z');
34
35 const BLINDENZUSATZ_SATZ =
36 'Zusatzeinrichtung für Blinde und Sehbehinderte (Freigabe für die ganze Furt statt für die halbe)';
37
38 let aufraeumen: (() => void) | null = null;
39 afterEach(() => {
40 aufraeumen?.();
41 aufraeumen = null;
42 document.body.replaceChildren();
43 });
44
45 function zeichne(project: Project): HTMLElement {
46 const wurzel = document.createElement('div');
47 document.body.append(wurzel);
48 const schliessen = signalGroupsView.render(wurzel, {
49 store: new ProjectStore(project),
50 refresh: () => {},
51 navigate: () => {},
52 target: null,
53 });
54 aufraeumen = () => {
55 schliessen();
56 wurzel.remove();
57 };
58 return wurzel;
59 }
60
61 /** Alle Kontrollkaestchen, deren Kurzhinweis mit `anfang` beginnt. */
62 function kaestchen(wurzel: HTMLElement, anfang: string): HTMLInputElement[] {
63 return [...wurzel.querySelectorAll<HTMLInputElement>('input[type="checkbox"]')].filter((i) =>
64 i.title.startsWith(anfang),
65 );
66 }
67
68 /** Text, den eine Sprachausgabe als Beschreibung des Feldes liest. */
69 function beschreibung(wurzel: HTMLElement, feld: HTMLElement): string {
70 const id = feld.getAttribute('aria-describedby') ?? '';
71 const knoten = id === '' ? null : wurzel.querySelector(`[id="${id}"]`);
72 return (knoten?.textContent ?? '').trim();
73 }
74
75 describe('Befund 18 - die Furtkaestchen nennen ihre Signalgruppe', () => {
76 it('benennt "Erhöhter Zeitbedarf" aus Spaltenkopf und Zeilenname', () => {
77 const wurzel = zeichne(createStandardIntersectionProject('Kaestchen', STICHTAG));
78 const felder = kaestchen(wurzel, 'Furt mit erhöhtem Zeitbedarf');
79 expect(felder.length, 'Der Regelknotenpunkt hat zwei Fußgängergruppen').toBe(2);
80
81 const namen = felder.map((f) => zugaenglicherName(f));
82 expect(namen).toEqual([
83 'Erhöhter Zeitbedarf bei der Furt, F1',
84 'Erhöhter Zeitbedarf bei der Furt, F2',
85 ]);
86 });
87
88 it('benennt "Blindenzusatz" aus Spaltenkopf und Zeilenname', () => {
89 const wurzel = zeichne(createStandardIntersectionProject('Kaestchen', STICHTAG));
90 const felder = kaestchen(wurzel, 'Zusatzeinrichtung für Blinde');
91 expect(felder.length).toBe(2);
92
93 expect(felder.map((f) => zugaenglicherName(f))).toEqual([
94 'Zusatzeinrichtung für Blinde und Sehbehinderte an der Furt, F1',
95 'Zusatzeinrichtung für Blinde und Sehbehinderte an der Furt, F2',
96 ]);
97 });
98
99 it('vergibt in der ganzen Tabelle keinen Namen zweimal', () => {
100 const wurzel = zeichne(createStandardIntersectionProject('Kaestchen', STICHTAG));
101 const namen = [...wurzel.querySelectorAll<HTMLInputElement>('input[type="checkbox"]')].map(
102 (f) => zugaenglicherName(f),
103 );
104 expect(namen.length).toBeGreaterThan(0);
105 expect(new Set(namen).size, `Doppelte Namen: ${namen.join(' | ')}`).toBe(namen.length);
106 });
107
108 it('fuehrt den Erklaersatz als Beschreibung weiter - mit dem wirksamen Wert', () => {
109 // Der Satz geht nicht verloren, er wechselt nur die Rolle: `aria-label`
110 // ERSETZT den Namen, `aria-describedby` ergaenzt ihn (Begruendung bei
111 // `ergaenzeBereichshinweis` in ui/dom.ts). Damit bleibt die Zusage aus
112 // Befund C21 gewahrt - der wirksame Kennwert wird vorgelesen.
113 const wurzel = zeichne(createStandardIntersectionProject('Kaestchen', STICHTAG));
114 const satz = erhoehterZeitbedarfBeschriftung(RILSA_DEFAULTS);
115 expect(satz).toBe('Furt mit erhöhtem Zeitbedarf (1,0 m/s statt 1,2 m/s)');
116
117 for (const feld of kaestchen(wurzel, 'Furt mit erhöhtem Zeitbedarf')) {
118 expect(feld.title).toBe(satz);
119 expect(beschreibung(wurzel, feld)).toBe(satz);
120 }
121 for (const feld of kaestchen(wurzel, 'Zusatzeinrichtung für Blinde')) {
122 expect(feld.title).toBe(BLINDENZUSATZ_SATZ);
123 expect(beschreibung(wurzel, feld)).toBe(BLINDENZUSATZ_SATZ);
124 }
125 });
126 });