this is my controller class:
@Crud({
model: {
type: InferenceFile,
},
query: {
join: {
model: {
eager: true,
},
file: {
eager: true,
},
},
},
params: {
id: {
type: 'uuid',
primary: true,
field: 'id',
},
},
})
@Controller('inference-files')
export class InferenceFilesController {
constructor(private service: InferenceFilesService) {
}
@Get('list/:algorithmId')
async getAllInferenceFiles(
@Param('algorithmId') algorithmId: number,
@Query('name') name: string,
@Query('page') page: number = 0,
@Query('size') limit: number = 1000,
) {
return await this.service.findAllByAlgorithmId(algorithmId, name, {
page,
limit,
});
}
@Get(':id')
async get(@Param('id') id: string) {
const result = await this.service.getFile(id);
result.presignedUrl = await this.service.getPresignedDownloadUrl(result);
result.presignedWordsUrl = await this.service.getPresignedWordsUrl(result);
return result;
}
@Get('status')
async getStatus(@Query('modelId') modelId: number) {
return await this.service.getStatus(modelId);
}
}
This is part of my test class where it goes wrong:
it('should return an array of inference file statuses', async () => {
// Act
let modelIdToPass = setUp.model1.id;
const { body } = await supertest
.agent(setUp.app.getHttpServer())
.get(`/inference-files/status?${modelIdToPass}`)
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200);
// Assert
expect(body).toEqual({
'test-id-2': 'FINISHED',
});
});
it('should return the inference file for the given id', async () => {
// Act
const { body } = await supertest
.agent(setUp.app.getHttpServer())
.get('/inference-files/' TestConstants.INFERENCEFILE_ID_1)
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200);
// Assert
expect(body).toEqual({
'test-id-1': 'FINISHED',
});
});
it('should return the inference file for the given algorithm id', async () => {
// Act
const { body } = await supertest
.agent(setUp.app.getHttpServer())
.get('/inference-files/list/' 9)
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200);
// Assert
expect(body).toBeDefined();
});
Al of these tests call the same endpoint: @Get(':id') But when I comment two out of the three of them out, it succeeds.. Or better yet, it calls the remaining "Get" method. I have been looking for an answer for a whole day, but no one seems to have experienced the same problem..
When I look at the documentation online, it doesn't mention anything about routing for this. I also do not wish to mock the implementation (I've seen examples of the routing with express). But that is not what I'm looking for. I wish to test the whole flow, so it needs to call (all or most of) my methods. I use a separate database for testing, so no mocking needed.
CodePudding user response:
Move the endpoint for @Get('status')
above the one for @Get(':id')
in your controller.
Because :id
comes first, it is assuming that status
is actually an id value and is therefore invoking the wrong handler.
When a request comes to your server all the routes are evaluated one at a time and the first matching route is selected to handle the request.
This is a duplicate of Error on ordering of methods in controller Nestjs and How to deal with NestJS @Get() decorator? which were both asked recently