import assert from 'node:assert/strict' import { after, before, test } from 'node:test' import pg from 'pg' import { HttpError } from './http.ts' import { createTfvarsStore, tfvarsText, type TfvarsStore } from './tfvarsStore.ts' // The tests create a scratch database on the server the PG* variables name, connected to through the database // postgres, and drop it at the end. const database = `tfvars_store_test_${process.pid}` const admin = new pg.Client({ database: 'postgres' }) let pool: pg.Pool let store: TfvarsStore before(async () => { await admin.connect() await admin.query(`CREATE DATABASE ${database}`) pool = new pg.Pool({ database }) store = createTfvarsStore(pool) }) after(async () => { await pool?.end() await admin.query(`DROP DATABASE IF EXISTS ${database}`) await admin.end() }) const status = async (promise: Promise) => { try { await promise } catch (error) { assert.ok(error instanceof HttpError, String(error)) return error.statusCode } return 0 } test('modules are created, changed, listed and deleted', async () => { await store.modules.put({ name: 'router', root: 'router/terraform', description: 'VPN router', configuratorUrl: null }) await store.modules.put({ name: 'router', root: 'router/terraform', description: 'VPN router', configuratorUrl: 'http://localhost:7083/' }) await store.modules.put({ name: 'app', root: 'app', description: '', configuratorUrl: null }) assert.deepEqual(await store.modules.list(), [ { name: 'app', root: 'app', description: '', configuratorUrl: null }, { name: 'router', root: 'router/terraform', description: 'VPN router', configuratorUrl: 'http://localhost:7083/' }, ]) await store.modules.delete('app') assert.deepEqual((await store.modules.list()).map((module) => module.name), ['router']) assert.equal(await status(store.modules.put({ name: 'Bad', root: 'x', description: '', configuratorUrl: null })), 400) }) test('instances are created and refused for a missing module or a name in use', async () => { await store.instances.create('router', 'platform', 'terraform_remote_state') await store.instances.create('router', 'test', 'tf_router_test') assert.deepEqual((await store.instances.list('router')).map((instance) => [instance.name, instance.stateSchema]), [ ['platform', 'terraform_remote_state'], ['test', 'tf_router_test'], ]) assert.equal(await status(store.instances.create('missing', 'x', 'tf_missing_x')), 404) assert.equal(await status(store.instances.create('router', 'test', 'tf_other')), 409) assert.equal(await status(store.instances.create('router', 'other', 'tf_router_test')), 409) assert.equal(await status(store.modules.delete('router')), 409) }) test('variable files are written with their version and refused against another version', async () => { const variables = store.variables('router', 'test') const empty = await variables.read() assert.deepEqual(empty.files, []) assert.equal(empty.version, '') assert.equal(await variables.write(empty.version, { 'platform.tfvars.json': tfvarsText({ a: 1 }), 'secrets.tfvars.json': tfvarsText({ s: 'x' }) }), true) const written = await variables.read() assert.deepEqual(written.files.map((file) => [file.name, file.content.toString('utf8')]), [ ['platform.tfvars.json', tfvarsText({ a: 1 })], ['secrets.tfvars.json', tfvarsText({ s: 'x' })], ]) assert.deepEqual(written.status.map((file) => file.previous), [false, false]) assert.equal(await variables.write(empty.version, { 'platform.tfvars.json': tfvarsText({ a: 2 }) }), false) assert.equal(await variables.write(written.version, { 'platform.tfvars.json': tfvarsText({ a: 2 }) }), true) const changed = await variables.read() assert.deepEqual(changed.status.map((file) => file.previous), [true, false]) assert.notEqual(changed.version, written.version) assert.equal(await variables.remove(written.version, 'secrets.tfvars.json'), false) assert.equal(await variables.remove(changed.version, 'secrets.tfvars.json'), true) assert.deepEqual((await variables.read()).files.map((file) => file.name), ['platform.tfvars.json']) assert.deepEqual((await store.variables('router', 'platform').read()).files, []) assert.equal(await status(variables.write((await variables.read()).version, { 'notes.json': tfvarsText({}) })), 400) assert.equal(await status(store.variables('router', 'missing').write('', { 'a.tfvars.json': tfvarsText({}) })), 404) }) test('an instance is deleted with its variable files, then its module', async () => { await store.instances.delete('router', 'test') await store.instances.delete('router', 'platform') assert.deepEqual(await store.instances.list('router'), []) assert.equal((await pool.query('SELECT count(*)::int AS n FROM tf_variable_files')).rows[0].n, 0) await store.modules.delete('router') assert.deepEqual(await store.modules.list(), []) })