lsa-planer

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

/ tests ui beschaedigtOhneBeiseite.test.ts

3,4 KB Rohdatei
tests/ui/beschaedigtOhneBeiseite.test.ts — 89 Zeilen
1 import { beforeAll, describe, expect, it, vi } from 'vitest';
2 import { ladeSitzung, saveSession } from '@/services/storage';
3
4 /**
5 * Befund 9 zur Fassung 5.9.0.
6 *
7 * Der Sitzungsbefund unterscheidet ausdruecklich, ob ein beschaedigter Satz
8 * beiseitegelegt werden konnte. Scheitert das - etwa weil das Kontingent durch
9 * ein 20-MB-Luftbild und fuenf Wiederherstellungspunkte erschoepft ist -, steht
10 * der beschaedigte Satz weiterhin unter dem Sitzungsschluessel, und der
11 * Quelltext sagt daneben zu: "Dann bleibt er eben liegen und wird beim
12 * naechsten Start erneut geprueft."
13 *
14 * Genau das hielt das Programm nicht ein. `restoreSession` reichte
15 * `beiseitegelegt` nur in den Meldungstext, nicht in den Rueckgabewert, und
16 * `boot()` sperrte das Schreiben ausschliesslich nach 'nicht-lesbar'. Der erste
17 * Sichtwechsel - Minimieren oder Schliessen, also genau der Weg, zu dem die
18 * Meldung auffordert - schrieb das leere Startprojekt ueber den beschaedigten
19 * Satz; die anschliessende Grossdatenaufraeumung nahm das Luftbild mit, sobald
20 * kein Wiederherstellungspunkt mehr darauf zeigte.
21 *
22 * Fuer 'nicht-lesbar' ist dieselbe Sperre in 5.9.0 eingefuehrt worden; der
23 * gleich gelagerte zweite Fall wurde dabei uebersehen.
24 *
25 * Geprueft wird am echten Einstiegspunkt: `src/main.ts` wird eingelesen und
26 * startet die ganze Anwendung. Nur der Sitzungsspeicher ist ersetzt.
27 */
28
29 vi.mock('@/services/storage', async (importOriginal) => {
30 const echt = await importOriginal<typeof import('@/services/storage')>();
31 return {
32 ...echt,
33 ladeSitzung: vi.fn(),
34 saveSession: vi.fn(),
35 addRecoveryPoint: vi.fn(),
36 };
37 });
38
39 async function warte(ms = 0): Promise<void> {
40 await new Promise((fertig) => setTimeout(fertig, ms));
41 }
42
43 function schaltflaeche(text: string): HTMLButtonElement {
44 const treffer = [...document.querySelectorAll('button')].find(
45 (b) => b.textContent?.trim() === text || b.getAttribute('aria-label') === text,
46 );
47 if (!treffer) throw new Error(`Schaltflaeche "${text}" nicht gefunden.`);
48 return treffer;
49 }
50
51 beforeAll(async () => {
52 vi.mocked(ladeSitzung).mockResolvedValue({ art: 'beschaedigt', beiseitegelegt: false });
53 vi.mocked(saveSession).mockResolvedValue({ ok: true, message: '' });
54
55 document.body.replaceChildren();
56 const wurzel = document.createElement('div');
57 wurzel.id = 'anwendung';
58 document.body.append(wurzel);
59
60 await import('@/main');
61 await warte(20);
62 });
63
64 describe('Beschädigter Sitzungssatz, der nicht beiseitegelegt werden konnte', () => {
65 it('schreibt beim Wechsel in den Hintergrund nichts darüber', async () => {
66 Object.defineProperty(document, 'visibilityState', { value: 'hidden', configurable: true });
67 document.dispatchEvent(new Event('visibilitychange'));
68 await warte(10);
69
70 expect(
71 saveSession,
72 'Das leere Startprojekt wurde ueber den beschaedigten Satz geschrieben',
73 ).not.toHaveBeenCalled();
74
75 Object.defineProperty(document, 'visibilityState', { value: 'visible', configurable: true });
76 });
77
78 it('schreibt wieder, sobald der Anwender über "Neu" bewusst ein Projekt setzt', async () => {
79 schaltflaeche('Neu').click();
80 await warte(10);
81 schaltflaeche('Leeres Projekt').click();
82 await warte(10);
83
84 // Erst diese ausdrueckliche Entscheidung gibt den Sitzungsspeicher wieder
85 // frei - und belegt zugleich, dass der Schreibweg oben nicht aus einem
86 // anderen Grund still war.
87 expect(saveSession).toHaveBeenCalledTimes(1);
88 });
89 });