waffensachkunde
Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.
/ app tests dateizugriff.test.ts
| 1 | // @vitest-environment node |
| 2 | /** |
| 3 | * Öffnen und Anzeigen geschriebener Dateien. |
| 4 | * |
| 5 | * **Der Anlass.** Alle Druckausgaben und die Sicherung endeten bis 0.22.0 mit |
| 6 | * einem reinen Textsatz samt Pfad. Wer die eben erzeugte Fragenliste drucken |
| 7 | * oder die Sicherung auf einen Stick ziehen wollte, musste den Pfad ablesen |
| 8 | * und im Explorer selbst hinnavigieren. |
| 9 | * |
| 10 | * **Was hier vor allem geprüft wird**, ist die Wache: `shell.openPath` |
| 11 | * überlässt dem Betriebssystem, womit eine Datei geöffnet wird. Käme der Pfad |
| 12 | * aus dem Renderer, wäre das ein Weg, beliebige Dateien starten zu lassen – |
| 13 | * dieselbe Überlegung, aus der die Sicherung nur Kennungen und nie Pfade über |
| 14 | * die Brücke schickt. |
| 15 | */ |
| 16 | |
| 17 | import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; |
| 18 | |
| 19 | const geoeffnet: string[] = []; |
| 20 | const gezeigt: string[] = []; |
| 21 | let oeffnenFehler = ''; |
| 22 | |
| 23 | vi.mock('electron', () => ({ |
| 24 | shell: { |
| 25 | openPath: (pfad: string): Promise<string> => { |
| 26 | geoeffnet.push(pfad); |
| 27 | return Promise.resolve(oeffnenFehler); |
| 28 | }, |
| 29 | showItemInFolder: (pfad: string): void => { |
| 30 | gezeigt.push(pfad); |
| 31 | }, |
| 32 | }, |
| 33 | })); |
| 34 | |
| 35 | const { dateiZeigen, geschriebenMerken, geschriebeneVergessen } = |
| 36 | await import('../src/main/dateizugriff'); |
| 37 | |
| 38 | beforeEach(() => { |
| 39 | geoeffnet.length = 0; |
| 40 | gezeigt.length = 0; |
| 41 | oeffnenFehler = ''; |
| 42 | geschriebeneVergessen(); |
| 43 | }); |
| 44 | |
| 45 | afterEach(() => { |
| 46 | geschriebeneVergessen(); |
| 47 | }); |
| 48 | |
| 49 | describe('Nur, was diese Anwendung selbst geschrieben hat', () => { |
| 50 | it('öffnet eine gemerkte Datei', async () => { |
| 51 | const kennung = geschriebenMerken('C:/Users/Erika/Dokumente/Lernbericht.pdf'); |
| 52 | |
| 53 | await expect(dateiZeigen(kennung, 'oeffnen')).resolves.toBe(true); |
| 54 | expect(geoeffnet).toEqual(['C:/Users/Erika/Dokumente/Lernbericht.pdf']); |
| 55 | }); |
| 56 | |
| 57 | it('zeigt eine gemerkte Datei im Ordner', async () => { |
| 58 | const kennung = geschriebenMerken('C:/Users/Erika/Dokumente/Sicherung.wsklernstand'); |
| 59 | |
| 60 | await expect(dateiZeigen(kennung, 'ordner')).resolves.toBe(true); |
| 61 | expect(gezeigt).toEqual(['C:/Users/Erika/Dokumente/Sicherung.wsklernstand']); |
| 62 | }); |
| 63 | |
| 64 | it('öffnet nichts bei einer unbekannten Kennung', async () => { |
| 65 | /* Der eigentliche Zweck der Merkliste: Eine erfundene Kennung darf |
| 66 | nirgendwo hinführen. */ |
| 67 | await expect(dateiZeigen('datei-999', 'oeffnen')).resolves.toBe(false); |
| 68 | expect(geoeffnet).toEqual([]); |
| 69 | }); |
| 70 | |
| 71 | it('nimmt keinen Pfad entgegen, auch wenn einer geschickt wird', async () => { |
| 72 | /* Der Kanal nimmt Kennungen. Ein Pfad ist keine – und wird deshalb wie |
| 73 | jede andere unbekannte Zeichenkette abgewiesen. */ |
| 74 | geschriebenMerken('C:/Users/Erika/Dokumente/Lernbericht.pdf'); |
| 75 | |
| 76 | await expect(dateiZeigen('C:/Windows/System32/cmd.exe', 'oeffnen')).resolves.toBe(false); |
| 77 | await expect(dateiZeigen('C:/Users/Erika/Dokumente/Lernbericht.pdf', 'oeffnen')).resolves.toBe( |
| 78 | false, |
| 79 | ); |
| 80 | expect(geoeffnet).toEqual([]); |
| 81 | }); |
| 82 | |
| 83 | it('weist alles ab, was keine Zeichenkette ist', async () => { |
| 84 | for (const unfug of [null, undefined, 42, {}, []]) { |
| 85 | await expect(dateiZeigen(unfug, 'oeffnen')).resolves.toBe(false); |
| 86 | } |
| 87 | expect(geoeffnet).toEqual([]); |
| 88 | }); |
| 89 | |
| 90 | it('vergibt für jede Datei eine eigene Kennung', async () => { |
| 91 | const a = geschriebenMerken('C:/a.pdf'); |
| 92 | const b = geschriebenMerken('C:/b.pdf'); |
| 93 | |
| 94 | expect(a).not.toBe(b); |
| 95 | await dateiZeigen(a, 'oeffnen'); |
| 96 | expect(geoeffnet).toEqual(['C:/a.pdf']); |
| 97 | }); |
| 98 | |
| 99 | it('meldet, wenn das System die Datei nicht öffnen konnte', async () => { |
| 100 | /* Etwa weil sie inzwischen verschoben wurde. Die Oberfläche sagt das |
| 101 | dann, statt so zu tun, als sei etwas geschehen. */ |
| 102 | const kennung = geschriebenMerken('C:/weg.pdf'); |
| 103 | oeffnenFehler = 'Datei nicht gefunden'; |
| 104 | |
| 105 | await expect(dateiZeigen(kennung, 'oeffnen')).resolves.toBe(false); |
| 106 | }); |
| 107 | |
| 108 | it('vergisst alles nach dem Zurücksetzen', async () => { |
| 109 | /* Die Liste lebt nur im Arbeitsspeicher – nach einem Neustart führt ein |
| 110 | alter Verweis nirgendwohin, und das ist richtig so. */ |
| 111 | const kennung = geschriebenMerken('C:/a.pdf'); |
| 112 | geschriebeneVergessen(); |
| 113 | |
| 114 | await expect(dateiZeigen(kennung, 'oeffnen')).resolves.toBe(false); |
| 115 | }); |
| 116 | }); |