/** * Vitest 테스트 환경 설정 * * Miniflare를 사용하여 D1 Database를 in-memory SQLite로 시뮬레이션 */ import { readFileSync } from 'fs'; import { join } from 'path'; import { beforeAll, afterEach } from 'vitest'; declare global { function getMiniflareBindings(): { DB: D1Database; RATE_LIMIT_KV: KVNamespace; }; } let db: D1Database; beforeAll(async () => { // Miniflare 바인딩 가져오기 const bindings = getMiniflareBindings(); db = bindings.DB; // 스키마 초기화 const schemaPath = join(__dirname, '../schema.sql'); const schema = readFileSync(schemaPath, 'utf-8'); // 각 statement를 개별 실행 const statements = schema .split(';') .map(s => s.trim()) .filter(s => s.length > 0 && !s.startsWith('--')); for (const statement of statements) { await db.exec(statement); } }); afterEach(async () => { // 각 테스트 후 데이터 정리 (스키마는 유지) await db.exec('DELETE FROM deposit_transactions'); await db.exec('DELETE FROM bank_notifications'); await db.exec('DELETE FROM user_deposits'); await db.exec('DELETE FROM user_domains'); await db.exec('DELETE FROM summaries'); await db.exec('DELETE FROM message_buffer'); await db.exec('DELETE FROM users'); }); /** * 테스트용 헬퍼 함수: 사용자 생성 */ export async function createTestUser( telegramId: string, username?: string ): Promise { const bindings = getMiniflareBindings(); const result = await bindings.DB.prepare( 'INSERT INTO users (telegram_id, username) VALUES (?, ?)' ).bind(telegramId, username || null).run(); return Number(result.meta?.last_row_id || 0); } /** * 테스트용 헬퍼 함수: 은행 알림 생성 */ export async function createBankNotification( depositorName: string, amount: number ): Promise { const bindings = getMiniflareBindings(); const result = await bindings.DB.prepare( 'INSERT INTO bank_notifications (depositor_name, depositor_name_prefix, amount) VALUES (?, ?, ?)' ).bind(depositorName, depositorName.slice(0, 7), amount).run(); return Number(result.meta?.last_row_id || 0); } /** * 테스트용 헬퍼 함수: 입금 거래 생성 */ export async function createDepositTransaction( userId: number, amount: number, status: string, depositorName?: string ): Promise { const bindings = getMiniflareBindings(); const result = await bindings.DB.prepare( `INSERT INTO deposit_transactions (user_id, type, amount, status, depositor_name, depositor_name_prefix) VALUES (?, 'deposit', ?, ?, ?, ?)` ).bind( userId, amount, status, depositorName || null, depositorName ? depositorName.slice(0, 7) : null ).run(); return Number(result.meta?.last_row_id || 0); } /** * 테스트용 헬퍼 함수: DB 바인딩 가져오기 */ export function getTestDB(): D1Database { return getMiniflareBindings().DB; }