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"; jest.mock("@nestjs/common", () => { const actual = jest.requireActual("@nestjs/common"); // eslint-disable-next-line @typescript-eslint/no-require-imports const log = require("debug")("test"); // eslint-disable-next-line @typescript-eslint/no-require-imports 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 { ScenarioRunLogEntity } from "../src/scenario/scenario-run-log.entity"; import { HealthController } from "../src/health/health.controller"; import { HttpExceptionFilter } from "../src/filters/http-exception.filter"; import { LoggingInterceptor } from "../src/interceptors/logging.interceptor"; import { validateAppConfig } from "../src/config/app.config"; export async function buildTestApp(): Promise { const module: TestingModule = await Test.createTestingModule({ imports: [ ConfigModule.forRoot({ isGlobal: true, ignoreEnvFile: true, validate: validateAppConfig, }), TypeOrmModule.forRoot({ type: "better-sqlite3", database: ":memory:", entities: [ SessionEntity, EnvironmentEntity, ScenarioEntity, ScenarioStepEntity, ScenarioRunEntity, ScenarioRunStepEntity, ScenarioRunLogEntity, ], 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; }