- add jest, ts-jest, supertest, and related dev dependencies - add test scripts (test, test:debug, test:watch) to package.json - add jest.config.js with ts-jest transform and module name mappers - add controller specs for auth, browser, environment, mcp, scenario, session - add mocks for jsdom, playwright, and readability - add test/tsconfig.json and exclude test dir from main tsconfig
79 lines
3.0 KiB
TypeScript
79 lines
3.0 KiB
TypeScript
import { INestApplication, ValidationPipe } from '@nestjs/common';
|
|
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
import { ConfigModule } from '@nestjs/config';
|
|
import { ScheduleModule } from '@nestjs/schedule';
|
|
import debug from 'debug';
|
|
|
|
jest.mock('@nestjs/common', () => {
|
|
const actual = jest.requireActual('@nestjs/common');
|
|
const log = require('debug')('test');
|
|
const { Logger } = require('@nestjs/common/services/logger.service');
|
|
|
|
Logger.prototype.error = function (message: unknown, stack?: string, context?: string) {
|
|
const ctx = context ?? this.context ?? 'App';
|
|
log(`[${ctx}]`, 'error', message, ...(stack ? [stack] : []));
|
|
};
|
|
|
|
for (const level of ['log', 'warn', 'debug', 'verbose', 'fatal'] as const) {
|
|
Logger.prototype[level] = function (message: unknown, context?: string) {
|
|
const ctx = context ?? this.context ?? 'App';
|
|
log(`[${ctx}]`, level, message);
|
|
};
|
|
}
|
|
|
|
return actual;
|
|
});
|
|
|
|
import { AuthModule } from '../src/auth/auth.module';
|
|
import { BrowserModule } from '../src/browser/browser.module';
|
|
import { SessionModule } from '../src/session/session.module';
|
|
import { EnvironmentModule } from '../src/environment/environment.module';
|
|
import { ScenarioModule } from '../src/scenario/scenario.module';
|
|
import { McpModule } from '../src/mcp/mcp.module';
|
|
import { SessionEntity } from '../src/session/session.entity';
|
|
import { EnvironmentEntity } from '../src/environment/environment.entity';
|
|
import { ScenarioEntity } from '../src/scenario/scenario.entity';
|
|
import { ScenarioStepEntity } from '../src/scenario/scenario-step.entity';
|
|
import { ScenarioRunEntity } from '../src/scenario/scenario-run.entity';
|
|
import { ScenarioRunStepEntity } from '../src/scenario/scenario-run-step.entity';
|
|
import { HealthController } from '../src/health/health.controller';
|
|
import { HttpExceptionFilter } from '../src/filters/http-exception.filter';
|
|
import { LoggingInterceptor } from '../src/interceptors/logging.interceptor';
|
|
|
|
export async function buildTestApp(): Promise<INestApplication> {
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
imports: [
|
|
ConfigModule.forRoot({ isGlobal: true, ignoreEnvFile: true }),
|
|
TypeOrmModule.forRoot({
|
|
type: 'better-sqlite3',
|
|
database: ':memory:',
|
|
entities: [
|
|
SessionEntity,
|
|
EnvironmentEntity,
|
|
ScenarioEntity,
|
|
ScenarioStepEntity,
|
|
ScenarioRunEntity,
|
|
ScenarioRunStepEntity,
|
|
],
|
|
synchronize: true,
|
|
}),
|
|
ScheduleModule.forRoot(),
|
|
AuthModule,
|
|
BrowserModule,
|
|
SessionModule,
|
|
EnvironmentModule,
|
|
ScenarioModule,
|
|
McpModule,
|
|
],
|
|
controllers: [HealthController],
|
|
}).compile();
|
|
|
|
const app = module.createNestApplication();
|
|
app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
|
|
app.useGlobalFilters(new HttpExceptionFilter());
|
|
app.useGlobalInterceptors(new LoggingInterceptor());
|
|
await app.init();
|
|
return app;
|
|
}
|