test: add jest test suite with controller specs and mocks
- 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
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user