mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
refactor: add Redis service to CircleCI for E2E tests
- Added Redis container to samples job in CircleCI config - Removed all mocking from E2E tests to use real Bull queue - Updated app.module.ts to support environment-based Redis config - Fixed test routes to match controller (POST /audio/transcode) - Updated jest-e2e.json with proper timeout and exit settings - Tests now perform true integration testing with real Redis
This commit is contained in:
@@ -169,8 +169,12 @@ jobs:
|
||||
working_directory: ~/nest
|
||||
docker:
|
||||
- image: cimg/node:<< pipeline.parameters.maintenance-node-version >>
|
||||
- image: redis:7-alpine
|
||||
name: redis
|
||||
environment:
|
||||
DISABLE_OPENCOLLECTIVE: 'true'
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
steps:
|
||||
- checkout
|
||||
- *restore-cache
|
||||
@@ -179,6 +183,7 @@ jobs:
|
||||
name: Build all samples
|
||||
command: npm run build:samples
|
||||
|
||||
|
||||
workflows:
|
||||
build-and-test:
|
||||
jobs:
|
||||
@@ -204,3 +209,4 @@ workflows:
|
||||
- samples:
|
||||
requires:
|
||||
- build
|
||||
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import * as request from 'supertest';
|
||||
import { AppModule } from '../../src/app.module';
|
||||
import { getQueueToken } from '@nestjs/bull';
|
||||
import { AppModule } from './../../src/app.module';
|
||||
|
||||
describe('Audio (e2e)', () => {
|
||||
describe('AudioController (e2e)', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
// Mock queue that doesn't need Redis
|
||||
const mockQueue = {
|
||||
add: jest.fn().mockResolvedValue({ id: 1 }),
|
||||
process: jest.fn(),
|
||||
on: jest.fn(),
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
})
|
||||
.overrideProvider(getQueueToken('audio'))
|
||||
.useValue(mockQueue)
|
||||
.compile();
|
||||
}).compile();
|
||||
|
||||
app = moduleFixture.createNestApplication();
|
||||
await app.init();
|
||||
@@ -30,67 +19,25 @@ describe('Audio (e2e)', () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
describe('POST /audio/transcode', () => {
|
||||
it('should accept transcode request and return 201', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
describe('/audio/transcode (POST)', () => {
|
||||
it('should queue a transcoding job and return success', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/audio/transcode')
|
||||
.expect(201);
|
||||
|
||||
expect(mockQueue.add).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should queue the job successfully', async () => {
|
||||
mockQueue.add.mockClear();
|
||||
|
||||
await request(app.getHttpServer())
|
||||
.post('/audio/transcode')
|
||||
.expect(201);
|
||||
|
||||
expect(mockQueue.add).toHaveBeenCalledWith(
|
||||
'transcode',
|
||||
expect.objectContaining({ file: expect.any(String) })
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle multiple concurrent requests', async () => {
|
||||
mockQueue.add.mockClear();
|
||||
const requests = Array.from({ length: 5 }, () =>
|
||||
request(app.getHttpServer()).post('/audio/transcode').expect(201),
|
||||
);
|
||||
|
||||
const requests = [
|
||||
request(app.getHttpServer()).post('/audio/transcode'),
|
||||
request(app.getHttpServer()).post('/audio/transcode'),
|
||||
request(app.getHttpServer()).post('/audio/transcode'),
|
||||
];
|
||||
|
||||
const responses = await Promise.all(requests);
|
||||
|
||||
responses.forEach(response => {
|
||||
expect(response.status).toBe(201);
|
||||
});
|
||||
|
||||
expect(mockQueue.add).toHaveBeenCalledTimes(3);
|
||||
await Promise.all(requests);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /audio', () => {
|
||||
it('should return 404 for GET request', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.get('/audio')
|
||||
it('should reject GET requests', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/audio/transcode')
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error Handling', () => {
|
||||
it('should handle invalid routes', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.post('/audio/invalid')
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should accept POST to transcode endpoint', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/audio/transcode');
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
{
|
||||
"moduleFileExtensions": ["js", "json", "ts"],
|
||||
"rootDir": ".",
|
||||
"testRegex": ".*\\.e2e-spec\\.ts$",
|
||||
"testEnvironment": "node",
|
||||
"testRegex": ".e2e-spec.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
"testEnvironment": "node"
|
||||
"testTimeout": 30000,
|
||||
"detectOpenHandles": true,
|
||||
"forceExit": true
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { BullModule } from '@nestjs/bull';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AudioModule } from './audio/audio.module';
|
||||
import { BullModule } from '@nestjs/bull';
|
||||
import { AudioController } from './audio/audio.controller';
|
||||
import { AudioProcessor } from './audio/audio.processor';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
BullModule.forRoot({
|
||||
redis: {
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
host: process.env.REDIS_HOST || 'localhost',
|
||||
port: parseInt(process.env.REDIS_PORT || '6379'),
|
||||
},
|
||||
}),
|
||||
AudioModule,
|
||||
BullModule.registerQueue({
|
||||
name: 'audio',
|
||||
}),
|
||||
],
|
||||
controllers: [],
|
||||
providers: [],
|
||||
controllers: [AudioController],
|
||||
providers: [AudioProcessor],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
Reference in New Issue
Block a user