import { readFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { getTableConfig } from "drizzle-orm/pg-core"; import { describe, expect, it } from "vitest"; import { ekklesiaCoreDevicePairingRequest } from "../src/devices/index.js"; /** * A pairing request may name no module (ADR 0065): a screen on the platform's `/display/setup` * pairs as a platform display, and a module is chosen for it, if at all, when it is approved. */ const migrationsDirectory = path.join( path.dirname(path.dirname(fileURLToPath(import.meta.url))), "drizzle", ); describe("platform display pairing requests", () => { it("lets a request name no module, but never a module without its permission", () => { const config = getTableConfig(ekklesiaCoreDevicePairingRequest); for (const name of ["module_id", "permission_id"]) { expect(config.columns.find((column) => column.name === name)?.notNull, name).toBe(false); } expect(config.checks.map((check) => check.name)).toContain( "ekklesia_core_device_pairing_module_check", ); }); it("is migrated by relaxing two columns and adding the both-or-neither check, nothing else", async () => { const sql = await readFile( path.join(migrationsDirectory, "0009_platform_display_pairing.sql"), "utf8", ); const statements = sql .split("--> statement-breakpoint") .map((statement) => statement.trim()) .filter((statement) => statement.length > 0); expect(statements).toEqual([ 'ALTER TABLE "ekklesia_core_device_pairing_request" ALTER COLUMN "module_id" DROP NOT NULL;', 'ALTER TABLE "ekklesia_core_device_pairing_request" ALTER COLUMN "permission_id" DROP NOT NULL;', 'ALTER TABLE "ekklesia_core_device_pairing_request" ADD CONSTRAINT "ekklesia_core_device_pairing_module_check" CHECK (("ekklesia_core_device_pairing_request"."module_id" is null) = ("ekklesia_core_device_pairing_request"."permission_id" is null));', ]); // Existing requests, which all name a module, satisfy the new check unchanged. }); it("is a migration that destroys nothing", async () => { const metadata = JSON.parse( await readFile(path.join(migrationsDirectory, "meta", "_ekklesia.json"), "utf8"), ) as { entries: { tag: string; destructive: { mode: string } }[] }; expect(metadata.entries.find((entry) => entry.tag === "0009_platform_display_pairing")).toEqual( { destructive: { mode: "none" }, tag: "0009_platform_display_pairing" }, ); }); });