import { Test } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { validateEnv } from '../../backend/src/config/env.schema'; import { DatabaseModule } from '../../backend/src/database/database.module'; import { DatabaseInitService } from '../../backend/src/database/database-init.service'; import { CategoryEntity } from '../../backend/src/database/entities/category.entity'; import { SettingEntity } from '../../backend/src/database/entities/setting.entity'; describe('DatabaseInitService', () => { let app: INestApplication; let init: DatabaseInitService; beforeAll(async () => { process.env.DATABASE_PATH = ':memory:'; process.env.THEMES_DIR = './themes'; process.env.FRONTEND_DIST = './frontend/dist'; const moduleRef = await Test.createTestingModule({ imports: [ ConfigModule.forRoot({ isGlobal: true, validate: validateEnv }), DatabaseModule, ], }).compile(); app = moduleRef.createNestApplication(); init = app.get(DatabaseInitService); }); afterAll(async () => { if (app) await app.close(); }); it('creates the schema and seed data on first init()', async () => { await init.init(); const ds = (init as any).dataSource; expect(ds.isInitialized).toBe(true); const tables: any[] = await ds.query("SELECT name FROM sqlite_master WHERE type='table'"); const names = tables.map((t) => t.name); expect(names).toEqual(expect.arrayContaining([ 'user', 'setting', 'category', 'challenge', 'challenge_file', 'solve', 'refresh_token', 'blog_post', ])); const categories = await ds.getRepository(CategoryEntity).find(); const systemCats = categories.filter((c: any) => c.systemKey); expect(systemCats.length).toBeGreaterThanOrEqual(6); const settings = await ds.getRepository(SettingEntity).find(); const keys = settings.map((s: any) => s.key); expect(keys).toEqual(expect.arrayContaining([ 'pageTitle', 'logo', 'welcomeMarkdown', 'themeKey', 'defaultChallengeIp', 'registrationsEnabled', 'eventStartUtc', 'eventEndUtc', ])); }); it('is idempotent — calling init() twice does not duplicate migrations or seeds', async () => { await init.init(); await init.init(); const ds = (init as any).dataSource; const categories = await ds.getRepository(CategoryEntity).find(); const systemCats = categories.filter((c: any) => c.systemKey); expect(systemCats.length).toBe(6); }); });