Files
Laufzettel/tests/betriebsstand.test.ts
T
florian.wildeandClaude Opus 5 7a0f875f55
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
feat(datenmodell): Schema, tagCodes und Geheimnisse (#20)
Vollständiges Datenmodell in deutscher Benennung: 20 Tabellen, 9 Aufzählungen,
eine Migration, dazu die framework-freien Helfer für tagCodes und Geheimnisse.

Regeln stehen zusätzlich in der Datenbank, nicht nur im Service: 12 CHECKs,
2 partielle Eindeutigkeitsindizes, 4 zusammengesetzte Fremdschlüssel. Die
Mandantengrenze ist damit strukturell erzwungen. Schrittergebnisse, Kommentare
und Protokolleinträge kaskadieren bewusst nicht — das Archiv ist das Gedächtnis
der Anwendung.

106 Tests, davon 42 gegen die echten Datenbankregeln.

Closes #6

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-24 23:11:58 +00:00

61 lines
2.3 KiB
TypeScript

import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
import { parse } from "yaml";
/**
* Die Datenbank im Betriebsstand ist absichtlich von aussen nicht erreichbar.
* Diese Tests halten das fest, damit ein ports:-Mapping nicht versehentlich
* zurueckkommt. Siehe docs/betrieb/inbetriebnahme.md.
*/
function compose(datei: string): Record<string, never> {
return parse(readFileSync(datei, "utf8")) as Record<string, never>;
}
describe("Betriebsstand: docker-compose.yml", () => {
const stand = compose("docker-compose.yml") as unknown as {
services: Record<string, { ports?: unknown[]; networks?: string[] }>;
networks: Record<string, { internal?: boolean } | null>;
};
it("veroeffentlicht keinen Port der Datenbank", () => {
expect(stand.services["postgres"]?.ports).toBeUndefined();
});
it("haengt die Datenbank nur in das interne Netz", () => {
expect(stand.services["postgres"]?.networks).toEqual(["intern"]);
});
it("hat das interne Netz ohne Gateway", () => {
expect(stand.networks["intern"]?.internal).toBe(true);
});
it("laesst nur den Webdienst in das externe Netz", () => {
const aussen = Object.entries(stand.services)
.filter(([, dienst]) => dienst.networks?.includes("extern"))
.map(([name]) => name);
expect(aussen).toEqual(["web"]);
});
it("bindet den Webdienst standardmaessig nur auf localhost", () => {
expect(stand.services["web"]?.ports).toEqual(["${BIND_ADDR:-127.0.0.1}:${APP_PORT:-3000}:3000"]);
});
it("bricht ohne Geheimnisse ab, statt mit Standardwerten zu starten", () => {
const roh = readFileSync("docker-compose.yml", "utf8");
expect(roh).toContain("${APP_SECRET:?");
expect(roh).toContain("${POSTGRES_PASSWORD:?");
expect(roh).toContain("${APP_URL:?");
});
});
describe("Betriebsstand: Entwicklungsdatenbank", () => {
it("bindet nur auf localhost und auf einen eigenen, umstellbaren Port", () => {
const stand = compose("docker-compose.dev.yml") as unknown as {
services: Record<string, { ports?: string[] }>;
};
// Der Standard ist 5434, weil 5432 lokal und 5433 von einem anderen Projekt
// belegt sein koennen. Umstellbar ueber DEV_DB_PORT.
expect(stand.services["postgres"]?.ports).toEqual(["127.0.0.1:${DEV_DB_PORT:-5434}:5432"]);
});
});