import { execFileSync } from "node:child_process"; import pg from "pg"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { migrieren } from "@/betrieb/migrieren"; import { datenbankVerfuegbar } from "./helpers/db"; const NAME = "proxdeploy_migtest"; describe.runIf(datenbankVerfuegbar)("Migrationen im Betrieb (ohne Prisma-CLI)", () => { const basis = new URL(process.env["TEST_DATABASE_URL"]!); const ziel = new URL(basis); ziel.pathname = `/${NAME}`; const verwaltung = async (sql: string) => { const c = new pg.Client({ connectionString: basis.href }); await c.connect(); try { await c.query(sql); } finally { await c.end(); } }; beforeAll(async () => { await verwaltung(`DROP DATABASE IF EXISTS ${NAME} WITH (FORCE)`); await verwaltung(`CREATE DATABASE ${NAME}`); }); afterAll(async () => { await verwaltung(`DROP DATABASE IF EXISTS ${NAME} WITH (FORCE)`); }); it("spielt alle ein, beim zweiten Mal nichts – und Prisma hält den Stand für aktuell", async () => { const erstes = await migrieren(ziel.href, "prisma/migrations"); expect(erstes.eingespielt.length).toBeGreaterThan(5); expect(erstes.eingespielt[0]).toMatch(/_grundgeruest$/); expect(await migrieren(ziel.href, "prisma/migrations")).toEqual({ eingespielt: [], vorhanden: erstes.eingespielt.length, }); const status = execFileSync("pnpm", ["exec", "prisma", "migrate", "status"], { env: { ...process.env, DATABASE_URL: ziel.href }, encoding: "utf8", }); expect(status).toMatch(/Database schema is up to date/); // Auch die Regeln aus den Migrationen (Trigger) sind da: das Audit-Log ist nur anhängbar. const c = new pg.Client({ connectionString: ziel.href }); await c.connect(); try { await c.query(`INSERT INTO "Protokoll" (quelle, aktion) VALUES ('SYSTEM', 'Test')`); await expect(c.query(`DELETE FROM "Protokoll"`)).rejects.toThrow(); } finally { await c.end(); } }); it("verweigert, wenn eine eingespielte Migration verändert wurde", async () => { const c = new pg.Client({ connectionString: ziel.href }); await c.connect(); await c.query(`UPDATE "_prisma_migrations" SET checksum = 'x' WHERE migration_name LIKE '%_server'`); await c.end(); await expect(migrieren(ziel.href, "prisma/migrations")).rejects.toThrow(/verändert/); }); });