import { afterEach, describe, expect, it } from 'vitest'; import * as actions from '@/app/actions'; import { ProjectStore } from '@/app/store'; import type { Lageplan } from '@/domain/geometrie/lageplan'; import { ASSISTENT_VORGABE, projektAusAngaben } from '@/ui/assistent'; import { lageplanView } from '@/ui/views/lageplanView'; /** * Befund 65: Nach einer abgewiesenen Fahrlinie meldete die Seitenleiste weiter * gesetzte Punkte. * * WAS DER ANWENDER SONST ERLEBT * * Er setzt einen einzigen Punkt und drueckt die Eingabetaste. Die Meldung "Eine * Fahrlinie braucht mindestens zwei Punkte" erscheint, der Entwurf ist * verworfen - die Seitenleiste behauptet aber weiter "1 Punkt(e) gesetzt ... * Beginnt an der Haltlinie 'X'. Naechster Punkt mit Klick oder Leertaste". * Wer der Zeile folgt und einen Punkt setzt, beginnt in Wahrheit eine NEUE * Linie an dieser Stelle, statt eine bestehende fortzusetzen; der erste Punkt * ist aber der Nullpunkt von Raeum- und Einfahrweg. * * Dieselbe Ursache trifft die Ruecknahme mit der Rueckschritttaste: Auch dort * wurde nur die Zeichenflaeche neu gemalt, nicht die Seitenleiste. */ const FESTES_DATUM = '2026-01-01T00:00:00.000Z'; /** Plan mit Massstab und einer waagerechten Haltlinie bei y = 200. */ function planMitHaltlinie(): Lageplan { return { arbeitsbereiche: [], signalgeber: [], bild: null, kalibrierung: { von: { x: 0, y: 0 }, bis: { x: 100, y: 0 }, laengeMeter: 20, herkunft: 'gemessen', }, haltlinien: [ { id: 'hl1', name: 'Nord', art: 'zufahrt', armId: null, von: { x: 100, y: 200 }, bis: { x: 220, y: 200 }, }, ], linien: [], }; } interface Ansicht { readonly store: ProjectStore; readonly wurzel: HTMLElement; readonly leinwand: HTMLCanvasElement; readonly aufraeumen: () => void; } function baueAnsicht(): Ansicht { const store = new ProjectStore(projektAusAngaben({ ...ASSISTENT_VORGABE }, FESTES_DATUM)); store.update((p) => actions.setLageplan(p, planMitHaltlinie()), { label: 'Pruefplan' }); const wurzel = document.createElement('div'); document.body.append(wurzel); const schliessen = lageplanView.render(wurzel, { store, refresh: () => {}, navigate: () => {}, target: null, }); const leinwand = wurzel.querySelector('canvas'); if (leinwand === null) throw new Error('Die Ansicht hat keine Zeichenflaeche.'); return { store, wurzel, leinwand, aufraeumen: () => { leinwand.blur(); schliessen(); wurzel.remove(); }, }; } afterEach(() => { document.body.replaceChildren(); }); function waehleWerkzeug(ansicht: Ansicht, beschriftung: string): void { const knopf = [ ...ansicht.wurzel.querySelectorAll('.lageplan-werkzeuge button'), ].find((b) => (b.textContent ?? '').trim() === beschriftung); if (knopf === undefined) throw new Error(`Kein Werkzeug "${beschriftung}"`); knopf.click(); } function tippe(key: string, male = 1): void { for (let i = 0; i < male; i += 1) { const ziel = (document.activeElement as HTMLElement | null) ?? document.body; ziel.dispatchEvent(new KeyboardEvent('keydown', { key, bubbles: true, cancelable: true })); } } /** Text der Seitenleiste - dort steht die Zeile mit den gesetzten Punkten. */ function seitentext(ansicht: Ansicht): string { return ansicht.wurzel.querySelector('.lageplan-seite')?.textContent ?? ''; } describe('Seitenleiste nach einem verworfenen Entwurf', () => { it('meldet nach der abgewiesenen Fahrlinie keine gesetzten Punkte mehr', () => { const ansicht = baueAnsicht(); try { waehleWerkzeug(ansicht, 'Fahrlinie'); ansicht.leinwand.focus(); tippe(' '); expect(seitentext(ansicht), 'die Statuszeile fehlt schon vorher').toContain( '1 Punkt(e) gesetzt', ); tippe('Enter'); expect(ansicht.store.getProject().lageplan.linien).toHaveLength(0); expect(seitentext(ansicht)).not.toContain('Punkt(e) gesetzt'); } finally { ansicht.aufraeumen(); } }); it('führt die Zahl der Punkte auch beim Zurücknehmen mit', () => { const ansicht = baueAnsicht(); try { waehleWerkzeug(ansicht, 'Fahrlinie'); ansicht.leinwand.focus(); tippe(' '); tippe('ArrowRight', 4); tippe(' '); expect(seitentext(ansicht)).toContain('2 Punkt(e) gesetzt'); tippe('Backspace'); expect(seitentext(ansicht)).toContain('1 Punkt(e) gesetzt'); tippe('Backspace'); // Kein Punkt mehr - die Zeile darf keinen mehr behaupten. expect(seitentext(ansicht)).not.toContain('Punkt(e) gesetzt'); } finally { ansicht.aufraeumen(); } }); });