32 lines
1.7 KiB
TypeScript
32 lines
1.7 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 root = resolve(import.meta.dirname, '..', '..', 'server', 'postgres');
|
|
|
|
describe('PostgreSQL materialized Result DB migration', () => {
|
|
it('is registered as an additive migration after reference recognition', () => {
|
|
expect(databaseMigrations.find(migration => migration.version === '024')).toMatchObject({
|
|
version: '024', name: 'result-db-materialization'
|
|
});
|
|
});
|
|
|
|
it('stores derived rows per client with cascade deletion and one state record', async () => {
|
|
const sql = await readFile(resolve(root, 'migrations', '024_result_db_materialization.sql'), 'utf8');
|
|
expect(sql).toContain('CREATE TABLE assessor_result_db_rows');
|
|
expect(sql).toContain('REFERENCES assessor_projects(id) ON DELETE CASCADE');
|
|
expect(sql).toContain('CREATE TABLE assessor_result_db_state');
|
|
expect(sql).not.toMatch(/\bDROP\b|\bALTER TABLE assessor_(?!result_db)/u);
|
|
});
|
|
|
|
it('serves every Result DB read from the stored rows and rebuilds after committed changes', async () => {
|
|
const repository = await readFile(resolve(root, 'postgres-assessor-repository.ts'), 'utf8');
|
|
expect(repository).toContain("if (query.audience !== 'internal-analysis') return this.storedResultDbRows(query.projectId);");
|
|
expect(repository).toContain("'SELECT row_data FROM assessor_result_db_rows WHERE result_projection_id = $1'");
|
|
expect(repository).toContain('if (changed(result)) this.scheduleResultDbRebuild();');
|
|
expect(repository).toContain('pg_advisory_lock($1)');
|
|
expect(repository).not.toContain('discloseResultDbProjection(');
|
|
});
|
|
});
|