import { afterEach, beforeEach, expect, it, vi } from 'vitest'; import { newFixture, type Fixture } from '../helpers/fixture.js'; let fixture: Fixture; beforeEach(async () => { vi.resetModules(); fixture = await newFixture([]); }); afterEach(async () => { await fixture.cleanup(); }); it('indexes campaign cascades and beta evidence on fresh and reopened databases', async () => { const { db, closeDb } = await import('../../src/lib/server/db/index.js'); for (let pass = 0; pass < 2; pass++) { const handle = db(); for (const [query, index] of [ ['SELECT id FROM staged_file_changes WHERE deployment_file_id = 1', 'idx_staged_files_deployment_file'], ['SELECT id FROM beta_test_runs WHERE beta_id = 1 AND revision = 2', 'idx_beta_test_runs_beta_revision'] ]) { const plan = handle.prepare(`EXPLAIN QUERY PLAN ${query}`).all() as { detail: string }[]; expect(plan.some(row => row.detail.includes(index))).toBe(true); } expect(handle.pragma('foreign_key_check')).toEqual([]); closeDb(); } }); it('covers every foreign key child prefix, including lazy host and library schemas', async () => { const { db } = await import('../../src/lib/server/db/index.js'); const { ensureHostSchema } = await import('../../src/lib/server/hosts/schema.js'); const { ensureGameFileSchema } = await import('../../src/lib/server/game-files/schema.js'); const handle = db(); ensureHostSchema(handle); ensureGameFileSchema(handle); const tables = handle.prepare("SELECT name FROM sqlite_master WHERE type='table'").all() as { name: string }[]; const missing: string[] = []; for (const { name } of tables) { const foreignKeys = handle.pragma(`foreign_key_list(${name})`) as { from: string; seq: number }[]; const indexes = handle.pragma(`index_list(${name})`) as { name: string; partial: number }[]; const prefixes = indexes.filter(index => !index.partial).map(index => (handle.pragma(`index_info(${index.name})`) as { name: string }[])[0]?.name); const columns = handle.pragma(`table_info(${name})`) as { name: string; type: string; pk: number }[]; if (columns.filter(column => column.pk).length === 1) prefixes.push(columns.find(column => column.pk)!.name); for (const key of foreignKeys.filter(key => key.seq === 0)) { if (!prefixes.includes(key.from)) missing.push(`${name}.${key.from}`); } } expect(missing).toEqual([]); });