30 lines
1.8 KiB
TypeScript
30 lines
1.8 KiB
TypeScript
import { readFile } from 'node:fs/promises';
|
|
import { resolve } from 'node:path';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { databaseMigrations } from '../../server/postgres/migration-catalog';
|
|
|
|
const migrationPath = resolve(import.meta.dirname, '..', '..', 'server', 'postgres', 'migrations', '017_policy_finding_factory.sql');
|
|
|
|
describe('PostgreSQL policy finding factory migration', () => {
|
|
it('persists an idempotent factory run and policy-specific occurrences against shared definitions', async () => {
|
|
const sql = await readFile(migrationPath, 'utf8');
|
|
expect(databaseMigrations.find(migration => migration.version === '017')).toMatchObject({
|
|
version: '017', name: 'policy-finding-factory'
|
|
});
|
|
expect(sql).toContain('CREATE TABLE assessor_policy_finding_runs');
|
|
expect(sql).toContain('CREATE TABLE assessor_policy_finding_occurrences');
|
|
expect(sql).toContain('definition_id text NOT NULL REFERENCES assessor_finding_definitions(id) ON DELETE RESTRICT');
|
|
expect(sql).toContain('UNIQUE (evaluation_run_id, factory_id, factory_version)');
|
|
});
|
|
|
|
it('keeps scope and effectiveness explicitly unverified at the relational boundary', async () => {
|
|
const sql = await readFile(migrationPath, 'utf8');
|
|
expect(sql).toContain("scope_state text NOT NULL CHECK (scope_state = 'unknown')");
|
|
expect(sql).toContain("effective_state text NOT NULL CHECK (effective_state = 'not-verified')");
|
|
expect(sql).toContain("classification text NOT NULL CHECK (classification = 'confirmed_configured_deviation')");
|
|
expect(sql).toContain('finding_eligible boolean NOT NULL DEFAULT true CHECK (finding_eligible)');
|
|
expect(sql).toContain('FOREIGN KEY (evaluation_result_id, finding_eligible, classification)');
|
|
expect(sql).toContain('REFERENCES assessor_policy_evaluation_results(id, finding_eligible, classification)');
|
|
});
|
|
});
|