Skip to content

Commit 4a7405d

Browse files
authored
fix: optional defaults (#662)
1 parent 657743e commit 4a7405d

3 files changed

Lines changed: 107 additions & 1 deletion

File tree

openapi3filter/issue639_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package openapi3filter
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
"net/http"
7+
"strings"
8+
"testing"
9+
10+
"github.com/stretchr/testify/require"
11+
12+
"github.com/getkin/kin-openapi/openapi3"
13+
"github.com/getkin/kin-openapi/routers/gorillamux"
14+
)
15+
16+
func TestIssue639(t *testing.T) {
17+
loader := openapi3.NewLoader()
18+
ctx := loader.Context
19+
spec := `
20+
openapi: 3.0.0
21+
info:
22+
version: 1.0.0
23+
title: Sample API
24+
paths:
25+
/items:
26+
put:
27+
requestBody:
28+
content:
29+
application/json:
30+
schema:
31+
properties:
32+
testWithdefault:
33+
default: false
34+
type: boolean
35+
testNoDefault:
36+
type: boolean
37+
type: object
38+
responses:
39+
'200':
40+
description: Successful respons
41+
`[1:]
42+
43+
doc, err := loader.LoadFromData([]byte(spec))
44+
require.NoError(t, err)
45+
46+
err = doc.Validate(ctx)
47+
require.NoError(t, err)
48+
49+
router, err := gorillamux.NewRouter(doc)
50+
require.NoError(t, err)
51+
52+
tests := []struct {
53+
name string
54+
options *Options
55+
expectedDefaultVal interface{}
56+
}{
57+
{
58+
name: "no defaults are added to requests",
59+
options: &Options{
60+
SkipSettingDefaults: true,
61+
},
62+
expectedDefaultVal: nil,
63+
},
64+
65+
{
66+
name: "defaults are added to requests",
67+
expectedDefaultVal: false,
68+
},
69+
}
70+
71+
for _, testcase := range tests {
72+
t.Run(testcase.name, func(t *testing.T) {
73+
body := "{\"testNoDefault\": true}"
74+
httpReq, err := http.NewRequest(http.MethodPut, "/items", strings.NewReader(body))
75+
require.NoError(t, err)
76+
httpReq.Header.Set("Content-Type", "application/json")
77+
require.NoError(t, err)
78+
79+
route, pathParams, err := router.FindRoute(httpReq)
80+
require.NoError(t, err)
81+
82+
requestValidationInput := &RequestValidationInput{
83+
Request: httpReq,
84+
PathParams: pathParams,
85+
Route: route,
86+
Options: testcase.options,
87+
}
88+
err = ValidateRequest(ctx, requestValidationInput)
89+
require.NoError(t, err)
90+
bodyAfterValidation, err := ioutil.ReadAll(httpReq.Body)
91+
require.NoError(t, err)
92+
93+
raw := map[string]interface{}{}
94+
err = json.Unmarshal(bodyAfterValidation, &raw)
95+
require.NoError(t, err)
96+
require.Equal(t, testcase.expectedDefaultVal,
97+
raw["testWithdefault"], "default value must not be included")
98+
})
99+
}
100+
}

openapi3filter/options.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@ type Options struct {
2121

2222
// See NoopAuthenticationFunc
2323
AuthenticationFunc AuthenticationFunc
24+
25+
// Indicates whether default values are set in the
26+
// request. If true, then they are not set
27+
SkipSettingDefaults bool
2428
}

openapi3filter/validate_request.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ func ValidateRequestBody(ctx context.Context, input *RequestValidationInput, req
258258
defaultsSet := false
259259
opts := make([]openapi3.SchemaValidationOption, 0, 3) // 3 potential opts here
260260
opts = append(opts, openapi3.VisitAsRequest())
261-
opts = append(opts, openapi3.DefaultsSet(func() { defaultsSet = true }))
261+
if !options.SkipSettingDefaults {
262+
opts = append(opts, openapi3.DefaultsSet(func() { defaultsSet = true }))
263+
}
262264
if options.MultiError {
263265
opts = append(opts, openapi3.MultiErrors())
264266
}

0 commit comments

Comments
 (0)