-
-
Notifications
You must be signed in to change notification settings - Fork 429
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refine schema error reason message (#748)
- Loading branch information
1 parent
abdca6c
commit 9f99fee
Showing
8 changed files
with
355 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
package openapi3 | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
type testCase struct { | ||
name string | ||
schema *Schema | ||
value interface{} | ||
extraNotContains []interface{} | ||
options []SchemaValidationOption | ||
} | ||
|
||
func TestIssue735(t *testing.T) { | ||
DefineStringFormat("uuid", FormatOfStringForUUIDOfRFC4122) | ||
DefineStringFormat("email", FormatOfStringForEmail) | ||
DefineIPv4Format() | ||
DefineIPv6Format() | ||
|
||
testCases := []testCase{ | ||
{ | ||
name: "type string", | ||
schema: NewStringSchema(), | ||
value: 42, | ||
}, | ||
{ | ||
name: "type boolean", | ||
schema: NewBoolSchema(), | ||
value: 42, | ||
}, | ||
{ | ||
name: "type integer", | ||
schema: NewIntegerSchema(), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "type number", | ||
schema: NewFloat64Schema(), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "type array", | ||
schema: NewArraySchema(), | ||
value: 42, | ||
}, | ||
{ | ||
name: "type object", | ||
schema: NewObjectSchema(), | ||
value: 42, | ||
}, | ||
{ | ||
name: "min", | ||
schema: NewSchema().WithMin(100), | ||
value: 42, | ||
}, | ||
{ | ||
name: "max", | ||
schema: NewSchema().WithMax(0), | ||
value: 42, | ||
}, | ||
{ | ||
name: "exclusive min", | ||
schema: NewSchema().WithMin(100).WithExclusiveMin(true), | ||
value: 42, | ||
}, | ||
{ | ||
name: "exclusive max", | ||
schema: NewSchema().WithMax(0).WithExclusiveMax(true), | ||
value: 42, | ||
}, | ||
{ | ||
name: "multiple of", | ||
schema: &Schema{MultipleOf: Float64Ptr(5.0)}, | ||
value: 42, | ||
}, | ||
{ | ||
name: "enum", | ||
schema: NewSchema().WithEnum(3, 5), | ||
value: 42, | ||
}, | ||
{ | ||
name: "min length", | ||
schema: NewSchema().WithMinLength(100), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "max length", | ||
schema: NewSchema().WithMaxLength(0), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "pattern", | ||
schema: NewSchema().WithPattern("[0-9]"), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "items", | ||
schema: NewSchema().WithItems(NewStringSchema()), | ||
value: []interface{}{42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "min items", | ||
schema: NewSchema().WithMinItems(100), | ||
value: []interface{}{42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "max items", | ||
schema: NewSchema().WithMaxItems(0), | ||
value: []interface{}{42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "unique items", | ||
schema: NewSchema().WithUniqueItems(true), | ||
value: []interface{}{42, 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "min properties", | ||
schema: NewSchema().WithMinProperties(100), | ||
value: map[string]interface{}{"foo": 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "max properties", | ||
schema: NewSchema().WithMaxProperties(0), | ||
value: map[string]interface{}{"foo": 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "additional properties other schema type", | ||
schema: NewSchema().WithAdditionalProperties(NewStringSchema()), | ||
value: map[string]interface{}{"foo": 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "additional properties false", | ||
schema: &Schema{AdditionalProperties: AdditionalProperties{ | ||
Has: BoolPtr(false), | ||
}}, | ||
value: map[string]interface{}{"foo": 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "invalid properties schema", | ||
schema: NewSchema().WithProperties(map[string]*Schema{ | ||
"foo": NewStringSchema(), | ||
}), | ||
value: map[string]interface{}{"foo": 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
// TODO: uncomment when https://github.com/getkin/kin-openapi/issues/502 is fixed | ||
//{ | ||
// name: "read only properties", | ||
// schema: NewSchema().WithProperties(map[string]*Schema{ | ||
// "foo": {ReadOnly: true}, | ||
// }).WithoutAdditionalProperties(), | ||
// value: map[string]interface{}{"foo": 42}, | ||
// extraNotContains: []interface{}{42}, | ||
// options: []SchemaValidationOption{VisitAsRequest()}, | ||
//}, | ||
//{ | ||
// name: "write only properties", | ||
// schema: NewSchema().WithProperties(map[string]*Schema{ | ||
// "foo": {WriteOnly: true}, | ||
// }).WithoutAdditionalProperties(), | ||
// value: map[string]interface{}{"foo": 42}, | ||
// extraNotContains: []interface{}{42}, | ||
// options: []SchemaValidationOption{VisitAsResponse()}, | ||
//}, | ||
{ | ||
name: "required properties", | ||
schema: &Schema{ | ||
Properties: Schemas{ | ||
"bar": NewStringSchema().NewRef(), | ||
}, | ||
Required: []string{"bar"}, | ||
}, | ||
value: map[string]interface{}{"foo": 42}, | ||
extraNotContains: []interface{}{42}, | ||
}, | ||
{ | ||
name: "one of (matches more then one)", | ||
schema: NewOneOfSchema( | ||
&Schema{MultipleOf: Float64Ptr(6)}, | ||
&Schema{MultipleOf: Float64Ptr(7)}, | ||
), | ||
value: 42, | ||
}, | ||
{ | ||
name: "one of (no matches)", | ||
schema: NewOneOfSchema( | ||
&Schema{MultipleOf: Float64Ptr(5)}, | ||
&Schema{MultipleOf: Float64Ptr(10)}, | ||
), | ||
value: 42, | ||
}, | ||
{ | ||
name: "any of", | ||
schema: NewAnyOfSchema( | ||
&Schema{MultipleOf: Float64Ptr(5)}, | ||
&Schema{MultipleOf: Float64Ptr(10)}, | ||
), | ||
value: 42, | ||
}, | ||
{ | ||
name: "all of (match some)", | ||
schema: NewAllOfSchema( | ||
&Schema{MultipleOf: Float64Ptr(6)}, | ||
&Schema{MultipleOf: Float64Ptr(5)}, | ||
), | ||
value: 42, | ||
}, | ||
{ | ||
name: "all of (no match)", | ||
schema: NewAllOfSchema( | ||
&Schema{MultipleOf: Float64Ptr(10)}, | ||
&Schema{MultipleOf: Float64Ptr(5)}, | ||
), | ||
value: 42, | ||
}, | ||
{ | ||
name: "uuid format", | ||
schema: NewUUIDSchema(), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "date time format", | ||
schema: NewDateTimeSchema(), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "date format", | ||
schema: NewSchema().WithFormat("date"), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "ipv4 format", | ||
schema: NewSchema().WithFormat("ipv4"), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "ipv6 format", | ||
schema: NewSchema().WithFormat("ipv6"), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "email format", | ||
schema: NewSchema().WithFormat("email"), | ||
value: "foo", | ||
}, | ||
{ | ||
name: "byte format", | ||
schema: NewBytesSchema(), | ||
value: "foo!", | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
err := tc.schema.VisitJSON(tc.value, tc.options...) | ||
var schemaError = &SchemaError{} | ||
require.Error(t, err) | ||
require.ErrorAs(t, err, &schemaError) | ||
require.NotZero(t, schemaError.Reason) | ||
require.NotContains(t, schemaError.Reason, fmt.Sprint(tc.value)) | ||
for _, extra := range tc.extraNotContains { | ||
require.NotContains(t, schemaError.Reason, fmt.Sprint(extra)) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.