lsa-planer

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

/ tests services projektdateiKennzeichen.test.ts

3,4 KB Rohdatei
tests/services/projektdateiKennzeichen.test.ts — 88 Zeilen
1 import { afterEach, describe, expect, it } from 'vitest';
2 import { openProjectFromFile, serializeProject } from '@/services/storage';
3 import { createEmptyProject } from '@/domain/model/factory';
4 import type { DesktopBridge, OpenFileResult } from '@/platform/bridge';
5
6 /**
7 * Befund 24 zur Fassung 5.9.0.
8 *
9 * Der Hauptprozess liest die bestaetigte Datei mit 'utf8' und reicht den Text
10 * unveraendert durch; `parseFileContent` gab ihn ohne Vorbehandlung an
11 * `JSON.parse`. Steht am Dateianfang das Byteordnungszeichen U+FEFF - unter
12 * Windows der Regelfall bei allem, was mit "UTF-8 mit BOM" geschrieben wurde,
13 * etwa im Editor oder ueber `Out-File` der Windows PowerShell 5.1 -, wirft
14 * `JSON.parse`. Der Anwender las "Die Datei enthält kein gültiges JSON: ..."
15 * und musste annehmen, seine Planunterlage sei beschaedigt, obwohl der Inhalt
16 * vollstaendig und gueltig ist.
17 *
18 * Auf der Schreibseite kennt das Projekt die Windows-Eigenheit laengst:
19 * `src/services/export/csv.ts` setzt das Kennzeichen absichtlich vor jede CSV,
20 * damit Excel die Umlaute richtig liest. Auf der Leseseite fehlte die
21 * Entsprechung.
22 *
23 * `parseFileContent` ist nicht ausgefuehrt und nur ueber `openProjectFromFile`
24 * erreichbar; die Bruecke wird dafuer nachgebildet - wie in
25 * tests/services/projektdatei.test.ts.
26 */
27
28 /** Das Byteordnungszeichen, ueber seinen Kennwert geschrieben. */
29 const KENNZEICHEN = '\uFEFF';
30
31 function mitBruecke(inhalt: string): void {
32 const antwort: OpenFileResult = {
33 ok: true,
34 canceled: false,
35 filePath: 'C:/Plaene/knotenpunkt.lsap',
36 content: inhalt,
37 error: null,
38 };
39 const bruecke = {
40 openFile: () => Promise.resolve(antwort),
41 } as unknown as DesktopBridge;
42 (globalThis as unknown as { window?: { lsaPlaner?: DesktopBridge } }).window = {
43 lsaPlaner: bruecke,
44 };
45 }
46
47 afterEach(() => {
48 delete (globalThis as unknown as { window?: unknown }).window;
49 });
50
51 describe('Projektdatei mit UTF-8-Kennzeichen am Anfang', () => {
52 it('liest sie ein, statt sie als "kein gültiges JSON" abzuweisen', async () => {
53 const original = createEmptyProject('Bahnhofstraße / Ringstraße');
54 mitBruecke(KENNZEICHEN + serializeProject(original));
55
56 const ergebnis = await openProjectFromFile();
57
58 expect(ergebnis.message, 'Die unversehrte Planunterlage wurde abgewiesen').not.toContain(
59 'kein gültiges JSON',
60 );
61 expect(ergebnis.ok).toBe(true);
62 expect(ergebnis.result?.project.meta.name).toBe('Bahnhofstraße / Ringstraße');
63 expect(ergebnis.filePath).toBe('C:/Plaene/knotenpunkt.lsap');
64 });
65
66 it('schneidet genau ein Zeichen ab und keines mehr', async () => {
67 // Ein zweites Kennzeichen ist kein Kodierungsvorzeichen mehr, sondern
68 // Inhalt - und der ist dann tatsaechlich unbrauchbar. Die Nachsicht darf
69 // nicht zur Reparatur beliebiger Vorspaenne werden.
70 mitBruecke(KENNZEICHEN + KENNZEICHEN + serializeProject(createEmptyProject('Zweimal')));
71
72 const ergebnis = await openProjectFromFile();
73
74 expect(ergebnis.ok).toBe(false);
75 expect(ergebnis.result).toBeNull();
76 expect(ergebnis.message).toContain('kein gültiges JSON');
77 });
78
79 it('weist eine wirklich unlesbare Datei weiterhin ab', async () => {
80 mitBruecke(`${KENNZEICHEN}Das ist kein JSON, sondern Text.`);
81
82 const ergebnis = await openProjectFromFile();
83
84 expect(ergebnis.ok).toBe(false);
85 expect(ergebnis.result).toBeNull();
86 expect(ergebnis.message).toContain('kein gültiges JSON');
87 });
88 });