Files
AfiS-Aktensystem/web/tests/neukodierung.test.ts
T
Harlekin e0b03ea336
Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
Gedankenstriche durch Bindestriche ersetzt
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die
README; an keiner Stelle Bedeutung, nur Zeichensetzung.
2026-09-04 08:54:52 +02:00

95 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @vitest-environment node
import { describe, expect, it } from 'vitest'
import sharp from 'sharp'
import { reencode } from '@/lib/files/reencode'
import { detectType } from '@/lib/files/magic'
/**
* Die Neukodierung ist die wirksamste Massnahme der Kette: ein Bild, das durch
* `sharp` gelaufen ist, besteht nur noch aus Pixeln.
*
* Diese Tests prüfen genau das - nicht, dass irgendetwas herauskommt, sondern
* dass das, was nicht Inhalt ist, **weg** ist.
*/
async function testbild(): Promise<Buffer> {
return sharp({
create: { width: 24, height: 16, channels: 3, background: { r: 200, g: 40, b: 40 } },
})
.jpeg()
.withMetadata({
exif: {
IFD0: { Copyright: 'GEHEIMER FOTOGRAF', Software: 'Kamera 9000' },
},
})
.toBuffer()
}
describe('Bilder neu kodieren', () => {
it('wirft die Metadaten weg, statt sie zu filtern', async () => {
const original = await testbild()
// Gegenprobe: das Original trägt die Daten wirklich.
expect(original.includes(Buffer.from('GEHEIMER FOTOGRAF'))).toBe(true)
const ergebnis = await reencode(new Uint8Array(original), 'image/jpeg')
expect(ergebnis.ok).toBe(true)
if (!ergebnis.ok) return
const neu = Buffer.from(ergebnis.result.content)
expect(neu.includes(Buffer.from('GEHEIMER FOTOGRAF'))).toBe(false)
expect(neu.includes(Buffer.from('Kamera 9000'))).toBe(false)
// Und es ist noch dasselbe Bild.
const info = await sharp(neu).metadata()
expect(info.width).toBe(24)
expect(info.height).toBe(16)
expect(ergebnis.result.width).toBe(24)
})
it('zerstört eine angehängte Nutzlast', async () => {
// Der klassische Trick: hinter das Bildende Daten kleben. Nach der
// Neukodierung ist davon nichts mehr da, weil nur die Pixel übernommen
// werden.
const angehaengt = Buffer.concat([
await testbild(),
Buffer.from('<?php system($_GET["c"]); ?>'),
])
const ergebnis = await reencode(new Uint8Array(angehaengt), 'image/jpeg')
expect(ergebnis.ok).toBe(true)
if (!ergebnis.ok) return
expect(Buffer.from(ergebnis.result.content).includes(Buffer.from('<?php'))).toBe(false)
})
it('erzeugt Vorschaubild und Platzhalter', async () => {
const ergebnis = await reencode(new Uint8Array(await testbild()), 'image/jpeg')
expect(ergebnis.ok).toBe(true)
if (!ergebnis.ok) return
expect(ergebnis.result.thumb).toBeDefined()
// Das Vorschaubild ist immer WebP, damit die Auslieferung es gefahrlos
// inline schicken kann.
expect(detectType(ergebnis.result.thumb!)).toEqual({ ok: true, type: 'image/webp' })
expect(ergebnis.result.blurhash).toMatch(/^[\w#$%*+,\-.:;=?@[\]^_{|}~]{6,}$/)
})
it('lehnt ab, was kein Bild ist', async () => {
const ergebnis = await reencode(new TextEncoder().encode('kein Bild'), 'image/png')
expect(ergebnis.ok).toBe(false)
})
})
describe('Text normalisieren', () => {
it('entfernt die Stückliste am Anfang', async () => {
const mitBom = new TextEncoder().encode('Hallo Welt')
const ergebnis = await reencode(mitBom, 'text/plain')
expect(ergebnis.ok).toBe(true)
if (!ergebnis.ok) return
expect(new TextDecoder().decode(ergebnis.result.content)).toBe('Hallo Welt')
})
it('lehnt ungültiges UTF-8 ab', async () => {
const ergebnis = await reencode(new Uint8Array([0xff, 0xfe, 0x41]), 'text/plain')
expect(ergebnis.ok).toBe(false)
})
})