Three test files covering the Phase 1 invariants: - derivePulseStatus: draft/closed are sticky; open auto-closes by date. - vote UNIQUE(pulse_id, user_id): castVote (OR IGNORE) keeps the first vote silently, a raw second INSERT raises a constraint error, and uniqueness is per-pulse (same user on a different pulse is fine). - homeRouteForRole: cab/fenja → /pulse, pilot → null (render existing home). tests/setup.ts opens BIFROST_DB_PATH=':memory:' and applies all migrations before tests run, so the in-memory DB has the live schema. Each vitest fork gets its own globalThis → its own fresh in-memory DB. The homeRouteForRole helper extraction makes the / role-redirect testable without booting Astro. Step 6 will use it from /index.astro. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
21 lines
901 B
TypeScript
21 lines
901 B
TypeScript
// Test setup: opens an in-memory SQLite database, applies all migrations.
|
|
// Each vitest worker fork gets its own globalThis, so each test file gets a
|
|
// fresh DB. db.ts reads BIFROST_DB_PATH at import time, so this must run first.
|
|
|
|
process.env.BIFROST_DB_PATH = ':memory:';
|
|
|
|
import { readFileSync, readdirSync } from 'fs';
|
|
import { join } from 'path';
|
|
import type Database from 'better-sqlite3';
|
|
|
|
// Importing db.ts triggers the singleton against ':memory:'.
|
|
await import('../src/lib/db.js');
|
|
|
|
const db = (globalThis as typeof globalThis & { __bifrost_db?: Database.Database }).__bifrost_db;
|
|
if (!db) throw new Error('db singleton did not initialise against :memory:');
|
|
|
|
const migrationsDir = join(process.cwd(), 'migrations');
|
|
const files = readdirSync(migrationsDir).filter(f => f.endsWith('.sql')).sort();
|
|
for (const file of files) {
|
|
db.exec(readFileSync(join(migrationsDir, file), 'utf8'));
|
|
}
|