github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/validation/validation_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package validation
     5  
     6  import (
     7  	"testing"
     8  
     9  	ut "github.com/go-playground/universal-translator"
    10  	valid "github.com/go-playground/validator/v10"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  type testStruct struct {
    15  	Field1 int      `json:"field1,omitempty" validate:"eq=1"`
    16  	Field2 string   `json:"field2,omitempty" validate:"possible-values=value1 value2 value3"`
    17  	Field3 string   `json:"field3,omitempty" validate:"required_if=Field1 1 Field4 test"`
    18  	Field4 string   `json:"field4,omitempty"`
    19  	Field5 []string `json:"field5,omitempty" validate:"possible-values=val1 val2 val3 val4"`
    20  }
    21  
    22  func TestValidateStruct(t *testing.T) {
    23  	t.Run("success case", func(t *testing.T) {
    24  		validation, err := New(WithPredefinedErrorMessages(), WithJSONNamesForStructFields())
    25  		assert.NoError(t, err)
    26  		tStruct := testStruct{
    27  			Field1: 1,
    28  			Field2: "value1",
    29  			Field3: "field3",
    30  			Field4: "test",
    31  			Field5: []string{"val1", "val2", "val3"},
    32  		}
    33  		err = validation.ValidateStruct(tStruct)
    34  		assert.NoError(t, err)
    35  	})
    36  
    37  	t.Run("success case - empty values for string and []string", func(t *testing.T) {
    38  		validation, err := New(WithPredefinedErrorMessages(), WithJSONNamesForStructFields())
    39  		assert.NoError(t, err)
    40  		tStruct := testStruct{
    41  			Field1: 1,
    42  			Field3: "field3",
    43  			Field4: "test",
    44  		}
    45  		err = validation.ValidateStruct(tStruct)
    46  		assert.NoError(t, err)
    47  	})
    48  
    49  	t.Run("error case - default error messages", func(t *testing.T) {
    50  		validation, err := New()
    51  		assert.NoError(t, err)
    52  		testStruct := testStruct{
    53  			Field1: 1,
    54  			Field2: "value4",
    55  			Field4: "test",
    56  			Field5: []string{"val1", "val2", "val5"},
    57  		}
    58  		err = validation.ValidateStruct(testStruct)
    59  		assert.Error(t, err)
    60  		assert.Contains(t, err.Error(), "Key: 'testStruct.Field2' Error:Field validation for 'Field2' failed on the 'possible-values' tag.")
    61  		assert.Contains(t, err.Error(), "Key: 'testStruct.Field3' Error:Field validation for 'Field3' failed on the 'required_if' tag.")
    62  		assert.Contains(t, err.Error(), "Key: 'testStruct.Field5' Error:Field validation for 'Field5' failed on the 'possible-values' tag.")
    63  	})
    64  
    65  	t.Run("error case - predefined error messages without naming fields from json tags", func(t *testing.T) {
    66  		validation, err := New(WithPredefinedErrorMessages())
    67  		assert.NoError(t, err)
    68  		testStruct := testStruct{
    69  			Field1: 1,
    70  			Field2: "value4",
    71  			Field4: "test",
    72  			Field5: []string{"val1", "val2", "val5"},
    73  		}
    74  		err = validation.ValidateStruct(testStruct)
    75  		assert.Error(t, err)
    76  		assert.Contains(t, err.Error(), "The Field2 must use the following values: value1 value2 value3.")
    77  		assert.Contains(t, err.Error(), "The Field3 is required since the Field1 is 1.")
    78  		assert.Contains(t, err.Error(), "The Field5 must use the following values: val1 val2 val3 val4.")
    79  	})
    80  
    81  	t.Run("failed case - predefined error messages with naming fields from json tags", func(t *testing.T) {
    82  		validation, err := New(WithPredefinedErrorMessages(), WithJSONNamesForStructFields())
    83  		assert.NoError(t, err)
    84  		testStruct := testStruct{
    85  			Field1: 1,
    86  			Field2: "value4",
    87  			Field4: "test",
    88  			Field5: []string{"val1", "val2", "val5"},
    89  		}
    90  		err = validation.ValidateStruct(testStruct)
    91  		assert.Error(t, err)
    92  		assert.Contains(t, err.Error(), "The field2 must use the following values: value1 value2 value3.")
    93  		assert.Contains(t, err.Error(), "The field3 is required since the Field1 is 1.")
    94  		assert.Contains(t, err.Error(), "The field5 must use the following values: val1 val2 val3 val4.")
    95  	})
    96  
    97  	t.Run("failed case - custom error messages", func(t *testing.T) {
    98  		translations := []Translation{
    99  			{
   100  				Tag: "possible-values",
   101  				RegisterFn: func(ut ut.Translator) error {
   102  					return ut.Add("possible-values", "Custom error message for {0}", true)
   103  				},
   104  				TranslationFn: func(ut ut.Translator, fe valid.FieldError) string {
   105  					t, _ := ut.T("possible-values", fe.Field())
   106  					return t
   107  				},
   108  			}, {
   109  				Tag: "required_if",
   110  				RegisterFn: func(ut ut.Translator) error {
   111  					return ut.Add("required_if", "Custom error message for {0}", true)
   112  				},
   113  				TranslationFn: func(ut ut.Translator, fe valid.FieldError) string {
   114  					t, _ := ut.T("required_if", fe.Field())
   115  					return t
   116  				},
   117  			},
   118  		}
   119  		validation, err := New(WithCustomErrorMessages(translations))
   120  		assert.NoError(t, err)
   121  		testStruct := testStruct{
   122  			Field1: 1,
   123  			Field2: "value4",
   124  			Field4: "test",
   125  			Field5: []string{"val1", "val2", "val5"},
   126  		}
   127  		err = validation.ValidateStruct(testStruct)
   128  		assert.Error(t, err)
   129  		assert.Contains(t, err.Error(), "Custom error message for Field2")
   130  		assert.Contains(t, err.Error(), "Custom error message for Field3")
   131  		assert.Contains(t, err.Error(), "Custom error message for Field5")
   132  	})
   133  }