Skip to content

Commit

Permalink
complex bodies now validatable
Browse files Browse the repository at this point in the history
  • Loading branch information
jakecoffman committed Mar 1, 2021
1 parent 8b32424 commit 48d32bc
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 10 deletions.
27 changes: 17 additions & 10 deletions prehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func validate(val Validate, query url.Values, body interface{}, path map[string]
}

if val.Body.Initialized() && val.Body.kind != KindFile {
err := validateBody(&val.Body, body)
err := validateBody("body", &val.Body, body)
if err != nil {
return err
}
Expand All @@ -96,42 +96,49 @@ func validate(val Validate, query url.Values, body interface{}, path map[string]
return nil
}

func validateBody(field *Field, body interface{}) error {
func validateBody(name string, field *Field, body interface{}) error {
switch v := body.(type) {
case nil:
if field.required != nil && *field.required {
return fmt.Errorf("body validation failed for field %v: %v", field, errRequired)
return fmt.Errorf("body validation failed for field %v: %v", name, errRequired)
}
case string:
if err := field.Validate(v); err != nil {
return fmt.Errorf("body validation failed: %v", err.Error())
return fmt.Errorf("body validation failed for field %v: %v", name, err.Error())
}
case bool:
if err := field.Validate(v); err != nil {
return fmt.Errorf("body validation failed: %v", err.Error())
return fmt.Errorf("body validation failed for field %v: %v", name, err.Error())
}
case float64:
if field.kind == KindInteger {
// JSON doesn't have integers, so Go treats these fields as float64.
// Need to convert to integer before validating it.
if v != float64(int64(v)) {
return fmt.Errorf("body validation failed for field %v: %v", field, errWrongType)
return fmt.Errorf("body validation failed for field %v: %v", name, errWrongType)
}
if err := field.Validate(int(v)); err != nil {
return fmt.Errorf("body validation failed: %v", err.Error())
return fmt.Errorf("body validation failed for field %v: %v", name, err.Error())
}
} else {
if err := field.Validate(v); err != nil {
return fmt.Errorf("body validation failed: %v", err.Error())
return fmt.Errorf("body validation failed for field %v: %v", name, err.Error())
}
}
case []interface{}:
if err := field.Validate(v); err != nil {
return fmt.Errorf("body validation failed: %v", err.Error())
return fmt.Errorf("body validation failed for field %v: %v", name, err.Error())
}
if field.arr != nil {
for i, item := range v {
if err := validateBody(fmt.Sprintf("%v[%v]", name, i), field.arr, item); err != nil {
return err
}
}
}
case map[string]interface{}:
for name, field := range field.obj {
if err := validateBody(&field, v[name]); err != nil {
if err := validateBody(name, &field, v[name]); err != nil {
return err
}
}
Expand Down
32 changes: 32 additions & 0 deletions prehandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,38 @@ func TestBodyValidation(t *testing.T) {
},
Input: `{"obj2":{"inner":"not a number"}}`,
Expected: 400,
}, {
Schema: map[string]Field{
"arr1": Array().Items(Number()),
},
Input: `{"arr1":[1]}`,
Expected: 200,
}, {
Schema: map[string]Field{
"arr2": Array().Items(Number()),
},
Input: `{"arr2":["a"]}`,
Expected: 400,
}, {
Schema: map[string]Field{
"complex1": Object(map[string]Field{
"array": Array().Required().Items(Object(map[string]Field{
"id": Number().Required(),
})),
}).Required(),
},
Input: `{"complex1":{"array":[{"id":1}]}}`,
Expected: 200,
}, {
Schema: map[string]Field{
"complex2": Object(map[string]Field{
"array": Array().Required().Items(Object(map[string]Field{
"id": Number().Required(),
})),
}).Required(),
},
Input: `{"complex2":{"array":[{"id":"a"}]}}`,
Expected: 400,
},
}

Expand Down

0 comments on commit 48d32bc

Please sign in to comment.