import { afterEach, describe, expect, it, vi } from 'vitest'; import { holeKartenbild } from '../../electron/karte'; /** * Was der Hauptprozess als Bild durchlaesst. * * Der Inhaltstyp allein faengt nur den Dienst ab, der ehrlich meldet, was er * schickt. Ueberlastete MapProxy- und UMN-Installationen antworten mit Status * 200, `content-type: image/jpeg` und LEEREM Koerper; ein vorgeschalteter Proxy * schiebt seine HTML-Fehlerseite unter demselben Typ durch. Beides kam bisher * mit `ok: true` an der Anzeige an - als Daten-URL ohne Nutzlast beziehungsweise * als base64-kodierte Fehlerseite. * * Der Schaden steht nicht im Hauptprozess, sondern im Dialog: Eine Antwort mit * `ok: true` beendet die Wiederholung je Kachel und wird zwischengespeichert. * Erst beim Zusammensetzen faellt auf, dass daraus kein Bild wird. * * Geprueft wird deshalb, dass eine solche Antwort hier abgewiesen wird - und * dass eine echte Kachel weiterhin durchkommt. */ const echtesFetch = globalThis.fetch; afterEach(() => { globalThis.fetch = echtesFetch; vi.restoreAllMocks(); }); const NRW = 'https://www.wms.nrw.de/geobasis/wms_nw_dop?SERVICE=WMS&REQUEST=GetMap'; /** Antwort mit Statuscode 200 und frei waehlbarem Koerper und Inhaltstyp. */ function antwortMit(koerper: BodyInit, typ: string): Response { return new Response(koerper, { status: 200, headers: { 'content-type': typ } }); } const JPEG = new Uint8Array([0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43]); const PNG = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); describe('Kartenantwort mit Bild-Inhaltstyp, aber ohne Bild', () => { it('weist einen leeren Koerper ab, statt Erfolg zu melden', async () => { globalThis.fetch = vi.fn(async () => antwortMit(new Uint8Array(0), 'image/jpeg')); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(false); expect(antwort.datenUrl).toBeNull(); // Der Anwender muss erfahren, dass der Fehler beim Dienst liegt - sonst // sucht er ihn bei sich. expect(antwort.fehler).toContain('Kartendienst'); // Und keine Daten-URL ohne Nutzlast: Genau daran scheitert erst das // Zusammensetzen des Mosaiks, lange nach dem Abruf. expect(antwort.fehler).not.toContain('base64,'); }); it('weist eine HTML-Fehlerseite unter Bild-Inhaltstyp ab', async () => { globalThis.fetch = vi.fn(async () => antwortMit('503 Service Unavailable', 'image/jpeg'), ); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(false); expect(antwort.datenUrl).toBeNull(); }); it('weist ab, wenn Inhaltstyp und Bildanfang nicht zusammenpassen', async () => { // Gemeldet wird PNG, geliefert ein JPEG. Was hier durchginge, traegt den // falschen Kopf in der Daten-URL. globalThis.fetch = vi.fn(async () => antwortMit(JPEG, 'image/png')); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(false); expect(antwort.datenUrl).toBeNull(); }); it('etikettiert ein GIF nicht als JPEG', async () => { // Ein Dienst, der image/gif liefert, wurde bisher als JPEG ausgegeben - // die Zuordnung kannte nur "png oder sonst jpeg". const gif = new Uint8Array([0x47, 0x49, 0x46, 0x38, 0x39, 0x61]); globalThis.fetch = vi.fn(async () => antwortMit(gif, 'image/gif')); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(false); expect(antwort.datenUrl).toBeNull(); }); }); describe('Echte Kacheln kommen weiterhin durch', () => { it('gibt ein JPEG mit gueltiger Signatur zurueck', async () => { globalThis.fetch = vi.fn(async () => antwortMit(JPEG, 'image/jpeg')); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(true); expect(antwort.fehler).toBeNull(); expect(antwort.datenUrl?.startsWith('data:image/jpeg;base64,')).toBe(true); }); it('gibt ein PNG mit gueltiger Signatur zurueck', async () => { globalThis.fetch = vi.fn(async () => antwortMit(PNG, 'image/png')); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(true); expect(antwort.datenUrl?.startsWith('data:image/png;base64,')).toBe(true); }); it('nimmt einen Inhaltstyp mit Anhang wie "image/jpeg; charset=binary"', async () => { globalThis.fetch = vi.fn(async () => antwortMit(JPEG, 'image/jpeg; charset=binary')); const antwort = await holeKartenbild({ url: NRW }); expect(antwort.ok).toBe(true); }); });