Skip to content

Commit

Permalink
fix: Store all Response examples by name (#1571)
Browse files Browse the repository at this point in the history
* Store all Response examples by name

Allow use multiple times the @response decorator with the same status and different examples.

* type Record

* reanme responseExamplesByName

* test multiple response same status code
  • Loading branch information
MiguelSavignano authored Mar 17, 2024
1 parent 8f34b1f commit 8c8b3b6
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 8 deletions.
5 changes: 3 additions & 2 deletions packages/cli/src/metadataGeneration/methodGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,18 @@ export class MethodGenerator {
}

private getMethodResponses(): Tsoa.Response[] {
const responseExamplesByName: Record<string, any> = {};
const decorators = this.getDecoratorsByIdentifier(this.node, 'Response');
if (!decorators || !decorators.length) {
return [];
}

return decorators.map(decorator => {
const [name, description, example, produces] = getDecoratorValues(decorator, this.current.typeChecker);

responseExamplesByName[name] = responseExamplesByName[name] ? [...responseExamplesByName[name], example] : [example];
return {
description: description || '',
examples: example === undefined ? undefined : [example],
examples: responseExamplesByName[name] || undefined,
name: name || '200',
produces: this.getProducesAdapter(produces),
schema: this.getSchemaFromDecorator(decorator, 0),
Expand Down
3 changes: 2 additions & 1 deletion tests/fixtures/controllers/methodController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ export class MethodController extends Controller {
return new ModelService().getModel();
}

@Response<ErrorResponseModel>('400', 'Bad Request')
@Response<ErrorResponseModel>('400', 'Bad Request', { status: 400, message: 'reason 1' })
@Response<ErrorResponseModel>('400', 'Bad Request', { status: 400, message: 'reason 2' })
@Response<ErrorResponseModel>('401', 'Unauthorized')
@Response<ErrorResponseModel>('default', 'Unexpected error', { status: 500, message: 'Something went wrong!' })
@Get('MultiResponse')
Expand Down
11 changes: 6 additions & 5 deletions tests/unit/swagger/definitionsGeneration/metadata.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,23 @@ describe('Metadata generation', () => {
throw new Error('Method multiResponse not defined!');
}

expect(method.responses.length).to.equal(4);
expect(method.responses.length).to.equal(5);

const badResponse = method.responses[0];
const badResponse = method.responses[1]
expect(badResponse.name).to.equal('400');
expect(badResponse.description).to.equal('Bad Request');
expect(badResponse.examples).to.deep.equal([{ status: 400, message: 'reason 1' }, { status: 400, message: 'reason 2' }]);

const unauthResponse = method.responses[1];
const unauthResponse = method.responses[2];
expect(unauthResponse.name).to.equal('401');
expect(unauthResponse.description).to.equal('Unauthorized');

const defaultResponse = method.responses[2];
const defaultResponse = method.responses[3];
expect(defaultResponse.name).to.equal('default');
expect(defaultResponse.description).to.equal('Unexpected error');
expect(defaultResponse.examples).to.deep.equal([{ status: 500, message: 'Something went wrong!' }]);

const successResponse = method.responses[3];
const successResponse = method.responses[4];
expect(successResponse.name).to.equal('200');
expect(successResponse.description).to.equal('Ok');
});
Expand Down

0 comments on commit 8c8b3b6

Please sign in to comment.