import { describe, expect, test } from "bun:test"; import { authzMigrationSql } from "../src/migrations.ts"; /** * The postgres/mysql DDL is generated but never exercised against a real * server in this repo, so it has to be asserted statically: the id column * type, the `effect` CHECK constraint (an unrecognised value must not vanish * from both the grant and deny buckets), the MySQL binary collation (so * tenant "T1" cannot match "t1" and role "admin" cannot collapse with * "Admin"), and both UNIQUE constraints, per dialect. */ describe("authzMigrationSql", () => { test("sqlite: autoincrement id, no collation, both constraints", () => { const { up, down } = authzMigrationSql("sqlite"); expect(up).toHaveLength(2); const [assignment, grant] = up; expect(assignment).toContain("id INTEGER PRIMARY KEY AUTOINCREMENT"); expect(assignment).toContain( "CONSTRAINT _wrn_authz_assignment_unique UNIQUE (subject_id, scope, role)", ); expect(assignment).not.toContain("COLLATE"); expect(grant).toContain("id INTEGER PRIMARY KEY AUTOINCREMENT"); expect(grant).toContain("effect VARCHAR(16) NOT NULL CHECK (effect IN ('allow', 'deny'))"); expect(grant).toContain( "CONSTRAINT _wrn_authz_grant_unique UNIQUE (subject_id, scope, permission)", ); expect(grant).not.toContain("COLLATE"); expect(down).toEqual([ "DROP TABLE IF EXISTS _wrn_authz_grant", "DROP TABLE IF EXISTS _wrn_authz_assignment", ]); }); test("postgres: SERIAL id, no collation, both constraints", () => { const { up } = authzMigrationSql("postgres"); const [assignment, grant] = up; expect(assignment).toContain("id SERIAL PRIMARY KEY"); expect(assignment).toContain( "CONSTRAINT _wrn_authz_assignment_unique UNIQUE (subject_id, scope, role)", ); expect(assignment).not.toContain("COLLATE"); expect(grant).toContain("id SERIAL PRIMARY KEY"); expect(grant).toContain("effect VARCHAR(16) NOT NULL CHECK (effect IN ('allow', 'deny'))"); expect(grant).toContain( "CONSTRAINT _wrn_authz_grant_unique UNIQUE (subject_id, scope, permission)", ); expect(grant).not.toContain("COLLATE"); }); test("mysql: AUTO_INCREMENT id, binary collation on identity columns, both constraints", () => { const { up } = authzMigrationSql("mysql"); const [assignment, grant] = up; expect(assignment).toContain("id INT AUTO_INCREMENT PRIMARY KEY"); expect(assignment).toContain("subject_id VARCHAR(255) COLLATE utf8mb4_bin NOT NULL"); expect(assignment).toContain("scope VARCHAR(255) COLLATE utf8mb4_bin NOT NULL DEFAULT ''"); expect(assignment).toContain("role VARCHAR(255) COLLATE utf8mb4_bin NOT NULL"); expect(assignment).toContain( "CONSTRAINT _wrn_authz_assignment_unique UNIQUE (subject_id, scope, role)", ); expect(grant).toContain("id INT AUTO_INCREMENT PRIMARY KEY"); expect(grant).toContain("subject_id VARCHAR(255) COLLATE utf8mb4_bin NOT NULL"); expect(grant).toContain("permission VARCHAR(255) COLLATE utf8mb4_bin NOT NULL"); expect(grant).toContain("effect VARCHAR(16) NOT NULL CHECK (effect IN ('allow', 'deny'))"); expect(grant).toContain( "CONSTRAINT _wrn_authz_grant_unique UNIQUE (subject_id, scope, permission)", ); }); });