- node-pg-migrate + pg: baseline migration (extensions, app_meta) with working down - src/infrastructure/db fail-fast pool and typed query helper - docker-compose: postgres:16-alpine + redis:7-alpine with one-command up - table naming convention <module>_<table> documented in README - integration tests (6) against real PostgreSQL; strict identifier validation for test DDL after security-gate hardening round - deps justified in spec/tech.md; all gates approved; verify.sh green
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import pg from 'pg';
|
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
import { createPoolFromEnv, query } from '../pool.js';
|
|
import { getTestDbUrl, recreateDatabase, runMigrations } from './db-test-support.js';
|
|
|
|
const hasDb = Boolean(process.env.TEST_DATABASE_URL);
|
|
|
|
describe.skipIf(!hasDb)('db pool', () => {
|
|
const url = hasDb ? getTestDbUrl() : '';
|
|
let pool: pg.Pool;
|
|
|
|
beforeAll(async () => {
|
|
await recreateDatabase(url);
|
|
await runMigrations(url, 'up');
|
|
pool = createPoolFromEnv({ DATABASE_URL: url } as NodeJS.ProcessEnv);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await pool.end();
|
|
});
|
|
|
|
it('connects and runs a trivial query', async () => {
|
|
const result = await query(pool, 'SELECT 1 AS ok');
|
|
expect(result.rows[0]?.ok).toBe(1);
|
|
});
|
|
|
|
it('supports a full roundtrip on app_meta via the query helper', async () => {
|
|
await query(pool, 'INSERT INTO app_meta (key, value) VALUES ($1, $2)', ['k1', 'v1']);
|
|
const read = await query(pool, 'SELECT value FROM app_meta WHERE key = $1', ['k1']);
|
|
expect(read.rows[0]?.value).toBe('v1');
|
|
await query(pool, 'DELETE FROM app_meta WHERE key = $1', ['k1']);
|
|
const gone = await query(pool, 'SELECT value FROM app_meta WHERE key = $1', ['k1']);
|
|
expect(gone.rowCount).toBe(0);
|
|
});
|
|
|
|
it('fails fast when DATABASE_URL is missing', () => {
|
|
expect(() => createPoolFromEnv({} as NodeJS.ProcessEnv)).toThrowError(
|
|
/DATABASE_URL is required/,
|
|
);
|
|
});
|
|
});
|