import { describe, expect, it } from 'vitest' import { barLength, highestRedactionLevel, markRedaction, redactForLevel, stripMarkup, stripRedacted, } from '@/lib/redaction' const BEISPIEL = 'Der Hinweis kam von [[c4]]Wachmann Perreira, Sektor B[[/c4]] am 27.08.' describe('Schwärzung im Freitext', () => { it('gibt den Inhalt frei, wenn die Stufe reicht', () => { const segmente = redactForLevel(BEISPIEL, 4) expect(segmente.every((s) => s.kind === 'text')).toBe(true) expect(segmente.map((s) => (s.kind === 'text' ? s.text : '')).join('')).toContain( 'Wachmann Perreira', ) }) it('schickt den Inhalt nicht mit, wenn die Stufe nicht reicht', () => { const segmente = redactForLevel(BEISPIEL, 1) const alsText = JSON.stringify(segmente) // Das ist der Kern: der echte Wert verlässt den Server nicht. expect(alsText).not.toContain('Perreira') expect(alsText).not.toContain('Sektor B') const geschwaerzt = segmente.find((s) => s.kind === 'redacted') expect(geschwaerzt).toMatchObject({ requiredLevel: 4 }) }) it('rundet die Balkenlänge auf ein Raster, damit sie nichts verrät', () => { // Zwei verschieden lange Namen dürfen nicht zu verschieden langen Balken // führen, sonst lässt sich aus der Länge raten. const kurz = redactForLevel('a [[c3]]Kim[[/c3]] b', 0) const laenger = redactForLevel('a [[c3]]Kim Lee[[/c3]] b', 0) const balken = (s: ReturnType) => s.find((x) => x.kind === 'redacted') as { blockLength: number } expect(balken(kurz).blockLength).toBe(balken(laenger).blockLength) expect(barLength(1)).toBe(8) expect(barLength(8)).toBe(8) expect(barLength(9)).toBe(16) }) it('behält den Text um die Schwärzung herum', () => { const segmente = redactForLevel(BEISPIEL, 0) const sichtbar = segmente.map((s) => (s.kind === 'text' ? s.text : '')).join('') expect(sichtbar).toContain('Der Hinweis kam von') expect(sichtbar).toContain('am 27.08.') }) it('kommt mit mehreren und verschachtelt wirkenden Auszeichnungen zurecht', () => { const text = '[[c2]]zwei[[/c2]] und [[c5]]fünf[[/c5]] und [[c0]]offen[[/c0]]' const segmente = redactForLevel(text, 2) const stufen = segmente.filter((s) => s.kind === 'redacted').map((s) => s.requiredLevel) expect(stufen).toEqual([5]) expect(JSON.stringify(segmente)).toContain('zwei') expect(JSON.stringify(segmente)).toContain('offen') expect(JSON.stringify(segmente)).not.toContain('fünf') }) it('nennt die höchste ausgezeichnete Stufe, ohne den Text preiszugeben', () => { expect(highestRedactionLevel(BEISPIEL)).toBe(4) expect(highestRedactionLevel('ohne Auszeichnung')).toBe(0) }) it('entfernt die Auszeichnung, behält aber den Inhalt', () => { expect(stripMarkup(BEISPIEL)).toBe( 'Der Hinweis kam von Wachmann Perreira, Sektor B am 27.08.', ) }) it('entfernt ausgezeichnete Bereiche für den Suchvektor', () => { // Muss dasselbe leisten wie strip_redactions in der Migration. const fuerIndex = stripRedacted(BEISPIEL) expect(fuerIndex).not.toContain('Perreira') expect(fuerIndex).toContain('Der Hinweis kam von') }) it('zeichnet einen markierten Bereich aus', () => { const quelle = 'Zeuge Meier war dabei' const markiert = markRedaction(quelle, 6, 11, 3) expect(markiert).toBe('Zeuge [[c3]]Meier[[/c3]] war dabei') expect(redactForLevel(markiert, 1).some((s) => s.kind === 'redacted')).toBe(true) }) })