From a0c515f389ab8a418ad74c7465d460d59c566323 Mon Sep 17 00:00:00 2001 From: solomon Date: Mon, 14 Nov 2022 15:11:05 +0000 Subject: [PATCH 1/3] fix: optional defaults --- openapi3filter/issue639_test.go | 99 ++++++++++++++++++++++++++++++ openapi3filter/options.go | 4 ++ openapi3filter/validate_request.go | 4 +- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 openapi3filter/issue639_test.go diff --git a/openapi3filter/issue639_test.go b/openapi3filter/issue639_test.go new file mode 100644 index 000000000..4e208e345 --- /dev/null +++ b/openapi3filter/issue639_test.go @@ -0,0 +1,99 @@ +package openapi3filter + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/getkin/kin-openapi/routers/gorillamux" +) + +func TestIssue639(t *testing.T) { + loader := openapi3.NewLoader() + ctx := loader.Context + spec := ` + openapi: 3.0.0 + info: + version: 1.0.0 + title: Sample API + paths: + /items: + put: + requestBody: + content: + application/json: + schema: + properties: + testWithdefault: + default: false + type: boolean + testNoDefault: + type: boolean + type: object + responses: + '200': + description: Successful respons +`[1:] + + doc, err := loader.LoadFromData([]byte(spec)) + require.NoError(t, err) + + err = doc.Validate(ctx) + require.NoError(t, err) + + router, err := gorillamux.NewRouter(doc) + require.NoError(t, err) + + tests := []struct { + name string + options *Options + expectedDefaultVal interface{} + }{ + { + name: "no defaults are added to requests", + options: &Options{ + SkipDefaultValueSet: true, // <== false by default, true means doesn't add default values to request body + }, + expectedDefaultVal: nil, + }, + + { + name: "defaults are added to requests", + expectedDefaultVal: false, + }, + } + + for _, testcase := range tests { + t.Run(testcase.name, func(t *testing.T) { + body := "{\"testNoDefault\": true}" + httpReq, _ := http.NewRequest(http.MethodPut, "/items", strings.NewReader(body)) + httpReq.Header.Set("Content-Type", "application/json") + require.NoError(t, err) + + route, pathParams, err := router.FindRoute(httpReq) + require.NoError(t, err) + + requestValidationInput := &RequestValidationInput{ + Request: httpReq, + PathParams: pathParams, + Route: route, + Options: testcase.options, + } + err = ValidateRequest(ctx, requestValidationInput) + require.NoError(t, err) + bodyAfterValidation, err := ioutil.ReadAll(httpReq.Body) + require.NoError(t, err) + + raw := map[string]interface{}{} + err = json.Unmarshal(bodyAfterValidation, &raw) + require.NoError(t, err) + require.Equal(t, testcase.expectedDefaultVal, + raw["testWithdefault"], "default value must not be included") + }) + } +} diff --git a/openapi3filter/options.go b/openapi3filter/options.go index 1622339e2..bbe7731f4 100644 --- a/openapi3filter/options.go +++ b/openapi3filter/options.go @@ -21,4 +21,8 @@ type Options struct { // See NoopAuthenticationFunc AuthenticationFunc AuthenticationFunc + + // Indicates whether default values are set in the + // request. If true, then they are not set + SkipDefaultValueSet bool } diff --git a/openapi3filter/validate_request.go b/openapi3filter/validate_request.go index 4b0bd3413..e23a895ac 100644 --- a/openapi3filter/validate_request.go +++ b/openapi3filter/validate_request.go @@ -258,7 +258,9 @@ func ValidateRequestBody(ctx context.Context, input *RequestValidationInput, req defaultsSet := false opts := make([]openapi3.SchemaValidationOption, 0, 3) // 3 potential opts here opts = append(opts, openapi3.VisitAsRequest()) - opts = append(opts, openapi3.DefaultsSet(func() { defaultsSet = true })) + if !options.SkipDefaultValueSet { + opts = append(opts, openapi3.DefaultsSet(func() { defaultsSet = true })) + } if options.MultiError { opts = append(opts, openapi3.MultiErrors()) } From b8ec356634d3c172841f5140eb7f92755753e82f Mon Sep 17 00:00:00 2001 From: solomon Date: Mon, 14 Nov 2022 15:21:22 +0000 Subject: [PATCH 2/3] fix: optional defaults --- openapi3filter/issue639_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3filter/issue639_test.go b/openapi3filter/issue639_test.go index 4e208e345..ac1ff8754 100644 --- a/openapi3filter/issue639_test.go +++ b/openapi3filter/issue639_test.go @@ -33,7 +33,7 @@ func TestIssue639(t *testing.T) { default: false type: boolean testNoDefault: - type: boolean + type: boolean type: object responses: '200': From 4dc63d777cbea90b0c2cd091f958f2e62cc41e26 Mon Sep 17 00:00:00 2001 From: solomon Date: Thu, 17 Nov 2022 06:54:46 +0000 Subject: [PATCH 3/3] fix: request default options --- openapi3filter/issue639_test.go | 5 +++-- openapi3filter/options.go | 2 +- openapi3filter/validate_request.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/openapi3filter/issue639_test.go b/openapi3filter/issue639_test.go index ac1ff8754..2caf1bd14 100644 --- a/openapi3filter/issue639_test.go +++ b/openapi3filter/issue639_test.go @@ -57,7 +57,7 @@ func TestIssue639(t *testing.T) { { name: "no defaults are added to requests", options: &Options{ - SkipDefaultValueSet: true, // <== false by default, true means doesn't add default values to request body + SkipSettingDefaults: true, }, expectedDefaultVal: nil, }, @@ -71,7 +71,8 @@ func TestIssue639(t *testing.T) { for _, testcase := range tests { t.Run(testcase.name, func(t *testing.T) { body := "{\"testNoDefault\": true}" - httpReq, _ := http.NewRequest(http.MethodPut, "/items", strings.NewReader(body)) + httpReq, err := http.NewRequest(http.MethodPut, "/items", strings.NewReader(body)) + require.NoError(t, err) httpReq.Header.Set("Content-Type", "application/json") require.NoError(t, err) diff --git a/openapi3filter/options.go b/openapi3filter/options.go index bbe7731f4..14843dd1b 100644 --- a/openapi3filter/options.go +++ b/openapi3filter/options.go @@ -24,5 +24,5 @@ type Options struct { // Indicates whether default values are set in the // request. If true, then they are not set - SkipDefaultValueSet bool + SkipSettingDefaults bool } diff --git a/openapi3filter/validate_request.go b/openapi3filter/validate_request.go index e23a895ac..70b8e8d0a 100644 --- a/openapi3filter/validate_request.go +++ b/openapi3filter/validate_request.go @@ -258,7 +258,7 @@ func ValidateRequestBody(ctx context.Context, input *RequestValidationInput, req defaultsSet := false opts := make([]openapi3.SchemaValidationOption, 0, 3) // 3 potential opts here opts = append(opts, openapi3.VisitAsRequest()) - if !options.SkipDefaultValueSet { + if !options.SkipSettingDefaults { opts = append(opts, openapi3.DefaultsSet(func() { defaultsSet = true })) } if options.MultiError {