Skip to content

Commit b0b7c54

Browse files
author
Simon Tsvilik
committed
tests: add support for union/enum types for @formfield()
1 parent 07c67b5 commit b0b7c54

File tree

3 files changed

+187
-32
lines changed

3 files changed

+187
-32
lines changed

tests/fixtures/controllers/parameterController.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Body, BodyProp, Get, Header, Path, Post, Query, Request, Route, Res, TsoaResponse, Deprecated, Queries, RequestProp, FormField } from '@tsoa/runtime';
2-
import { Gender, ParameterTestModel } from '../testModel';
2+
import { EnumNumberValue, FormTestModel, Gender, ParameterTestModel } from '../testModel';
33

44
@Route('ParameterTest')
55
export class ParameterController {
@@ -308,13 +308,17 @@ export class ParameterController {
308308
});
309309
}
310310

311-
@Get('ParameterHeaderStringType')
312-
public async headerStringType(@Header() header: string): Promise<void> {
313-
//
311+
@Get('FormData')
312+
public async formData(@FormField() data: string, @FormField() indexes: EnumNumberValue, @FormField() gender: Gender): Promise<FormTestModel> {
313+
return Promise.resolve<FormTestModel>({
314+
data,
315+
indexes,
316+
gender,
317+
});
314318
}
315319

316-
@Get('FormDataStringType')
317-
public async formData(@FormField() data: string): Promise<void> {
320+
@Get('ParameterHeaderStringType')
321+
public async headerStringType(@Header() header: string): Promise<void> {
318322
//
319323
}
320324

@@ -399,7 +403,10 @@ export class ParameterController {
399403
}
400404

401405
@Post('Inline1')
402-
public async inline1(@Body() body: { requestString: string; requestNumber: number }): Promise<{ resultString: string; responseNumber: number }> {
406+
public async inline1(@Body() body: { requestString: string; requestNumber: number }): Promise<{
407+
resultString: string;
408+
responseNumber: number;
409+
}> {
403410
return { resultString: 'a', responseNumber: 1 };
404411
}
405412
}

tests/fixtures/testModel.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,12 @@ export class ParameterTestModel {
828828
public nicknames?: string[];
829829
}
830830

831+
export class FormTestModel {
832+
public data!: string;
833+
public indexes!: EnumNumberValue;
834+
public gender!: Gender;
835+
}
836+
831837
export class ValidateCustomErrorModel {}
832838

833839
export class ValidateModel {

tests/unit/swagger/schemaDetails.spec.ts

Lines changed: 167 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,16 @@ describe('Schema details generation', () => {
714714
expect(extensionPath['x-attKey3']).to.deep.equal(null);
715715
expect(extensionPath['x-attKey4']).to.deep.equal({ test: 'testVal' });
716716
expect(extensionPath['x-attKey5']).to.deep.equal(['y0', 'y1', 123, true, null]);
717-
expect(extensionPath['x-attKey6']).to.deep.equal([{ y0: 'yt0', y1: 'yt1', y2: 123, y3: true, y4: null }, { y2: 'yt2' }]);
717+
expect(extensionPath['x-attKey6']).to.deep.equal([
718+
{
719+
y0: 'yt0',
720+
y1: 'yt1',
721+
y2: 123,
722+
y3: true,
723+
y4: null,
724+
},
725+
{ y2: 'yt2' },
726+
]);
718727
expect(extensionPath['x-attKey7']).to.deep.equal({ test: ['testVal', 123, true, null] });
719728
expect(extensionPath['x-attKey8']).to.deep.equal({ test: { testArray: ['testVal1', true, null, ['testVal2', 'testVal3', 123, true, null]] } });
720729
expect(extensionPath['x-attKey10']).to.deep.equal(['testVal1', 'testVal2', 123, true, null]);
@@ -839,7 +848,13 @@ describe('Schema details generation', () => {
839848
expect(schema).to.deep.eq({
840849
properties: {
841850
account: { $ref: '#/definitions/Account', format: undefined, description: undefined, example: undefined },
842-
defaultValue2: { type: 'string', default: 'Default Value 2', description: undefined, format: undefined, example: undefined },
851+
defaultValue2: {
852+
type: 'string',
853+
default: 'Default Value 2',
854+
description: undefined,
855+
format: undefined,
856+
example: undefined,
857+
},
843858
enumKeys: {
844859
default: undefined,
845860
description: undefined,
@@ -849,11 +864,40 @@ describe('Schema details generation', () => {
849864
type: 'string',
850865
'x-nullable': false,
851866
},
852-
keyInterface: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined, enum: ['id'], 'x-nullable': false },
853-
indexedType: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined },
854-
indexedTypeToInterface: { $ref: '#/definitions/IndexedInterface', description: undefined, format: undefined, example: undefined },
855-
indexedTypeToClass: { $ref: '#/definitions/IndexedClass', description: undefined, format: undefined, example: undefined },
856-
indexedTypeToAlias: { $ref: '#/definitions/IndexedInterface', description: undefined, format: undefined, example: undefined },
867+
keyInterface: {
868+
type: 'string',
869+
default: undefined,
870+
description: undefined,
871+
format: undefined,
872+
example: undefined,
873+
enum: ['id'],
874+
'x-nullable': false,
875+
},
876+
indexedType: {
877+
type: 'string',
878+
default: undefined,
879+
description: undefined,
880+
format: undefined,
881+
example: undefined,
882+
},
883+
indexedTypeToInterface: {
884+
$ref: '#/definitions/IndexedInterface',
885+
description: undefined,
886+
format: undefined,
887+
example: undefined,
888+
},
889+
indexedTypeToClass: {
890+
$ref: '#/definitions/IndexedClass',
891+
description: undefined,
892+
format: undefined,
893+
example: undefined,
894+
},
895+
indexedTypeToAlias: {
896+
$ref: '#/definitions/IndexedInterface',
897+
description: undefined,
898+
format: undefined,
899+
example: undefined,
900+
},
857901
indexedResponse: {
858902
$ref: '#/definitions/Record_id.string_',
859903
description: undefined,
@@ -895,7 +939,15 @@ describe('Schema details generation', () => {
895939
example: 'classPropExample',
896940
title: 'Example title',
897941
},
898-
optionalPublicStringProperty: { type: 'string', minLength: 0, maxLength: 10, default: undefined, description: undefined, format: undefined, example: undefined },
942+
optionalPublicStringProperty: {
943+
type: 'string',
944+
minLength: 0,
945+
maxLength: 10,
946+
default: undefined,
947+
description: undefined,
948+
format: undefined,
949+
example: undefined,
950+
},
899951
emailPattern: {
900952
type: 'string',
901953
default: undefined,
@@ -904,12 +956,54 @@ describe('Schema details generation', () => {
904956
pattern: '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$',
905957
example: undefined,
906958
},
907-
stringProperty: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined },
908-
deprecated1: { type: 'boolean', default: undefined, description: undefined, format: undefined, example: undefined, 'x-deprecated': true },
909-
deprecated2: { type: 'boolean', default: undefined, description: undefined, format: undefined, example: undefined, 'x-deprecated': true },
910-
extensionTest: { type: 'boolean', default: undefined, description: undefined, format: undefined, example: undefined, 'x-key-1': 'value-1', 'x-key-2': 'value-2' },
911-
extensionComment: { type: 'boolean', default: undefined, description: undefined, format: undefined, example: undefined, 'x-key-1': 'value-1', 'x-key-2': 'value-2' },
912-
stringExample: { type: 'string', default: undefined, description: undefined, format: undefined, example: 'stringValue' },
959+
stringProperty: {
960+
type: 'string',
961+
default: undefined,
962+
description: undefined,
963+
format: undefined,
964+
example: undefined,
965+
},
966+
deprecated1: {
967+
type: 'boolean',
968+
default: undefined,
969+
description: undefined,
970+
format: undefined,
971+
example: undefined,
972+
'x-deprecated': true,
973+
},
974+
deprecated2: {
975+
type: 'boolean',
976+
default: undefined,
977+
description: undefined,
978+
format: undefined,
979+
example: undefined,
980+
'x-deprecated': true,
981+
},
982+
extensionTest: {
983+
type: 'boolean',
984+
default: undefined,
985+
description: undefined,
986+
format: undefined,
987+
example: undefined,
988+
'x-key-1': 'value-1',
989+
'x-key-2': 'value-2',
990+
},
991+
extensionComment: {
992+
type: 'boolean',
993+
default: undefined,
994+
description: undefined,
995+
format: undefined,
996+
example: undefined,
997+
'x-key-1': 'value-1',
998+
'x-key-2': 'value-2',
999+
},
1000+
stringExample: {
1001+
type: 'string',
1002+
default: undefined,
1003+
description: undefined,
1004+
format: undefined,
1005+
example: 'stringValue',
1006+
},
9131007
objectExample: {
9141008
type: 'object',
9151009
default: undefined,
@@ -937,13 +1031,51 @@ describe('Schema details generation', () => {
9371031
},
9381032
required: ['label', 'id'],
9391033
},
940-
publicConstructorVar: { type: 'string', default: undefined, description: 'This is a description for publicConstructorVar', format: undefined, example: undefined },
941-
readonlyConstructorArgument: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined },
942-
optionalPublicConstructorVar: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined },
943-
deprecatedPublicConstructorVar: { type: 'boolean', default: undefined, description: undefined, format: undefined, example: undefined, 'x-deprecated': true },
944-
deprecatedPublicConstructorVar2: { type: 'boolean', default: undefined, description: undefined, format: undefined, example: undefined, 'x-deprecated': true },
1034+
publicConstructorVar: {
1035+
type: 'string',
1036+
default: undefined,
1037+
description: 'This is a description for publicConstructorVar',
1038+
format: undefined,
1039+
example: undefined,
1040+
},
1041+
readonlyConstructorArgument: {
1042+
type: 'string',
1043+
default: undefined,
1044+
description: undefined,
1045+
format: undefined,
1046+
example: undefined,
1047+
},
1048+
optionalPublicConstructorVar: {
1049+
type: 'string',
1050+
default: undefined,
1051+
description: undefined,
1052+
format: undefined,
1053+
example: undefined,
1054+
},
1055+
deprecatedPublicConstructorVar: {
1056+
type: 'boolean',
1057+
default: undefined,
1058+
description: undefined,
1059+
format: undefined,
1060+
example: undefined,
1061+
'x-deprecated': true,
1062+
},
1063+
deprecatedPublicConstructorVar2: {
1064+
type: 'boolean',
1065+
default: undefined,
1066+
description: undefined,
1067+
format: undefined,
1068+
example: undefined,
1069+
'x-deprecated': true,
1070+
},
9451071
id: { type: 'number', format: 'double', default: undefined, description: undefined, example: undefined },
946-
defaultValue1: { type: 'string', default: 'Default Value 1', description: undefined, format: undefined, example: undefined },
1072+
defaultValue1: {
1073+
type: 'string',
1074+
default: 'Default Value 1',
1075+
description: undefined,
1076+
format: undefined,
1077+
example: undefined,
1078+
},
9471079
},
9481080
required: ['account', 'enumKeys', 'publicStringProperty', 'stringProperty', 'publicConstructorVar', 'readonlyConstructorArgument', 'id'],
9491081
type: 'object',
@@ -1004,11 +1136,21 @@ describe('Schema details generation', () => {
10041136
const metadata = new MetadataGenerator('./fixtures/controllers/parameterController.ts').Generate();
10051137
const spec = new SpecGenerator2(metadata, getDefaultExtendedOptions()).GetSpec();
10061138

1007-
const method = spec.paths['/ParameterTest/FormDataStringType'].get?.parameters ?? [];
1008-
1009-
expect(method).to.have.lengthOf(1);
1010-
const queryParam = method[0];
1011-
expect(queryParam.in).to.equal('formData');
1139+
const method = spec.paths['/ParameterTest/FormData'].get?.parameters ?? [];
1140+
1141+
expect(method).to.have.lengthOf(3);
1142+
const [data, indexes, gender] = method;
1143+
1144+
expect(data.in).to.equal('formData');
1145+
expect(data.type).to.equal('string');
1146+
// Can process numeric enum
1147+
expect(indexes.in).to.equal('formData');
1148+
expect(indexes.type).to.equal('number');
1149+
expect(indexes.enum).to.deep.equal([0, 2, 5]);
1150+
// Can process string enum
1151+
expect(gender.in).to.equal('formData');
1152+
expect(gender.type).to.equal('string');
1153+
expect(gender.enum).to.deep.equal(['MALE', 'FEMALE']);
10121154
});
10131155
});
10141156

0 commit comments

Comments
 (0)