Skip to content

Commit

Permalink
Merge pull request #31 from Rhyanz46/required-if
Browse files Browse the repository at this point in the history
add `RequiredIf` check
  • Loading branch information
Rhyanz46 authored Jul 11, 2024
2 parents e137135 + d235716 commit 4115db6
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 5 deletions.
36 changes: 34 additions & 2 deletions map_validator/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,39 @@ func validateRecursive(wrapper *RulesWrapper, key string, data map[string]interf
}
}
if !required {
return nil, errors.New(fmt.Sprintf("if field '%s' is null you need to put value in this %v field", field, dependenciesField))
return nil, errors.New(fmt.Sprintf("if field '%s' is null you need to put value in %v field", field, dependenciesField))
}
}
}

// put required if values
if wrapper != nil && len(rule.RequiredIf) > 0 {
for _, unique := range rule.RequiredIf {
if wrapper.requiredIf == nil {
wrapper.requiredIf = &map[string][]string{}
}

if _, exists := (*wrapper.requiredIf)[unique]; !exists {
(*wrapper.requiredIf)[unique] = []string{}
}
(*wrapper.requiredIf)[unique] = append((*wrapper.requiredIf)[unique], key)
}
}

if endOfLoop && wrapper.requiredIf != nil {
for _, field := range *wrapper.filledField {
var required bool
dependenciesField := (*wrapper.requiredIf)[field]
if len(dependenciesField) == 0 {
continue
}
for _, XField := range dependenciesField {
if !isDataInList(XField, *wrapper.nullFields) {
required = true
}
}
if !required {
return nil, errors.New(fmt.Sprintf("if field '%s' is filled you need to put value in %v field also", field, dependenciesField))
}
}
}
Expand Down Expand Up @@ -233,7 +265,7 @@ func validate(field string, dataTemp map[string]interface{}, validator Rules, da
var sliceData []interface{}
//var isListObject bool

if len(validator.RequiredWithout) > 0 {
if len(validator.RequiredWithout) > 0 || len(validator.RequiredIf) > 0 {
validator.Null = true
}

Expand Down
2 changes: 2 additions & 0 deletions map_validator/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type RulesWrapper struct {
filledField *[]string
nullFields *[]string
requiredWithout *map[string][]string
requiredIf *map[string][]string
}

type Rules struct {
Expand All @@ -60,6 +61,7 @@ type Rules struct {
RegexString string
Unique []string
RequiredWithout []string
RequiredIf []string
Object *RulesWrapper
ListObject *RulesWrapper

Expand Down
124 changes: 124 additions & 0 deletions test/required_if_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package test

import (
"github.com/Rhyanz46/go-map-validator/map_validator"
"reflect"
"strings"
"testing"
)

func TestRequiredIf(t *testing.T) {
check, err := map_validator.NewValidateBuilder().SetRules(map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"name": {Type: reflect.String},
"flavor": {Type: reflect.String, RequiredWithout: []string{"name"}},
"custom_flavor": {Type: reflect.String, RequiredIf: []string{"name"}},
},
}).Load(map[string]interface{}{
"name": "SSD",
//"custom_flavor": "large",
})
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
return
}

expected := "' is filled you need to put value in ["
_, err = check.RunValidate()
if err == nil || !strings.Contains(err.Error(), expected) {
t.Errorf("Expected error contains '%s', but we got %s", expected, err)
}
}

func TestChildRequiredIfStandardError(t *testing.T) {
role := map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"data": {Object: &map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"unit_size": {Type: reflect.Int, RequiredIf: []string{"size"}},
"size": {Type: reflect.Int, RequiredIf: []string{"unit_size"}},
},
}},
},
}
payload := map[string]interface{}{
"data": map[string]interface{}{
"size": 1,
//"unit_size": 2,
},
}
check, err := map_validator.NewValidateBuilder().SetRules(role).Load(payload)
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
return
}
expected := "' is filled you need to put value in ["
_, err = check.RunValidate()
if err == nil || !strings.Contains(err.Error(), expected) {
t.Errorf("Expected error contains '%s', but we got %s", expected, err)
}
}

func TestChildRequiredIfStandardOk(t *testing.T) {
role := map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"data": {Object: &map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"unit_size": {Type: reflect.Int, RequiredIf: []string{"size"}},
"size": {Type: reflect.Int, RequiredIf: []string{"unit_size"}},
},
}},
},
}
payload := map[string]interface{}{
"data": map[string]interface{}{
"size": 1,
"unit_size": 2,
},
}
check, err := map_validator.NewValidateBuilder().SetRules(role).Load(payload)
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
return
}
_, err = check.RunValidate()
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
return
}
}

func TestChildRequiredIf(t *testing.T) {
role := map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"data": {Object: &map_validator.RulesWrapper{
Rules: map[string]map_validator.Rules{
"name": {Type: reflect.String},
"flavor": {Type: reflect.String, RequiredWithout: []string{"custom_flavor", "size"}},
"custom_flavor": {Type: reflect.String, RequiredWithout: []string{"flavor", "size"}},
"unit_size": {Enum: &map_validator.EnumField[any]{Items: []string{"GB", "MB", "TB"}}, RequiredIf: []string{"size"}},
"size": {Type: reflect.Int, RequiredWithout: []string{"flavor", "custom_flavor"}, RequiredIf: []string{"unit_size"}},
},
}},
},
}
payload := map[string]interface{}{
"data": map[string]interface{}{
"name": "sabalong",
"flavor": "normal",
"size": 1,
//"unit_size": 2,
},
}
check, err := map_validator.NewValidateBuilder().SetRules(role).Load(payload)
if err != nil {
t.Errorf("Expected not have error, but got error : %s", err)
return
}
expected := "' is filled you need to put value in ["
_, err = check.RunValidate()

if err == nil || !strings.Contains(err.Error(), expected) {
t.Errorf("Expected error contains '%s', but we got %s", expected, err)
}
}
6 changes: 3 additions & 3 deletions test/required_without_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestRequiredWithout(t *testing.T) {
return
}

expected := "is null you need to put value in this"
expected := "is null you need to put value in "
_, err = check.RunValidate()
if !strings.Contains(err.Error(), expected) {
t.Errorf("Expected error with text at least %s, but we got %s", expected, err)
Expand Down Expand Up @@ -53,9 +53,9 @@ func TestChildRequiredWithout(t *testing.T) {
t.Errorf("Expected not have error, but got error : %s", err)
return
}
expected := "is null you need to put value in this"
expected := "is null you need to put value in "
_, err = check.RunValidate()
if !strings.Contains(err.Error(), expected) {
if err == nil || !strings.Contains(err.Error(), expected) {
t.Errorf("Expected error with text at least %s, but we got %s", expected, err)
}
}
Expand Down

0 comments on commit 4115db6

Please sign in to comment.