Files

53 lines
3.8 KiB
JavaScript
Raw Permalink Normal View History

const assert = require('node:assert/strict')
const fs = require('node:fs')
const crypto = require('node:crypto')
const { execFileSync } = require('node:child_process')
const schema = `fusion_migration_test_${crypto.randomBytes(6).toString('hex')}`
const migration = fs.readFileSync(`${__dirname}/../migrations/versioned/000208_agent_fusions.up.sql`, 'utf8')
const checks = []
const sql = query => execFileSync('docker', ['--context', 'colima-yawan', 'exec', '-i', 'WeKnora-postgres',
'psql', '-X', '-U', 'postgres', '-d', 'yawan_native_acceptance_20260915', '-At', '-v', 'ON_ERROR_STOP=1'],
{ input: `SET search_path TO ${schema}, public;\n${query}`, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim()
const check = (name, condition) => { assert.ok(condition, name); checks.push(name) }
const value = text => `'${JSON.stringify(text).replaceAll("'", "''")}'::jsonb`
function fixture(id, fusion, role = 'production', native = { role: 'production', sentinel: 'preserved' }) {
sql(`INSERT INTO custom_agents VALUES ('agent-${id}',10059,${value(native)},NULL);
INSERT INTO yawan_legacy_asset_mappings VALUES ('yawan-workbench',1,'agent',${id},10059,'agent-${id}',${value({ role, fusion_agent_ids: fusion })},'{}');`)
}
const run = () => sql(`BEGIN; ${migration} COMMIT;`)
try {
sql(`CREATE SCHEMA ${schema};
CREATE TABLE custom_agents (id TEXT PRIMARY KEY,tenant_id BIGINT,config JSONB,deleted_at TIMESTAMPTZ);
CREATE TABLE yawan_legacy_asset_mappings (source_system TEXT,source_organization_id BIGINT,source_kind TEXT,source_id BIGINT,target_tenant_id BIGINT,target_id TEXT,source_snapshot JSONB,native_snapshot JSONB);`)
fixture(1, [3, 2]); fixture(2, [1]); fixture(3, [])
fixture(4, [2], 'production', { role: 'production', fusion_agent_ids: [], sentinel: 'explicit-empty' })
fixture(5, [2], 'production', { role: 'qc', sentinel: 'native-duty-edited' })
run()
const data = JSON.parse(sql('SELECT jsonb_object_agg(id,config) FROM custom_agents').split('\n').at(-1))
check('ordered_direct_ids_preserved_without_recursive_cycle_expansion', JSON.stringify(data['agent-1'].fusion_agent_ids) === JSON.stringify(['agent-3', 'agent-2']) && JSON.stringify(data['agent-2'].fusion_agent_ids) === JSON.stringify(['agent-1']))
check('empty_selection_and_native_duty_edits_preserved', data['agent-4'].fusion_agent_ids.length === 0 && !('fusion_agent_ids' in data['agent-5']))
check('unrelated_configuration_preserved', data['agent-1'].sentinel === 'preserved')
sql(`UPDATE custom_agents SET config=config || '{"fusion_agent_ids":[],"sentinel":"owner-edit"}' WHERE id='agent-1';`)
const before = sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a')
run()
check('rerun_does_not_restore_user_removed_bindings', before === sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a'))
const cases = [[6, [999], 'missing-target'], [7, [2, 2], 'duplicate'], [8, [8], 'self'], [9, ['2'], 'invalid-id'], [10, [2], 'primary-wrong-role']]
for (const [id, fusions, label] of cases) {
fixture(id, fusions, label === 'primary-wrong-role' ? 'qc' : 'production')
const baseline = sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a')
let rejected = false
try { run() } catch { rejected = true }
check(`${label}_rejected_atomically`, rejected && baseline === sql('SELECT jsonb_agg(to_jsonb(a) ORDER BY id) FROM custom_agents a'))
sql(`DELETE FROM custom_agents WHERE id='agent-${id}'; DELETE FROM yawan_legacy_asset_mappings WHERE source_id=${id};`)
}
fixture(11, [2])
sql(`UPDATE yawan_legacy_asset_mappings SET source_snapshot=jsonb_set(source_snapshot,'{role}','"qc"') WHERE source_id=2;`)
let rejected = false
try { run() } catch { rejected = true }
check('nonproduction_target_rejected', rejected)
console.log(JSON.stringify({ passed: true, checks }, null, 2))
} finally {
sql(`DROP SCHEMA IF EXISTS ${schema} CASCADE;`)
}