Skip to content

Commit

Permalink
feat(validator): new PayloadValidationOptions type (#10)
Browse files Browse the repository at this point in the history
Accepts values for both `ValidationOptions` and `DecoderOptions`.
The appropriate set of options is passed to `Validate()` and `Decode()`,
respectively.
  • Loading branch information
oleoneto authored Nov 10, 2022
1 parent 67d4922 commit 8be2b54
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 30 deletions.
27 changes: 14 additions & 13 deletions validators/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,17 @@ var Errors = map[string]string{
"value": "INVALID_VALUE",
}

type ValidationOptions struct {
Ignore []string
SkipRules []string
}
type (
ValidationOptions struct {
Ignore []string
SkipRules []string
}

PayloadValidationOptions struct {
ValidationOptions
structs.DecoderOptions
}
)

// Validates a struct and its attributes and returns a list of validation errors.
//
Expand Down Expand Up @@ -353,25 +360,19 @@ func ValidateAttribute(attribute structs.StructAttribute, options ValidationOpti
// name: ["REQUIRED_ATTRIBUTE_MISSING"]
// }
// */
func ValidatePayload(data []byte, model any, options ValidationOptions) map[string][]string {
func ValidatePayload(data []byte, model any, options PayloadValidationOptions) map[string][]string {
decoderErrors := structs.Decode(
data,
model,
structs.DecoderOptions{
Rules: []structs.SchemaValidationRule{
structs.ADDITIONAL_PROPERTY,
structs.INVALID_TYPE,
structs.REQUIRED_ATTRIBUTE,
},
},
options.DecoderOptions,
)

// NOTE: no need to go any further because the payload is invalid.
if _, ok := decoderErrors["_"]; ok {
return decoderErrors
}

validations := Validate(model, options)
validations := Validate(model, options.ValidationOptions)

for k, v := range decoderErrors {
validations[k] = v
Expand Down
75 changes: 58 additions & 17 deletions validators/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package validators
import (
"reflect"
"testing"

"github.com/oleoneto/go-structs/structs"
)

type Identifiable struct {
Expand Down Expand Up @@ -271,7 +273,7 @@ func Test_ValidatePayload(t *testing.T) {
type args struct {
data []byte
model any
options ValidationOptions
options PayloadValidationOptions
}

tests := []struct {
Expand All @@ -282,9 +284,17 @@ func Test_ValidatePayload(t *testing.T) {
{
name: "person - 1",
args: args{
data: []byte(`{"name": "", "contact": {"emails": []}}`),
model: &Person{},
options: ValidationOptions{},
data: []byte(`{"name": "", "contact": {"emails": []}}`),
model: &Person{},
options: PayloadValidationOptions{
DecoderOptions: structs.DecoderOptions{
Rules: []structs.SchemaValidationRule{
structs.ADDITIONAL_PROPERTY,
structs.INVALID_TYPE,
structs.REQUIRED_ATTRIBUTE,
},
},
},
},
want: map[string][]string{
"id": {"REQUIRED_ATTRIBUTE_MISSING"},
Expand All @@ -295,21 +305,36 @@ func Test_ValidatePayload(t *testing.T) {
{
name: "person - 2",
args: args{
data: []byte(`{"id": "1108129d-1d98-4a21-837a-ae6319f64c73", "name": 1, "contact": {"emails": ["}}`),
model: &Person{},
options: ValidationOptions{},
data: []byte(`{"id": "1108129d-1d98-4a21-837a-ae6319f64c73", "name": 1, "contact": {"emails": ["}}`),
model: &Person{},
options: PayloadValidationOptions{
DecoderOptions: structs.DecoderOptions{
Rules: []structs.SchemaValidationRule{
structs.ADDITIONAL_PROPERTY,
structs.INVALID_TYPE,
structs.REQUIRED_ATTRIBUTE,
},
},
},
},

want: map[string][]string{
"_": {"INVALID_PAYLOAD"},
},
},
{
name: "person - 3",
args: args{
data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": 1, "contact": {"emails": ["leo", "[email protected]"]}}`),
model: &Person{},
options: ValidationOptions{},
data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": 1, "contact": {"emails": ["leo", "[email protected]"]}}`),
model: &Person{},
options: PayloadValidationOptions{
DecoderOptions: structs.DecoderOptions{
Rules: []structs.SchemaValidationRule{
structs.ADDITIONAL_PROPERTY,
structs.INVALID_TYPE,
structs.REQUIRED_ATTRIBUTE,
},
},
},
},
want: map[string][]string{
"name": {"INVALID_TYPE"},
Expand All @@ -319,18 +344,34 @@ func Test_ValidatePayload(t *testing.T) {
{
name: "person - 4",
args: args{
data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": "Leonardo", "contact": {"emails": ["[email protected]"]}}`),
model: &Person{},
options: ValidationOptions{},
data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": "Leonardo", "contact": {"emails": ["[email protected]"]}}`),
model: &Person{},
options: PayloadValidationOptions{
DecoderOptions: structs.DecoderOptions{
Rules: []structs.SchemaValidationRule{
structs.ADDITIONAL_PROPERTY,
structs.INVALID_TYPE,
structs.REQUIRED_ATTRIBUTE,
},
},
},
},
want: map[string][]string{},
},
{
name: "resource - 1",
args: args{
model: &Resource{},
data: []byte(`{"currency": "BRL", "price": 14, "group": 7, "type": "NEW", "code": "ABC12", "qty": 2, "rating": 5, "related": ["123", "145"], "published_at": "2020-01-01T00:00:00+01:00", "id": "some-id"}`),
options: ValidationOptions{},
model: &Resource{},
data: []byte(`{"currency": "BRL", "price": 14, "group": 7, "type": "NEW", "code": "ABC12", "qty": 2, "rating": 5, "related": ["123", "145"], "published_at": "2020-01-01T00:00:00+01:00", "id": "some-id"}`),
options: PayloadValidationOptions{
DecoderOptions: structs.DecoderOptions{
Rules: []structs.SchemaValidationRule{
structs.ADDITIONAL_PROPERTY,
structs.INVALID_TYPE,
structs.REQUIRED_ATTRIBUTE,
},
},
},
},
want: map[string][]string{
"id": {"ADDITIONAL_PROPERTY"},
Expand Down

0 comments on commit 8be2b54

Please sign in to comment.