import 'reflect-metadata'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { IS_PUBLIC_KEY } from '../auth/decorators/public.decorator'; import { formatAppVersionLine } from './app-version'; import { HealthController } from './health.controller'; /** * HealthController.spec — legt die Testlage fuer den Health-Bereich aus dem * Nichts an (quick-260914-ku1, Aufgabe 1: vorher gab es keinen Spec). * * Gegenstand ist der Versionsstempel: `GET /health/version` liest * `APP_VERSION`, `APP_CHANNEL`, `APP_COMMIT`, `APP_BUILD_TIME` aus der * Laufzeit-Umgebung (gesetzt als `ENV` in der Runner-Stufe beider * Dockerfiles, befuellt vom CI-Skript `.gitea/scripts/publish-images.sh`). * Leere Zeichenketten zaehlen wie ungesetzt, weil Docker Compose unbelegte * Variablen als Leerstring weiterreicht (siehe `migrate-and-start.sh`). * * Der Controller hat keine Abhaengigkeiten und wird direkt instanziiert. */ const ALL_VARS = ['APP_VERSION', 'APP_CHANNEL', 'APP_COMMIT', 'APP_BUILD_TIME'] as const; afterEach(() => { vi.unstubAllEnvs(); }); function stubAll(value: string) { for (const name of ALL_VARS) { vi.stubEnv(name, value); } } function stubSample() { vi.stubEnv('APP_VERSION', 'v1.2.3'); vi.stubEnv('APP_CHANNEL', 'live'); vi.stubEnv('APP_COMMIT', 'abc1234'); vi.stubEnv('APP_BUILD_TIME', '2026-09-14T12:00:00Z'); } describe('HealthController — Versionsstempel (quick-260914-ku1)', () => { it('Test 1 (check): liefert status ok und einen Zeitstempel, den Date.parse versteht', () => { const controller = new HealthController(); const result = controller.check(); expect(result.status).toBe('ok'); expect(Number.isNaN(Date.parse(result.timestamp))).toBe(false); }); it('Test 2 (Vorgaben): ohne die vier Variablen liefert getVersion() dev/dev und leere Kennungen', () => { for (const name of ALL_VARS) { vi.stubEnv(name, undefined); } const controller = new HealthController(); expect(controller.getVersion()).toEqual({ name: 'tessera', version: 'dev', channel: 'dev', commit: '', buildTime: '', }); }); it('Test 3 (durchgereicht): die vier Variablen kommen woertlich an, name bleibt tessera', () => { stubSample(); const controller = new HealthController(); expect(controller.getVersion()).toEqual({ name: 'tessera', version: 'v1.2.3', channel: 'live', commit: 'abc1234', buildTime: '2026-09-14T12:00:00Z', }); }); it('Test 4 (Compose-Semantik): leere Zeichenketten zaehlen wie ungesetzt', () => { stubAll(''); const controller = new HealthController(); expect(controller.getVersion()).toEqual({ name: 'tessera', version: 'dev', channel: 'dev', commit: '', buildTime: '', }); }); it('Test 5 (formatAppVersionLine): mit Commit angehaengt, ohne Commit kein Leerzeichen am Ende', () => { stubSample(); expect(formatAppVersionLine()).toBe('Tessera API v1.2.3 (live) abc1234'); stubAll(''); expect(formatAppVersionLine()).toBe('Tessera API dev (dev)'); }); it('Test 6 (bewusst oeffentlich, T-KU1-03): getVersion und check tragen @Public()', () => { expect(Reflect.getMetadata(IS_PUBLIC_KEY, HealthController.prototype.getVersion)).toBe(true); expect(Reflect.getMetadata(IS_PUBLIC_KEY, HealthController.prototype.check)).toBe(true); }); });