/** * Database test helper - manages test database lifecycle * * NOTE: The smartdata models use a global `db` singleton. This helper * ensures proper initialization and cleanup for tests. */ import * as plugins from '../../ts/plugins.ts'; import { testConfig } from '../test.config.ts'; // Test database instance - separate from production let testDb: plugins.smartdata.SmartdataDb | null = null; let testDbName: string = ''; let isConnected = false; // We need to patch the global db export since models reference it // This is done by re-initializing with the test config import { initDb, closeDb } from '../../ts/models/db.ts'; /** * Initialize test database with unique name per test run */ export async function setupTestDb(config?: { mongoUrl?: string; dbName?: string; }): Promise { // If already connected, reuse the connection if (isConnected && testDb) { return; } const mongoUrl = config?.mongoUrl || testConfig.mongodb.url; // Generate unique database name for this test session const uniqueId = crypto.randomUUID().slice(0, 8); testDbName = config?.dbName || `${testConfig.mongodb.name}-${uniqueId}`; // Initialize the global db singleton with test configuration testDb = await initDb(mongoUrl, testDbName); isConnected = true; } /** * Clean up test database - deletes all documents from collections * This is safer than dropping collections which causes index rebuild issues */ export async function cleanupTestDb(): Promise { if (!testDb || !isConnected) return; try { const collections = await testDb.mongoDb.listCollections().toArray(); for (const col of collections) { // Delete all documents but preserve indexes await testDb.mongoDb.collection(col.name).deleteMany({}); } } catch (error) { console.warn('[TestHelper] Error cleaning database:', error); } } /** * Teardown test database - drops database and closes connection */ export async function teardownTestDb(): Promise { if (!testDb || !isConnected) return; try { // Drop the test database await testDb.mongoDb.dropDatabase(); // Close the connection await closeDb(); testDb = null; isConnected = false; } catch (error) { console.warn('[TestHelper] Error tearing down database:', error); } } /** * Clear specific collection(s) - deletes all documents */ export async function clearCollections(...collectionNames: string[]): Promise { if (!testDb || !isConnected) return; for (const name of collectionNames) { try { await testDb.mongoDb.collection(name).deleteMany({}); } catch { // Collection may not exist, ignore } } } /** * Get the current test database name */ export function getTestDbName(): string { return testDbName; } /** * Get the database instance for direct access */ export function getTestDb(): plugins.smartdata.SmartdataDb | null { return testDb; }