Skip to content

Commit

Permalink
fix: setting defaults for oneOf and anyOf (#690)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomato0111 committed Dec 6, 2022
1 parent b4b41f3 commit ebbf60d
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 8 deletions.
17 changes: 9 additions & 8 deletions openapi3/schema.go
Expand Up @@ -934,10 +934,6 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val
matchedOneOfIdx = 0
tempValue = value
)
// make a deep copy to protect origin value from being injected default value that defined in mismatched oneOf schema
if settings.asreq || settings.asrep {
tempValue = deepcopy.Copy(value)
}
for idx, item := range v {
v := item.Value
if v == nil {
Expand All @@ -948,6 +944,11 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val
continue
}

// make a deep copy to protect origin value from being injected default value that defined in mismatched oneOf schema
if settings.asreq || settings.asrep {
tempValue = deepcopy.Copy(value)
}

if err := v.visitJSON(settings, tempValue); err != nil {
validationErrors = append(validationErrors, err)
continue
Expand Down Expand Up @@ -990,15 +991,15 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val
matchedAnyOfIdx = 0
tempValue = value
)
// make a deep copy to protect origin value from being injected default value that defined in mismatched anyOf schema
if settings.asreq || settings.asrep {
tempValue = deepcopy.Copy(value)
}
for idx, item := range v {
v := item.Value
if v == nil {
return foundUnresolvedRef(item.Ref)
}
// make a deep copy to protect origin value from being injected default value that defined in mismatched anyOf schema
if settings.asreq || settings.asrep {
tempValue = deepcopy.Copy(value)
}
if err := v.visitJSON(settings, tempValue); err == nil {
ok = true
matchedAnyOfIdx = idx
Expand Down
116 changes: 116 additions & 0 deletions openapi3filter/validate_set_default_test.go
Expand Up @@ -317,6 +317,70 @@ func TestValidateRequestBodyAndSetDefault(t *testing.T) {
}
}
]
},
"contact": {
"oneOf": [
{
"type": "object",
"required": ["email"],
"properties": {
"email": {
"type": "string"
},
"allow_image": {
"type": "boolean",
"default": true
}
},
"additionalProperties": false
},
{
"type": "object",
"required": ["phone"],
"properties": {
"phone": {
"type": "string"
},
"allow_text": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false
}
]
},
"contact2": {
"anyOf": [
{
"type": "object",
"required": ["email"],
"properties": {
"email": {
"type": "string"
},
"allow_image": {
"type": "boolean",
"default": true
}
},
"additionalProperties": false
},
{
"type": "object",
"required": ["phone"],
"properties": {
"phone": {
"type": "string"
},
"allow_text": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false
}
]
}
}
}
Expand Down Expand Up @@ -358,6 +422,10 @@ func TestValidateRequestBodyAndSetDefault(t *testing.T) {
FBLink string `json:"fb_link,omitempty"`
TWLink string `json:"tw_link,omitempty"`
}
type contact struct {
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
}
type body struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Expand All @@ -367,6 +435,8 @@ func TestValidateRequestBodyAndSetDefault(t *testing.T) {
Filters []filter `json:"filters,omitempty"`
SocialNetwork *socialNetwork `json:"social_network,omitempty"`
SocialNetwork2 *socialNetwork `json:"social_network_2,omitempty"`
Contact *contact `json:"contact,omitempty"`
Contact2 *contact `json:"contact2,omitempty"`
}

testCases := []struct {
Expand Down Expand Up @@ -656,6 +726,52 @@ func TestValidateRequestBodyAndSetDefault(t *testing.T) {
"platform": "facebook",
"fb_link": "www.facebook.com"
}
}
`, body)
},
},
{
name: "contact(oneOf)",
body: body{
ID: "bt6kdc3d0cvp6u8u3ft0",
Contact: &contact{
Phone: "123456",
},
},
bodyAssertion: func(t *testing.T, body string) {
require.JSONEq(t, `
{
"id": "bt6kdc3d0cvp6u8u3ft0",
"name": "default",
"code": 123,
"all": false,
"contact": {
"phone": "123456",
"allow_text": false
}
}
`, body)
},
},
{
name: "contact(anyOf)",
body: body{
ID: "bt6kdc3d0cvp6u8u3ft0",
Contact2: &contact{
Phone: "123456",
},
},
bodyAssertion: func(t *testing.T, body string) {
require.JSONEq(t, `
{
"id": "bt6kdc3d0cvp6u8u3ft0",
"name": "default",
"code": 123,
"all": false,
"contact2": {
"phone": "123456",
"allow_text": false
}
}
`, body)
},
Expand Down

0 comments on commit ebbf60d

Please sign in to comment.