teqo/tests/helpers/assertTestDatabase.ts
Francisco Solla 8125334401 feat(worktree): ambientes isolados por worktree — porta própria, bancos próprios, migrations no provision
pnpm worktree next [--go] [--no-migrate] agora provisiona um ambiente
determinístico por worktree: slot = parte numérica do código da Issue
(C15→15; hash sem dígitos; bump em colisão entre worktrees vivos), dev
server em 3100+slot, bancos teqo_wt<slot> / teqo_wt<slot>_test no
container compartilhado (-p teqo) com a cadeia de migrations aplicada;
escreve .env.local + .env.test.local (gitignored, marcador gerado; envs
manuais nunca sobrescritos) e copia PAYLOAD_SECRET/Blob/VAPID do main.
kill remove o worktree e dropa os bancos gerados (WITH FORCE, best-effort).

Suites leem .env.test.local depois de .env.test (vitest.setup /
playwright / db-doctor / gate-ci espelham o layering) e
assertTestDatabase aceita teqo_test ou teqo_<worktree>_test em localhost
só (fail-closed preservado). db:start/db:stop fixam -p teqo (um
container de qualquer diretório); max_connections 200→400. Sem Docker
(Cursor Cloud): degrada ao compartilhado com aviso.

Derivação pura em scripts/lib/worktree-env.mjs (unit-tested); fluxo
validado end-to-end: provision → migrate → 598/598 int no banco do
worktree → kill sem resíduo.
2026-08-08 11:33:07 -03:00

47 lines
1.9 KiB
TypeScript

/**
* Fail-closed guard for the automated test suite.
*
* The tests delete and recreate records (see seedUser.ts), so they must NEVER
* run against the production database. Rather than trying to detect prod (an
* allowlist we could forget to update), we require a LOCAL database whose name
* is `teqo_test` or `teqo_<worktree>_test` (per-worktree isolation generated
* by `pnpm worktree next`). A remote database is rejected even if its name
* looks test-like.
*/
/** `teqo_test`, `teqo_wt15_test`, … — the _test suffix is the hard contract. */
const TEST_DATABASE_NAME = /^teqo(_[a-z0-9]+)?_test$/
export function assertTestDatabase(databaseUrl: string | undefined): void {
if (!databaseUrl) {
throw new Error(
'DATABASE_URL is not set. Tests require a dedicated local test database configured in ' +
'.env.test (e.g. postgresql://teqo:teqo@localhost:5432/teqo_test).',
)
}
let parsedUrl: URL
try {
parsedUrl = new URL(databaseUrl)
} catch {
throw new Error('DATABASE_URL is not a valid PostgreSQL connection string.')
}
const databaseName = decodeURIComponent(parsedUrl.pathname.replace(/^\//, ''))
const localHosts = new Set(['localhost', '127.0.0.1', '::1', '[::1]'])
if (
parsedUrl.protocol !== 'postgresql:' ||
!TEST_DATABASE_NAME.test(databaseName) ||
!localHosts.has(parsedUrl.hostname)
) {
throw new Error(
`Refusing to run tests using protocol "${parsedUrl.protocol || '(unknown)'}" against database ` +
`"${databaseName || '(unknown)'}" on host ` +
`"${parsedUrl.hostname || '(unknown)'}". Tests require a local database named ` +
'`teqo_test` or `teqo_<worktree>_test` (per-worktree isolation from `pnpm worktree next`) ' +
'over postgresql: on localhost, 127.0.0.1, or ::1. ' +
'Configure DATABASE_URL in .env.test (e.g. postgresql://teqo:teqo@localhost:5432/teqo_test).',
)
}
}