import { describe, expect, test } from 'bun:test'; import { existsSync } from 'node:fs'; import { modules } from '../db/schema'; import { cleanupMultipleTestDatabases, cleanupTestDatabase, setupMultipleTestDatabases, setupTestDatabase, setupTestDatabaseFile, } from './database'; describe('Database Test Utilities', () => { describe('setupTestDatabase', () => { test('creates in-memory database', async () => { const db = await setupTestDatabase(); expect(db).toBeDefined(); await cleanupTestDatabase(db); }); test('applies migrations', async () => { const db = await setupTestDatabase(); // Should be able to query modules table const result = await db.select().from(modules); expect(result).toEqual([]); await cleanupTestDatabase(db); }); test('creates isolated databases', async () => { const db1 = await setupTestDatabase(); const db2 = await setupTestDatabase(); // Insert into db1 await db1.insert(modules).values({ id: 'test-module', name: 'Test Module', version: '1.0.0', state: 'IMPORTED', manifestData: {}, sourcePath: '/tmp/test', importedAt: new Date(), updatedAt: new Date(), }); // db2 should be empty const result1 = await db1.select().from(modules); const result2 = await db2.select().from(modules); expect(result1).toHaveLength(1); expect(result2).toHaveLength(0); await cleanupTestDatabase(db1); await cleanupTestDatabase(db2); }); }); describe('setupTestDatabaseFile', () => { test('creates file-based database', async () => { const { db, path: dbPath, cleanup } = await setupTestDatabaseFile(); expect(db).toBeDefined(); expect(dbPath).toBeTruthy(); expect(existsSync(dbPath)).toBe(true); await cleanup(); }); test('applies migrations', async () => { const { db, cleanup } = await setupTestDatabaseFile(); // Should be able to query modules table const result = await db.select().from(modules); expect(result).toEqual([]); await cleanup(); }); test('cleanup removes database file', async () => { const { path: dbPath, cleanup } = await setupTestDatabaseFile(); expect(existsSync(dbPath)).toBe(true); await cleanup(); // Database file should be gone expect(existsSync(dbPath)).toBe(false); }); test('database path can be used by CLI', async () => { const { db, path: dbPath, cleanup } = await setupTestDatabaseFile(); // Path should be a valid file path expect(dbPath).toMatch(/\/celilo-test-.*\/test\.db$/); // Insert some data await db.insert(modules).values({ id: 'cli-test', name: 'CLI Test', version: '1.0.0', state: 'IMPORTED', manifestData: {}, sourcePath: '/tmp/cli', importedAt: new Date(), updatedAt: new Date(), }); // Data should be persisted (can be accessed by CLI) const result = await db.select().from(modules); expect(result).toHaveLength(1); await cleanup(); }); }); describe('setupMultipleTestDatabases', () => { test('creates multiple databases', async () => { const databases = await setupMultipleTestDatabases(3); expect(databases).toHaveLength(3); expect(databases[0]).toBeDefined(); expect(databases[1]).toBeDefined(); expect(databases[2]).toBeDefined(); await cleanupMultipleTestDatabases(databases); }); test('databases are isolated', async () => { const [db1, db2, db3] = await setupMultipleTestDatabases(3); // Insert different data in each await db1.insert(modules).values({ id: 'module-1', name: 'Module 1', version: '1.0.0', state: 'IMPORTED', manifestData: {}, sourcePath: '/tmp/1', importedAt: new Date(), updatedAt: new Date(), }); await db2.insert(modules).values({ id: 'module-2', name: 'Module 2', version: '1.0.0', state: 'IMPORTED', manifestData: {}, sourcePath: '/tmp/2', importedAt: new Date(), updatedAt: new Date(), }); // Verify isolation const result1 = await db1.select().from(modules); const result2 = await db2.select().from(modules); const result3 = await db3.select().from(modules); expect(result1).toHaveLength(1); expect(result1[0].id).toBe('module-1'); expect(result2).toHaveLength(1); expect(result2[0].id).toBe('module-2'); expect(result3).toHaveLength(0); await cleanupMultipleTestDatabases([db1, db2, db3]); }); }); describe('cleanupTestDatabase', () => { test('closes database', async () => { const db = await setupTestDatabase(); await cleanupTestDatabase(db); // Database should be closed (attempting to use it should fail) // Note: Testing database closure is difficult with Drizzle's lazy query builders expect(db).toBeDefined(); }); }); });