diff --git a/validators/validator.go b/validators/validator.go index 3508109..467e341 100644 --- a/validators/validator.go +++ b/validators/validator.go @@ -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. // @@ -353,17 +360,11 @@ 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. @@ -371,7 +372,7 @@ func ValidatePayload(data []byte, model any, options ValidationOptions) map[stri return decoderErrors } - validations := Validate(model, options) + validations := Validate(model, options.ValidationOptions) for k, v := range decoderErrors { validations[k] = v diff --git a/validators/validator_test.go b/validators/validator_test.go index ff28ae1..8cdc8c2 100644 --- a/validators/validator_test.go +++ b/validators/validator_test.go @@ -3,6 +3,8 @@ package validators import ( "reflect" "testing" + + "github.com/oleoneto/go-structs/structs" ) type Identifiable struct { @@ -271,7 +273,7 @@ func Test_ValidatePayload(t *testing.T) { type args struct { data []byte model any - options ValidationOptions + options PayloadValidationOptions } tests := []struct { @@ -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"}, @@ -295,11 +305,18 @@ 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"}, }, @@ -307,9 +324,17 @@ func Test_ValidatePayload(t *testing.T) { { name: "person - 3", args: args{ - data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": 1, "contact": {"emails": ["leo", "leo@example.org"]}}`), - model: &Person{}, - options: ValidationOptions{}, + data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": 1, "contact": {"emails": ["leo", "leo@example.org"]}}`), + 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"}, @@ -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": ["leo@example.org"]}}`), - model: &Person{}, - options: ValidationOptions{}, + data: []byte(`{"id": "2b852002-f19d-11ec-8ea0-0242ac120002", "name": "Leonardo", "contact": {"emails": ["leo@example.org"]}}`), + 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"},