import { afterEach, describe, expect, it } from 'vitest'; import { ProjectStore } from '@/app/store'; import { createStandardIntersectionProject } from '@/domain/model/factory'; import { RILSA_DEFAULTS } from '@/domain/rilsa/constants'; import type { Project } from '@/domain/model/project'; import { resolveRilsaSettings } from '@/domain/rilsa/settings'; import { settingsView } from '@/ui/views/settingsView'; /** * Befund 56 zur Fassung 5.9.0 (Anzeige gegen Fachkern). * * WAS DER ANWENDER SONST ERLEBT * * Er senkt in der Ansicht "Vorgaben" die "Räumgeschwindigkeit Fußgänger" auf * 0,8 m/s und laesst das Nachbarfeld "Räumgeschwindigkeit Fußgänger mit * erhöhtem Zeitbedarf" leer. Der Fachkern koppelt beide: Angesetzt wird * min(1,0; 0,8) = 0,8 m/s, und er fuehrt das als Abweichung mit einer * Fehlermeldung. Die Zeile, in der die Zahl eingetragen wird, zeigt trotzdem * Regelwert 1 und Platzhalter 1 - ohne den Vermerk "wirksam 0,8 m/s". Der * Fehlerbalken darueber sagt dabei woertlich: "gerechnet wird mit dem * zulässigen Wert, der neben dem Feld steht" - und neben dem Feld steht nichts. * * Ursache: `wirksamerWert` brach ab, sobald kein eigener Eintrag vorlag. Die * Ansicht entschied damit selbst, wann eine Abweichung moeglich ist, statt den * aufgeloesten Kennwertsatz zu fragen. */ const FESTES_DATUM = new Date('2026-01-01T00:00:00Z'); afterEach(() => { document.body.replaceChildren(); }); function mitVorgabe(rilsa: Project['settings']['rilsa']): Project { const roh = createStandardIntersectionProject('Vorgaben', FESTES_DATUM); return { ...roh, settings: { ...roh.settings, rilsa: { ...roh.settings.rilsa, ...rilsa } } }; } interface Ansicht { readonly wurzel: HTMLElement; readonly aufraeumen: () => void; } function zeichne(project: Project): Ansicht { const wurzel = document.createElement('div'); document.body.append(wurzel); const schliessen = settingsView.render(wurzel, { store: new ProjectStore(project), refresh: () => {}, navigate: () => {}, target: null, }); return { wurzel, aufraeumen: () => { schliessen(); wurzel.remove(); }, }; } /** Zeile der Vorgabentabelle zu einem Kennwert. */ function zeileZu(wurzel: ParentNode, label: string): HTMLTableRowElement { const zeile = [...wurzel.querySelectorAll('tbody tr')].find( (tr) => tr.children[0]?.textContent?.trim() === label, ); if (!zeile) throw new Error(`Keine Zeile "${label}"`); return zeile; } describe('Vorgaben: der Vermerk "wirksam N" steht auch am leeren Feld', () => { it('nennt bei gesenkter Fussgaengergeschwindigkeit die gekappte Geschwindigkeit des erhoehten Zeitbedarfs', () => { // Der Fachkern kappt hier - belegt am Fachkern selbst, damit die Ansicht // gegen den gerechneten Wert geprueft wird und nicht gegen eine Annahme. const aufgeloest = resolveRilsaSettings({ clearingSpeedFuss: 0.8 }, undefined, 'knotenpunkt'); expect(aufgeloest.defaults.clearingSpeed.fussReducedMobility).toBe(0.8); expect(RILSA_DEFAULTS.clearingSpeed.fussReducedMobility).toBe(1.0); const ansicht = zeichne(mitVorgabe({ clearingSpeedFuss: 0.8 })); try { const zeile = zeileZu( ansicht.wurzel, 'Räumgeschwindigkeit Fußgänger mit erhöhtem Zeitbedarf', ); // Das Feld bleibt leer, der Regelwert bleibt 1 - nur der Vermerk fehlte. expect(zeile.querySelector('input')?.value).toBe(''); expect(zeile.textContent, 'die Zeile stellt 1 m/s als geltend dar').toContain( 'wirksam 0,8 m/s', ); } finally { ansicht.aufraeumen(); } }); it('nennt beim engen Innenradius die Kappung durch die Geschwindigkeit des Abbiegers', () => { const aufgeloest = resolveRilsaSettings( { clearingSpeedKfzTurning: 4 }, undefined, 'knotenpunkt', ); expect(aufgeloest.defaults.clearingSpeed.kfzTurningEngerRadius).toBe(4); const ansicht = zeichne(mitVorgabe({ clearingSpeedKfzTurning: 4 })); try { const zeile = zeileZu( ansicht.wurzel, 'Räumgeschwindigkeit Kfz abbiegend bei engem Innenradius', ); expect(zeile.querySelector('input')?.value).toBe(''); expect(zeile.textContent).toContain('wirksam 4 m/s'); } finally { ansicht.aufraeumen(); } }); it('schweigt an Zeilen, an denen nichts abweicht', () => { const ansicht = zeichne(mitVorgabe({ clearingSpeedFuss: 0.8 })); try { // Das eingetragene Feld selbst: 0,8 ist zulaessig, es wird nichts // ersetzt - kein Vermerk. expect(zeileZu(ansicht.wurzel, 'Räumgeschwindigkeit Fußgänger').textContent).not.toContain( 'wirksam', ); // Ein voellig unbeteiligter Kennwert bleibt ebenfalls stumm. expect(zeileZu(ansicht.wurzel, 'Kleinste Umlaufzeit').textContent).not.toContain('wirksam'); } finally { ansicht.aufraeumen(); } }); it('bleibt ohne jede Vorgabe an allen Zeilen stumm', () => { const ansicht = zeichne(createStandardIntersectionProject('Vorgaben', FESTES_DATUM)); try { const zeilen = [...ansicht.wurzel.querySelectorAll('tbody tr')]; expect(zeilen.length, 'Die Vorgabentabelle ist leer').toBeGreaterThan(0); const mitVermerk = zeilen.filter((tr) => (tr.textContent ?? '').includes('wirksam')); expect(mitVermerk.map((tr) => tr.children[0]?.textContent ?? '')).toEqual([]); } finally { ansicht.aufraeumen(); } }); });