rwadurian/backend/services/reporting-service/test/app.e2e-spec.ts

175 lines
5.4 KiB
TypeScript

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';
import { ReportPeriod } from '../src/domain/value-objects';
describe('Reporting Service (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
app.setGlobalPrefix('api/v1');
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
transformOptions: {
enableImplicitConversion: true,
},
}),
);
// TransformInterceptor and GlobalExceptionFilter are already registered in AppModule
// Don't add them again to avoid double-wrapping responses
await app.init();
});
afterAll(async () => {
await app.close();
});
describe('Health Check', () => {
it('/api/v1/health (GET) should return ok status', () => {
return request(app.getHttpServer())
.get('/api/v1/health')
.expect(200)
.expect((res) => {
// Response is wrapped by TransformInterceptor: { success: true, data: { ... }, timestamp: ... }
expect(res.body.success).toBe(true);
expect(res.body.data).toBeDefined();
expect(res.body.data.status).toBe('ok');
expect(res.body.data.service).toBe('reporting-service');
});
});
it('/api/v1/health/ready (GET) should return ready status', () => {
return request(app.getHttpServer())
.get('/api/v1/health/ready')
.expect(200)
.expect((res) => {
expect(res.body.success).toBe(true);
expect(res.body.data).toBeDefined();
expect(res.body.data.status).toBe('ready');
});
});
});
describe('Reports API', () => {
describe('GET /api/v1/reports/definitions', () => {
it('should return list of report definitions', () => {
return request(app.getHttpServer())
.get('/api/v1/reports/definitions')
.expect(200)
.expect((res) => {
expect(res.body.success).toBe(true);
expect(res.body.data).toBeDefined();
expect(Array.isArray(res.body.data)).toBe(true);
});
});
});
describe('GET /api/v1/reports/definitions/:code', () => {
it('should return 404 for non-existent report code', () => {
return request(app.getHttpServer())
.get('/api/v1/reports/definitions/NON_EXISTENT_CODE')
.expect(404)
.expect((res) => {
expect(res.body.statusCode).toBe(404);
});
});
});
describe('POST /api/v1/reports/generate', () => {
it('should validate request body', () => {
return request(app.getHttpServer())
.post('/api/v1/reports/generate')
.send({})
.expect(400);
});
it('should reject invalid report period', () => {
return request(app.getHttpServer())
.post('/api/v1/reports/generate')
.send({
reportCode: 'RPT_LEADERBOARD',
reportPeriod: 'INVALID_PERIOD',
startDate: '2024-01-01',
endDate: '2024-01-31',
})
.expect(400);
});
it('should return 404 for non-existent report code', () => {
return request(app.getHttpServer())
.post('/api/v1/reports/generate')
.send({
reportCode: 'NON_EXISTENT',
reportPeriod: ReportPeriod.DAILY,
startDate: '2024-01-01',
endDate: '2024-01-01',
})
.expect(404);
});
});
describe('GET /api/v1/reports/snapshots', () => {
it('should return empty array when no report code provided', () => {
return request(app.getHttpServer())
.get('/api/v1/reports/snapshots')
.expect(200)
.expect((res) => {
expect(res.body.success).toBe(true);
expect(res.body.data).toBeDefined();
expect(Array.isArray(res.body.data)).toBe(true);
});
});
it('should filter snapshots by report code', () => {
return request(app.getHttpServer())
.get('/api/v1/reports/snapshots')
.query({ reportCode: 'RPT_LEADERBOARD' })
.expect(200)
.expect((res) => {
expect(res.body.success).toBe(true);
expect(res.body.data).toBeDefined();
expect(Array.isArray(res.body.data)).toBe(true);
});
});
});
describe('GET /api/v1/reports/snapshots/:code/latest', () => {
it('should return 404 when no snapshots exist', () => {
return request(app.getHttpServer())
.get('/api/v1/reports/snapshots/RPT_LEADERBOARD/latest')
.expect(404);
});
});
});
describe('Export API', () => {
describe('POST /api/v1/export', () => {
it('should validate request body', () => {
return request(app.getHttpServer())
.post('/api/v1/export')
.send({})
.expect(400);
});
it('should reject invalid format', () => {
return request(app.getHttpServer())
.post('/api/v1/export')
.send({
snapshotId: '1',
format: 'INVALID_FORMAT',
})
.expect(400);
});
});
});
});