Files
betreuungs-cockpit/tests/speicher-pruefung.test.ts
T
2026-09-01 16:39:59 +02:00

106 lines
3.7 KiB
TypeScript

import { mkdtemp, readdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
/**
* Die Bereitschaftsprüfung der Dateiablage.
*
* Bis v1.12.0 fiel eine kaputte Speicherkonfiguration erst auf, wenn
* jemand ein Dokument ablegen wollte. Auf dem Livesystem waren das
* mehrere Wochen nach der Installation — und dann mitten in der Arbeit,
* mit einer Meldung, die nichts sagte.
*
* Die Prüfung schreibt eine winzige Datei, liest sie zurück und räumt sie
* weg. Sie beantwortet damit drei Fragen auf einmal: erreichbar,
* Ablagebereich vorhanden, Schreibrecht da.
*/
let verzeichnis = ''
beforeEach(async () => {
verzeichnis = await mkdtemp(join(tmpdir(), 'bc-pruefung-'))
process.env.SPEICHER_TREIBER = 'datei'
process.env.DATEI_SPEICHER_PFAD = verzeichnis
vi.resetModules()
})
afterEach(async () => {
await rm(verzeichnis, { recursive: true, force: true })
delete process.env.SPEICHER_TREIBER
delete process.env.DATEI_SPEICHER_PFAD
vi.restoreAllMocks()
})
describe('Bereitschaftsprüfung', () => {
it('meldet eine benutzbare Ablage', async () => {
const { speicherPruefen } = await import('@/lib/speicher/pruefung')
const zustand = await speicherPruefen()
expect(zustand.ok).toBe(true)
expect(zustand.treiber).toBe('datei')
})
it('lässt nichts liegen', async () => {
// Eine Pruefung, die bei jedem Aufruf eine Datei zuruecklaesst, waere
// nach einem Jahr Betrieb ein Verzeichnis voller Muell.
const { speicherPruefen } = await import('@/lib/speicher/pruefung')
await speicherPruefen()
await speicherPruefen()
await speicherPruefen()
const inhalt = await readdir(join(verzeichnis, 'pruefung')).catch(() => [])
expect(inhalt).toEqual([])
})
it('meldet einen Fehler, statt zu werfen', async () => {
// Der Aufrufer ist die Gesundheitsauskunft. Wirft die Pruefung, ist
// die Auskunft weg - und mit ihr die Erklaerung.
// Eine Datei als Ablageverzeichnis: Das Anlegen des Unterordners
// scheitert dann zuverlaessig und auf jedem System.
const alsDatei = join(verzeichnis, 'keine-ablage')
await writeFile(alsDatei, 'ich bin eine Datei')
process.env.DATEI_SPEICHER_PFAD = alsDatei
const { speicherPruefen } = await import('@/lib/speicher/pruefung')
const zustand = await speicherPruefen()
expect(zustand.ok).toBe(false)
if (!zustand.ok) expect(zustand.meldung.length).toBeGreaterThan(10)
})
})
describe('Gemerkter Zustand', () => {
it('prüft nicht bei jedem Aufruf neu', async () => {
// Der Healthcheck fragt alle 30 Sekunden. Ohne Schonfrist schriebe er
// ebenso oft eine Probedatei in den Objektspeicher.
const modul = await import('@/lib/speicher/pruefung')
modul.zustandVergessen()
const erste = await modul.speicherZustand()
const zweite = await modul.speicherZustand()
expect(zweite).toBe(erste)
})
it('meldet denselben Zustand nicht wieder und wieder', async () => {
const protokoll = vi.spyOn(console, 'log').mockImplementation(() => {})
const modul = await import('@/lib/speicher/pruefung')
modul.zustandVergessen()
await modul.speicherZustand()
// Wie nach fuenf Minuten: neu pruefen, aber das Meldegedaechtnis bleibt.
modul.schonfristUeberspringen()
await modul.speicherZustand()
// Zweimal geprueft, aber nur die erste Meldung - sonst stuende alle
// fuenf Minuten dieselbe Zeile im Log und niemand liest sie mehr.
const speicherzeilen = protokoll.mock.calls.filter((aufruf) =>
String(aufruf[0]).startsWith('[speicher]'),
)
expect(speicherzeilen).toHaveLength(1)
})
})