Files
mercadodevida/project/src/infrastructure/db/tests/migrations.itest.ts
rikrdo 425fedd13e feat(F-002): database foundation with migrations and dev compose
- 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
2026-08-14 22:00:16 +02:00

38 lines
1.2 KiB
TypeScript

import pg from 'pg';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { getTestDbUrl, recreateDatabase, runMigrations, tableExists } from './db-test-support.js';
const hasDb = Boolean(process.env.TEST_DATABASE_URL);
describe.skipIf(!hasDb)('migrations', () => {
const url = hasDb ? getTestDbUrl() : '';
let pool: pg.Pool;
beforeAll(async () => {
await recreateDatabase(url);
pool = new pg.Pool({ connectionString: url, max: 2 });
});
afterAll(async () => {
await pool.end();
});
it('fresh up creates the baseline schema', async () => {
await runMigrations(url, 'up');
expect(await tableExists(pool, 'app_meta')).toBe(true);
});
it('second up is a no-op', async () => {
const before = await pool.query('SELECT count(*)::int AS n FROM pgmigrations');
await runMigrations(url, 'up');
const after = await pool.query('SELECT count(*)::int AS n FROM pgmigrations');
expect(after.rows[0]?.n).toBe(before.rows[0]?.n);
expect(await tableExists(pool, 'app_meta')).toBe(true);
});
it('down rolls back the baseline schema cleanly', async () => {
await runMigrations(url, 'down');
expect(await tableExists(pool, 'app_meta')).toBe(false);
});
});