test: add board and postgres safety net
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import pg from 'pg'
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
|
||||
import { runMigrations } from './migrations.js'
|
||||
|
||||
const { Client } = pg
|
||||
const baseDatabaseUrl = process.env.TEST_DATABASE_URL
|
||||
const suite = baseDatabaseUrl ? describe : describe.skip
|
||||
const databaseName = `osint_test_${process.pid}_${Date.now()}`
|
||||
let adminClient: InstanceType<typeof Client>
|
||||
let testDatabaseUrl = ''
|
||||
|
||||
suite('PostgreSQL migrations', () => {
|
||||
beforeAll(async () => {
|
||||
const adminUrl = new URL(baseDatabaseUrl!)
|
||||
adminUrl.pathname = '/postgres'
|
||||
adminClient = new Client({ connectionString: adminUrl.toString() })
|
||||
await adminClient.connect()
|
||||
await adminClient.query(`CREATE DATABASE "${databaseName}"`)
|
||||
const testUrl = new URL(baseDatabaseUrl!)
|
||||
testUrl.pathname = `/${databaseName}`
|
||||
testDatabaseUrl = testUrl.toString()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
if (!adminClient) return
|
||||
await adminClient.query('SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1', [databaseName])
|
||||
await adminClient.query(`DROP DATABASE IF EXISTS "${databaseName}"`)
|
||||
await adminClient.end()
|
||||
})
|
||||
|
||||
it('applies every migration transactionally and is idempotent', async () => {
|
||||
const migrationsDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'migrations')
|
||||
const firstRun: string[] = []
|
||||
await runMigrations(testDatabaseUrl, migrationsDir, message => firstRun.push(message))
|
||||
expect(firstRun.filter(message => message.startsWith('apply '))).toHaveLength(5)
|
||||
|
||||
const client = new Client({ connectionString: testDatabaseUrl })
|
||||
await client.connect()
|
||||
const tables = await client.query<{ table_name: string }>(`SELECT table_name FROM information_schema.tables WHERE table_schema = 'osint'`)
|
||||
const tableNames = tables.rows.map(row => row.table_name)
|
||||
expect(tableNames).toEqual(expect.arrayContaining(['levels', 'widgets', 'widget_relations', 'playthroughs', 'assets', 'schema_migrations']))
|
||||
const ledger = await client.query<{ count: string }>('SELECT COUNT(*)::text AS count FROM osint.schema_migrations')
|
||||
expect(ledger.rows[0].count).toBe('5')
|
||||
await client.end()
|
||||
|
||||
const secondRun: string[] = []
|
||||
await runMigrations(testDatabaseUrl, migrationsDir, message => secondRun.push(message))
|
||||
expect(secondRun.filter(message => message.startsWith('skip '))).toHaveLength(5)
|
||||
expect(secondRun.some(message => message.startsWith('apply '))).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user