/** * Test database setup and teardown utilities for migration tests * Updated for PostgreSQL */ import { PrismaClient } from '@prisma/client' /** * Create a Prisma client instance for testing * Uses DATABASE_URL from environment */ export function createTestPrismaClient(): PrismaClient { return new PrismaClient() } /** * Initialize test database schema * Runs prisma migrate deploy or db push */ export async function initializeTestDatabase(prisma: PrismaClient) { await prisma.$connect() } /** * Cleanup test database * Disconnects Prisma client and cleans all data */ export async function cleanupTestDatabase(prisma: PrismaClient) { try { // Delete in dependency order await prisma.aiFeedback.deleteMany() await prisma.memoryEchoInsight.deleteMany() await prisma.noteShare.deleteMany() await prisma.note.deleteMany() await prisma.label.deleteMany() await prisma.notebook.deleteMany() await prisma.userAISettings.deleteMany() await prisma.systemConfig.deleteMany() await prisma.session.deleteMany() await prisma.account.deleteMany() await prisma.verificationToken.deleteMany() await prisma.user.deleteMany() await prisma.$disconnect() } catch (error) { console.error('Error cleaning up test database:', error) } } /** * Create sample test data */ export async function createSampleNotes(prisma: PrismaClient, count: number = 10) { const notes = [] const userId = 'test-user-123' for (let i = 0; i < count; i++) { const note = await prisma.note.create({ data: { title: `Test Note ${i + 1}`, content: `This is test content for note ${i + 1}`, userId, color: `color-${i % 5}`, order: i, isPinned: i % 3 === 0, isArchived: false, type: 'text', size: i % 3 === 0 ? 'small' : 'medium' } }) notes.push(note) } return notes } /** * Create sample AI-enabled notes */ export async function createSampleAINotes(prisma: PrismaClient, count: number = 10) { const notes = [] const userId = 'test-user-ai' for (let i = 0; i < count; i++) { const note = await prisma.note.create({ data: { title: `AI Test Note ${i + 1}`, content: `This is AI test content for note ${i + 1}`, userId, color: 'default', order: i, autoGenerated: i % 2 === 0, aiProvider: i % 3 === 0 ? 'openai' : 'ollama', aiConfidence: 70 + i * 2, language: i % 2 === 0 ? 'en' : 'fr', languageConfidence: 0.85 + (i * 0.01), lastAiAnalysis: new Date() } }) notes.push(note) } return notes } /** * Measure execution time for a function */ export async function measureExecutionTime(fn: () => Promise): Promise<{ result: T; duration: number }> { const start = performance.now() const result = await fn() const end = performance.now() return { result, duration: end - start } } /** * Verify data integrity after migration */ export async function verifyDataIntegrity(prisma: PrismaClient, expectedNoteCount: number) { const noteCount = await prisma.note.count() if (noteCount !== expectedNoteCount) { throw new Error(`Data integrity check failed: Expected ${expectedNoteCount} notes, found ${noteCount}`) } return true } /** * Check if database table exists (PostgreSQL version) */ export async function verifyTableExists(prisma: PrismaClient, tableName: string): Promise { try { const result = await prisma.$queryRawUnsafe>( `SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1 )`, tableName ) return result[0]?.exists ?? false } catch (error) { return false } } /** * Check if index exists on a table (PostgreSQL version) */ export async function verifyIndexExists(prisma: PrismaClient, tableName: string, indexName: string): Promise { try { const result = await prisma.$queryRawUnsafe>( `SELECT EXISTS ( SELECT FROM pg_indexes WHERE schemaname = 'public' AND tablename = $1 AND indexname = $2 )`, tableName, indexName ) return result[0]?.exists ?? false } catch (error) { return false } } /** * Check if column exists in table (PostgreSQL version) */ export async function verifyColumnExists(prisma: PrismaClient, tableName: string, columnName: string): Promise { try { const result = await prisma.$queryRawUnsafe>( `SELECT EXISTS ( SELECT FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1 AND column_name = $2 )`, tableName, columnName ) return result[0]?.exists ?? false } catch (error) { return false } } /** * Get table schema information (PostgreSQL version) */ export async function getTableSchema(prisma: PrismaClient, tableName: string) { try { const result = await prisma.$queryRawUnsafe>( `SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1 ORDER BY ordinal_position`, tableName ) return result } catch (error) { return null } }