11import { Expose } from 'class-transformer' ;
22import { defaultMetadataStorage } from 'class-transformer/storage' ;
3+ import { Length } from 'class-validator' ;
34import { Server as HttpServer } from 'http' ;
45import HttpStatusCodes from 'http-status-codes' ;
56import qs from 'qs' ;
67import { Get } from '../../src/decorator/Get' ;
78import { JsonController } from '../../src/decorator/JsonController' ;
89import { QueryParam } from '../../src/decorator/QueryParam' ;
9- import { createExpressServer , getMetadataArgsStorage , ResponseClassTransformOptions } from '../../src/index' ;
10+ import { createExpressServer , getMetadataArgsStorage , ResponseClassTransformOptions , RoutingControllersOptions } from '../../src/index' ;
1011import { axios } from '../utilities/axios' ;
1112import DoneCallback = jest . DoneCallback ;
1213
1314describe ( `` , ( ) => {
1415 let expressServer : HttpServer ;
15-
16+ let requestFilter : UserFilter ;
17+
1618 class UserFilter {
19+ @Length ( 5 , 15 )
1720 keyword : string ;
1821 }
1922
@@ -31,8 +34,6 @@ describe(``, () => {
3134 afterAll ( ( ) => defaultMetadataStorage . clear ( ) ) ;
3235
3336 describe ( 'no options' , ( ) => {
34- let requestFilter : UserFilter ;
35-
3637 beforeEach ( ( done : DoneCallback ) => {
3738 requestFilter = undefined ;
3839 getMetadataArgsStorage ( ) . reset ( ) ;
@@ -63,12 +64,12 @@ describe(``, () => {
6364 expect . assertions ( 4 ) ;
6465 const response = await axios . get (
6566 '/user?' +
66- qs . stringify ( {
67- filter : {
68- keyword : 'Um' ,
69- __somethingPrivate : 'blablabla' ,
70- } ,
71- } )
67+ qs . stringify ( {
68+ filter : {
69+ keyword : 'Um' ,
70+ __somethingPrivate : 'blablabla' ,
71+ } ,
72+ } )
7273 ) ;
7374 expect ( response . status ) . toEqual ( HttpStatusCodes . OK ) ;
7475 expect ( response . data ) . toEqual ( {
@@ -82,66 +83,141 @@ describe(``, () => {
8283 keyword : 'Um' ,
8384 __somethingPrivate : 'blablabla' ,
8485 } ) ;
85- } ) ;
86- } ) ; // ------ end no options
86+ } ) ; // ------ end no options
87+ } ) ;
8788
8889 describe ( 'global options' , ( ) => {
89- let requestFilter : UserFilter ;
9090
91- beforeEach ( ( done : DoneCallback ) => {
92- requestFilter = undefined ;
93- getMetadataArgsStorage ( ) . reset ( ) ;
91+ describe ( "should merge local validation options with global validation options prioritizing local" , ( ) => {
9492
95- @JsonController ( )
96- class ClassTransformUserController {
97- @Get ( '/user' )
98- getUsers ( @QueryParam ( 'filter' ) filter : UserFilter ) : any {
99- requestFilter = filter ;
100- const user = new UserModel ( ) ;
101- user . id = 1 ;
102- user . _firstName = 'Umed' ;
103- user . _lastName = 'Khudoiberdiev' ;
104- return user ;
93+ beforeEach ( ( done ) => {
94+ requestFilter = undefined ;
95+ getMetadataArgsStorage ( ) . reset ( ) ;
96+
97+ @JsonController ( )
98+ class ClassTransformUserController {
99+
100+ @Get ( "/user" )
101+ getUsers ( @QueryParam ( "filter" , { validate : { skipMissingProperties : false } } ) filter : UserFilter ) : any {
102+ requestFilter = filter ;
103+ const user = new UserModel ( ) ;
104+ user . id = 1 ;
105+ user . _firstName = "Umed" ;
106+ user . _lastName = "Khudoiberdiev" ;
107+ return user ;
108+ }
105109 }
106- }
107110
108- expressServer = createExpressServer ( {
109- validation : false ,
110- classToPlainTransformOptions : {
111- excludePrefixes : [ '_' ] ,
112- } ,
113- plainToClassTransformOptions : {
114- excludePrefixes : [ '__' ] ,
115- } ,
116- } ) . listen ( 3001 , done ) ;
117- } ) ;
111+ const options : RoutingControllersOptions = {
112+ validation : {
113+ whitelist : true ,
114+ skipMissingProperties : true
115+ }
116+ } ;
118117
119- afterEach ( ( done : DoneCallback ) => {
120- expressServer . close ( done ) ;
121- } ) ;
118+ expressServer = createExpressServer ( options ) . listen ( 3001 , done )
119+ } ) ;
122120
123- it ( 'should apply global options' , async ( ) => {
124- expect . assertions ( 4 ) ;
125- const response = await axios . get (
126- '/user?' +
121+
122+ afterEach ( done => {
123+ expressServer . close ( done )
124+ } ) ;
125+
126+ it ( `succeed` , async ( ) => {
127+ const response = await axios . get (
128+ '/user?' +
127129 qs . stringify ( {
128130 filter : {
129- keyword : 'Um' ,
131+ keyword : 'aValidKeyword' ,
132+ notKeyword : 'Um' ,
130133 __somethingPrivate : 'blablabla' ,
131134 } ,
132135 } )
133- ) ;
134- expect ( response . status ) . toEqual ( HttpStatusCodes . OK ) ;
135- expect ( response . data ) . toEqual ( {
136- id : 1 ,
137- name : 'Umed Khudoiberdiev' ,
136+ ) ;
137+ expect ( response . status ) . toEqual ( 200 ) ;
138+ expect ( requestFilter ) . toEqual ( {
139+ keyword : "aValidKeyword"
140+ } ) ;
141+ } )
142+ } ) ;
143+
144+ describe ( "should pass the valid param after validation" , ( ) => {
145+ beforeEach ( ( done ) => {
146+ requestFilter = undefined ;
147+ getMetadataArgsStorage ( ) . reset ( ) ;
148+
149+ @JsonController ( )
150+ class UserController {
151+
152+ @Get ( "/user" )
153+ getUsers ( @QueryParam ( "filter" ) filter : UserFilter ) : any {
154+ requestFilter = filter ;
155+ const user = new UserModel ( ) ;
156+ user . id = 1 ;
157+ user . _firstName = "Umed" ;
158+ user . _lastName = "Khudoiberdiev" ;
159+ return user ;
160+ }
161+ }
162+
163+ const options : RoutingControllersOptions = {
164+ validation : true
165+ } ;
166+
167+ expressServer = createExpressServer ( options ) . listen ( 3001 , done )
138168 } ) ;
139- expect ( requestFilter ) . toBeInstanceOf ( UserFilter ) ;
140- expect ( requestFilter ) . toEqual ( {
141- keyword : 'Um' ,
169+
170+ afterEach ( done => {
171+ expressServer . close ( done )
142172 } ) ;
143- } ) ;
144- } ) ; // ----- end global options
173+
174+ it ( `succeed` , async ( ) => {
175+ const response = await axios . get (
176+ '/user?' +
177+ qs . stringify ( {
178+ filter : {
179+ keyword : 'aValidKeyword' ,
180+ notKeyword : 'Um' ,
181+ __somethingPrivate : 'blablabla' ,
182+ } ,
183+ } )
184+ ) ;
185+
186+ expect ( response . status ) . toEqual ( 200 ) ;
187+ expect ( response . data ) . toMatchObject ( {
188+ id : 1 ,
189+ _firstName : "Umed" ,
190+ _lastName : "Khudoiberdiev"
191+ } ) ;
192+ expect ( requestFilter ) . toBeInstanceOf ( UserFilter ) ;
193+ expect ( requestFilter ) . toMatchObject ( {
194+ keyword : "aValidKeyword" ,
195+ __somethingPrivate : "blablabla" ,
196+ } ) ;
197+ } )
198+
199+ it ( 'should contain param name on validation failed' , async ( ) => {
200+ expect . assertions ( 2 ) ;
201+ try {
202+ await axios . get (
203+ '/user?' +
204+ qs . stringify ( {
205+ filter : {
206+ keyword : 'Um' ,
207+ __somethingPrivate : 'blablabla' ,
208+ } ,
209+ } )
210+ ) ;
211+ }
212+ catch ( error ) {
213+ expect ( error . response . status ) . toEqual ( HttpStatusCodes . BAD_REQUEST ) ;
214+ expect ( error . response . data . errors [ 0 ] . property ) . toBe ( `keyword` ) ;
215+ }
216+
217+ } ) ;
218+ } ) ; // ----- end global options
219+ } ) ;
220+
145221
146222 describe ( 'local options' , ( ) => {
147223 let requestFilter : UserFilter ;
@@ -177,12 +253,12 @@ describe(``, () => {
177253 expect . assertions ( 4 ) ;
178254 const response = await axios . get (
179255 '/user?' +
180- qs . stringify ( {
181- filter : {
182- keyword : 'Um' ,
183- __somethingPrivate : 'blablabla' ,
184- } ,
185- } )
256+ qs . stringify ( {
257+ filter : {
258+ keyword : 'Um' ,
259+ __somethingPrivate : 'blablabla' ,
260+ } ,
261+ } )
186262 ) ;
187263 expect ( response . status ) . toEqual ( HttpStatusCodes . OK ) ;
188264 expect ( response . data ) . toEqual ( {
@@ -195,4 +271,4 @@ describe(``, () => {
195271 } ) ;
196272 } ) ;
197273 } ) ; //----- end local options
198- } ) ;
274+ } ) ;
0 commit comments