67 lines
2.6 KiB
TypeScript
67 lines
2.6 KiB
TypeScript
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).toBe(6);
|
|
const systemKeys = systemCats.map((c: any) => c.systemKey).sort();
|
|
expect(systemKeys).toEqual(['CRY', 'HW', 'MSC', 'PWN', 'REV', 'WEB']);
|
|
|
|
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);
|
|
});
|
|
}); |