import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication, ValidationPipe } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { JwtService } from '@nestjs/jwt'; import { DataSource } from 'typeorm'; import { AppModule } from '../../src/app.module'; export interface TestContext { app: INestApplication; moduleRef: TestingModule; dataSource: DataSource; jwtService: JwtService; } export async function createTestApp(): Promise { const moduleRef = await Test.createTestingModule({ imports: [AppModule], }) .overrideProvider(ConfigService) .useValue({ get: (key: string, defaultValue?: string) => { const testConfig: Record = { NODE_ENV: 'test', DATABASE_HOST: process.env.DATABASE_HOST || 'localhost', DATABASE_PORT: process.env.DATABASE_PORT || '5433', DATABASE_NAME: process.env.DATABASE_NAME || 'miinventario_test', DATABASE_USER: process.env.DATABASE_USER || 'postgres', DATABASE_PASSWORD: process.env.DATABASE_PASSWORD || 'postgres', JWT_SECRET: 'test-secret', JWT_EXPIRES_IN: '15m', JWT_REFRESH_SECRET: 'test-refresh-secret', JWT_REFRESH_EXPIRES_IN: '7d', REDIS_HOST: process.env.REDIS_HOST || 'localhost', REDIS_PORT: process.env.REDIS_PORT || '6380', S3_ENDPOINT: 'http://localhost:9002', S3_ACCESS_KEY: 'minioadmin', S3_SECRET_KEY: 'minioadmin', S3_BUCKET: 'miinventario-test', S3_REGION: 'us-east-1', }; return testConfig[key] ?? defaultValue; }, }) .compile(); const app = moduleRef.createNestApplication(); // Apply same pipes as production app.useGlobalPipes( new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, }), ); await app.init(); const dataSource = moduleRef.get(DataSource); const jwtService = moduleRef.get(JwtService); return { app, moduleRef, dataSource, jwtService }; } export async function closeTestApp(context: TestContext): Promise { if (context.dataSource?.isInitialized) { await context.dataSource.destroy(); } await context.app.close(); } export async function cleanDatabase(dataSource: DataSource): Promise { const entities = dataSource.entityMetadatas; for (const entity of entities) { const repository = dataSource.getRepository(entity.name); await repository.query(`TRUNCATE TABLE "${entity.tableName}" CASCADE`); } }