- Backend NestJS con módulos de autenticación, inventario, créditos - Frontend React con dashboard y componentes UI - Base de datos PostgreSQL con migraciones - Tests E2E configurados - Configuración de Docker y deployment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
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<TestContext> {
|
|
const moduleRef = await Test.createTestingModule({
|
|
imports: [AppModule],
|
|
})
|
|
.overrideProvider(ConfigService)
|
|
.useValue({
|
|
get: (key: string, defaultValue?: string) => {
|
|
const testConfig: Record<string, string> = {
|
|
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>(DataSource);
|
|
const jwtService = moduleRef.get<JwtService>(JwtService);
|
|
|
|
return { app, moduleRef, dataSource, jwtService };
|
|
}
|
|
|
|
export async function closeTestApp(context: TestContext): Promise<void> {
|
|
if (context.dataSource?.isInitialized) {
|
|
await context.dataSource.destroy();
|
|
}
|
|
await context.app.close();
|
|
}
|
|
|
|
export async function cleanDatabase(dataSource: DataSource): Promise<void> {
|
|
const entities = dataSource.entityMetadatas;
|
|
|
|
for (const entity of entities) {
|
|
const repository = dataSource.getRepository(entity.name);
|
|
await repository.query(`TRUNCATE TABLE "${entity.tableName}" CASCADE`);
|
|
}
|
|
}
|