@@ -11,6 +11,7 @@ import (
1111 "net/url"
1212 "os"
1313 "os/signal"
14+ "slices"
1415 "strings"
1516 "sync"
1617 "syscall"
@@ -22,7 +23,6 @@ import (
2223 "github.com/google/uuid"
2324 "github.com/rs/zerolog"
2425 "github.com/valyala/fasthttp"
25- "golang.org/x/exp/slices"
2626
2727 handlersAPI "github.com/wallarm/api-firewall/cmd/api-firewall/internal/handlers/api"
2828 "github.com/wallarm/api-firewall/internal/config"
@@ -613,6 +613,9 @@ func TestAPIModeBasic(t *testing.T) {
613613 // check conflicts in the Path
614614 t .Run ("testConflictsInThePath" , apifwTests .testConflictsInThePath )
615615 t .Run ("testObjectInQuery" , apifwTests .testObjectInQuery )
616+
617+ // check limited response (maxErrorsInResponse param)
618+ t .Run ("testAPIModeMissedMultipleReqParamsLimitedResponse" , apifwTests .testAPIModeMissedMultipleReqParamsLimitedResponse )
616619}
617620
618621func createForm (form map [string ]string ) (string , io.Reader , error ) {
@@ -2926,3 +2929,105 @@ func (s *APIModeServiceTests) testObjectInQuery(t *testing.T) {
29262929 // check response status code and response body
29272930 checkResponseForbiddenStatusCode (t , & reqCtx , DefaultSchemaID , []string {validator .ErrCodeRequiredQueryParameterMissed })
29282931}
2932+
2933+ func (s * APIModeServiceTests ) testAPIModeMissedMultipleReqParamsLimitedResponse (t * testing.T ) {
2934+
2935+ updatedCfg := config.APIMode {
2936+ APIFWInit : config.APIFWInit {Mode : web .APIMode },
2937+ SpecificationUpdatePeriod : 2 * time .Second ,
2938+ UnknownParametersDetection : true ,
2939+ PassOptionsRequests : false ,
2940+ MaxErrorsInResponse : 1 ,
2941+ }
2942+
2943+ handler := handlersAPI .Handlers (s .lock , & updatedCfg , s .shutdown , s .logger , s .dbSpec , nil , nil )
2944+
2945+ p , err := json .Marshal (map [string ]any {
2946+ "firstname" : "test" ,
2947+ "lastname" : "test" ,
2948+ "job" : "test" ,
2949+ 2950+ "url" : "http://wallarm.com" ,
2951+ })
2952+
2953+ if err != nil {
2954+ t .Fatal (err )
2955+ }
2956+
2957+ req := fasthttp .AcquireRequest ()
2958+ req .SetRequestURI ("/test/signup" )
2959+ req .Header .SetMethod ("POST" )
2960+ req .SetBodyStream (bytes .NewReader (p ), - 1 )
2961+ req .Header .SetContentType ("application/json" )
2962+ req .Header .Add (web .XWallarmSchemaIDHeader , fmt .Sprintf ("%d" , DefaultSchemaID ))
2963+
2964+ reqCtx := fasthttp.RequestCtx {
2965+ Request : * req ,
2966+ }
2967+
2968+ handler (& reqCtx )
2969+
2970+ t .Logf ("Name of the test: %s; request method: %s; request uri: %s; request body: %s" , t .Name (), string (reqCtx .Request .Header .Method ()), string (reqCtx .Request .RequestURI ()), string (reqCtx .Request .Body ()))
2971+ t .Logf ("Name of the test: %s; status code: %d; response body: %s" , t .Name (), reqCtx .Response .StatusCode (), string (reqCtx .Response .Body ()))
2972+
2973+ // check response status code and response body
2974+ checkResponseOkStatusCode (t , & reqCtx , DefaultSchemaID )
2975+
2976+ // Repeat request with invalid email
2977+ reqInvalidEmail , err := json .Marshal (map [string ]any {
2978+ 2979+ })
2980+
2981+ if err != nil {
2982+ t .Fatal (err )
2983+ }
2984+
2985+ req .SetBodyStream (bytes .NewReader (reqInvalidEmail ), - 1 )
2986+
2987+ missedParams := map [string ]any {
2988+ "firstname" : struct {}{},
2989+ "lastname" : struct {}{},
2990+ }
2991+
2992+ reqCtx = fasthttp.RequestCtx {
2993+ Request : * req ,
2994+ }
2995+
2996+ handler (& reqCtx )
2997+
2998+ if reqCtx .Response .StatusCode () != 200 {
2999+ t .Errorf ("Incorrect response status code. Expected: 200 and got %d" ,
3000+ reqCtx .Response .StatusCode ())
3001+ }
3002+
3003+ apifwResponse := validator.ValidationResponse {}
3004+ if err := json .Unmarshal (reqCtx .Response .Body (), & apifwResponse ); err != nil {
3005+ t .Errorf ("Error while JSON response parsing: %v" , err )
3006+ }
3007+
3008+ if len (apifwResponse .Errors ) != 1 {
3009+ t .Errorf ("wrong number of errors. Expected: 1. Got: %d" , len (apifwResponse .Errors ))
3010+ }
3011+
3012+ for _ , apifwErr := range apifwResponse .Errors {
3013+
3014+ if apifwErr .Code != validator .ErrCodeRequiredBodyParameterMissed {
3015+ t .Errorf ("Incorrect error code. Expected: %s and got %s" ,
3016+ validator .ErrCodeRequiredBodyParameterMissed , apifwErr .Code )
3017+ }
3018+
3019+ if len (apifwErr .Fields ) != 1 {
3020+ t .Errorf ("wrong number of related fields. Expected: 1. Got: %d" , len (apifwErr .Fields ))
3021+ }
3022+
3023+ if _ , ok := missedParams [apifwErr .Fields [0 ]]; ! ok {
3024+ t .Errorf ("Invalid missed field. Expected: firstname or lastname but got %s" ,
3025+ apifwErr .Fields [0 ])
3026+ }
3027+
3028+ }
3029+
3030+ t .Logf ("Name of the test: %s; request method: %s; request uri: %s; request body: %s" , t .Name (), string (reqCtx .Request .Header .Method ()), string (reqCtx .Request .RequestURI ()), string (reqCtx .Request .Body ()))
3031+ t .Logf ("Name of the test: %s; status code: %d; response body: %s" , t .Name (), reqCtx .Response .StatusCode (), string (reqCtx .Response .Body ()))
3032+
3033+ }
0 commit comments