...

Source file src/github.com/go-openapi/validate/parameter_validator_test.go

Documentation: github.com/go-openapi/validate

     1  // Copyright 2015 go-swagger maintainers
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package validate
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  
    21  	"github.com/go-openapi/errors"
    22  	"github.com/go-openapi/spec"
    23  	"github.com/go-openapi/strfmt"
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  // common validations: enum, allOf, anyOf, oneOf, not, definitions
    29  
    30  func maxError(param *spec.Parameter, data interface{}) *errors.Validation {
    31  	return errors.ExceedsMaximum(param.Name, param.In, *param.Maximum, param.ExclusiveMaximum, data)
    32  }
    33  
    34  func minError(param *spec.Parameter, data interface{}) *errors.Validation {
    35  	return errors.ExceedsMinimum(param.Name, param.In, *param.Minimum, param.ExclusiveMinimum, data)
    36  }
    37  
    38  func multipleOfError(param *spec.Parameter, data interface{}) *errors.Validation {
    39  	return errors.NotMultipleOf(param.Name, param.In, *param.MultipleOf, data)
    40  }
    41  
    42  func makeFloat(data interface{}) float64 {
    43  	val := reflect.ValueOf(data)
    44  	knd := val.Kind()
    45  	switch {
    46  	case knd >= reflect.Int && knd <= reflect.Int64:
    47  		return float64(val.Int())
    48  	case knd >= reflect.Uint && knd <= reflect.Uint64:
    49  		return float64(val.Uint())
    50  	default:
    51  		return val.Float()
    52  	}
    53  }
    54  
    55  func TestNumberParameterValidation(t *testing.T) {
    56  
    57  	values := [][]interface{}{
    58  		{23, 49, 56, 21, 14, 35, 28, 7, 42},
    59  		{uint(23), uint(49), uint(56), uint(21), uint(14), uint(35), uint(28), uint(7), uint(42)},
    60  		{float64(23), float64(49), float64(56), float64(21), float64(14), float64(35), float64(28), float64(7), float64(42)},
    61  	}
    62  
    63  	for _, v := range values {
    64  		factorParam := spec.QueryParam("factor")
    65  		factorParam.WithMaximum(makeFloat(v[1]), false)
    66  		factorParam.WithMinimum(makeFloat(v[3]), false)
    67  		factorParam.WithMultipleOf(makeFloat(v[7]))
    68  		factorParam.WithEnum(v[3], v[6], v[8], v[1])
    69  		factorParam.Typed("number", "double")
    70  		validator := NewParamValidator(factorParam, strfmt.Default)
    71  
    72  		// MultipleOf
    73  		err := validator.Validate(v[0])
    74  		assert.True(t, err.HasErrors())
    75  		require.NotEmpty(t, err.Errors)
    76  		require.EqualError(t, multipleOfError(factorParam, v[0]), err.Errors[0].Error())
    77  
    78  		// Maximum
    79  		err = validator.Validate(v[1])
    80  		assert.True(t, err == nil || err.IsValid())
    81  		if err != nil {
    82  			assert.Empty(t, err.Errors)
    83  		}
    84  		err = validator.Validate(v[2])
    85  
    86  		assert.True(t, err.HasErrors())
    87  		require.NotEmpty(t, err.Errors)
    88  		require.EqualError(t, maxError(factorParam, v[1]), err.Errors[0].Error())
    89  
    90  		// ExclusiveMaximum
    91  		factorParam.ExclusiveMaximum = true
    92  		// requires a new items validator because this is set a creation time
    93  		validator = NewParamValidator(factorParam, strfmt.Default)
    94  		err = validator.Validate(v[1])
    95  		assert.True(t, err.HasErrors())
    96  		require.NotEmpty(t, err.Errors)
    97  		require.EqualError(t, maxError(factorParam, v[1]), err.Errors[0].Error())
    98  
    99  		// Minimum
   100  		err = validator.Validate(v[3])
   101  		assert.True(t, err == nil || err.IsValid())
   102  		err = validator.Validate(v[4])
   103  		assert.True(t, err.HasErrors())
   104  		require.EqualError(t, minError(factorParam, v[4]), err.Errors[0].Error())
   105  
   106  		// ExclusiveMinimum
   107  		factorParam.ExclusiveMinimum = true
   108  		// requires a new items validator because this is set a creation time
   109  		validator = NewParamValidator(factorParam, strfmt.Default)
   110  		err = validator.Validate(v[3])
   111  		assert.True(t, err.HasErrors())
   112  		require.NotEmpty(t, err.Errors)
   113  		require.EqualError(t, minError(factorParam, v[3]), err.Errors[0].Error())
   114  
   115  		// Enum
   116  		err = validator.Validate(v[5])
   117  		assert.True(t, err.HasErrors())
   118  		require.NotEmpty(t, err.Errors)
   119  		require.EqualError(t, enumFail(factorParam, v[5]), err.Errors[0].Error())
   120  
   121  		err = validator.Validate(v[6])
   122  		assert.True(t, err == nil || err.IsValid())
   123  	}
   124  
   125  	// Not required in a parameter or items
   126  	// AllOf
   127  	// AnyOf
   128  	// OneOf
   129  	// Not
   130  	// Definitions
   131  }
   132  
   133  func maxLengthError(param *spec.Parameter, data interface{}) *errors.Validation {
   134  	return errors.TooLong(param.Name, param.In, *param.MaxLength, data)
   135  }
   136  
   137  func minLengthError(param *spec.Parameter, data interface{}) *errors.Validation {
   138  	return errors.TooShort(param.Name, param.In, *param.MinLength, data)
   139  }
   140  
   141  func patternFail(param *spec.Parameter, data interface{}) *errors.Validation {
   142  	return errors.FailedPattern(param.Name, param.In, param.Pattern, data)
   143  }
   144  
   145  func enumFail(param *spec.Parameter, data interface{}) *errors.Validation {
   146  	return errors.EnumFail(param.Name, param.In, data, param.Enum)
   147  }
   148  
   149  func TestStringParameterValidation(t *testing.T) {
   150  	nameParam := spec.QueryParam("name").AsRequired().WithMinLength(3).WithMaxLength(5).WithPattern(`^[a-z]+$`).Typed(stringType, "")
   151  	nameParam.WithEnum("aaa", "bbb", "ccc")
   152  	validator := NewParamValidator(nameParam, strfmt.Default)
   153  
   154  	// required
   155  	data := ""
   156  	err := validator.Validate(data)
   157  	assert.True(t, err.HasErrors())
   158  	require.NotEmpty(t, err.Errors)
   159  	require.EqualError(t, requiredError(nameParam, data), err.Errors[0].Error())
   160  	// MaxLength
   161  	data = "abcdef"
   162  	err = validator.Validate(data)
   163  	assert.True(t, err.HasErrors())
   164  	require.NotEmpty(t, err.Errors)
   165  	require.EqualError(t, maxLengthError(nameParam, data), err.Errors[0].Error())
   166  	// MinLength
   167  	data = "a"
   168  	err = validator.Validate(data)
   169  	assert.True(t, err.HasErrors())
   170  	require.NotEmpty(t, err.Errors)
   171  	require.EqualError(t, minLengthError(nameParam, data), err.Errors[0].Error())
   172  	// Pattern
   173  	data = "a394"
   174  	err = validator.Validate(data)
   175  	assert.True(t, err.HasErrors())
   176  	require.NotEmpty(t, err.Errors)
   177  	require.EqualError(t, patternFail(nameParam, data), err.Errors[0].Error())
   178  
   179  	// Enum
   180  	data = "abcde"
   181  	err = validator.Validate(data)
   182  	assert.True(t, err.HasErrors())
   183  	require.NotEmpty(t, err.Errors)
   184  	require.EqualError(t, enumFail(nameParam, data), err.Errors[0].Error())
   185  
   186  	// Valid passes
   187  	err = validator.Validate("bbb")
   188  	assert.True(t, err == nil || err.IsValid())
   189  
   190  	// Not required in a parameter or items
   191  	// AllOf
   192  	// AnyOf
   193  	// OneOf
   194  	// Not
   195  	// Definitions
   196  }
   197  
   198  func minItemsError(param *spec.Parameter, data interface{}) *errors.Validation {
   199  	return errors.TooFewItems(param.Name, param.In, *param.MinItems, data)
   200  }
   201  func maxItemsError(param *spec.Parameter, data interface{}) *errors.Validation {
   202  	return errors.TooManyItems(param.Name, param.In, *param.MaxItems, data)
   203  }
   204  func duplicatesError(param *spec.Parameter) *errors.Validation {
   205  	return errors.DuplicateItems(param.Name, param.In)
   206  }
   207  
   208  func TestArrayParameterValidation(t *testing.T) {
   209  	tagsParam := spec.QueryParam("tags").CollectionOf(stringItems(), "").WithMinItems(1).WithMaxItems(5).UniqueValues()
   210  	tagsParam.WithEnum([]string{"a", "a", "a"}, []string{"b", "b", "b"}, []string{"c", "c", "c"})
   211  	validator := NewParamValidator(tagsParam, strfmt.Default)
   212  
   213  	// MinItems
   214  	data := []string{}
   215  	err := validator.Validate(data)
   216  	assert.True(t, err.HasErrors())
   217  	require.NotEmpty(t, err.Errors)
   218  	require.EqualError(t, minItemsError(tagsParam, len(data)), err.Errors[0].Error())
   219  	// MaxItems
   220  	data = []string{"a", "b", "c", "d", "e", "f"}
   221  	err = validator.Validate(data)
   222  	assert.True(t, err.HasErrors())
   223  	require.NotEmpty(t, err.Errors)
   224  	require.EqualError(t, maxItemsError(tagsParam, len(data)), err.Errors[0].Error())
   225  	// UniqueItems
   226  	err = validator.Validate([]string{"a", "a"})
   227  	assert.True(t, err.HasErrors())
   228  	require.NotEmpty(t, err.Errors)
   229  	require.EqualError(t, duplicatesError(tagsParam), err.Errors[0].Error())
   230  
   231  	// Enum
   232  	err = validator.Validate([]string{"a", "b", "c"})
   233  	assert.True(t, err.HasErrors())
   234  	require.NotEmpty(t, err.Errors)
   235  	require.EqualError(t, enumFail(tagsParam, []string{"a", "b", "c"}), err.Errors[0].Error())
   236  
   237  	// Items
   238  	strItems := spec.NewItems().WithMinLength(3).WithMaxLength(5).WithPattern(`^[a-z]+$`).Typed(stringType, "")
   239  	tagsParam = spec.QueryParam("tags").CollectionOf(strItems, "").WithMinItems(1).WithMaxItems(5).UniqueValues()
   240  	validator = NewParamValidator(tagsParam, strfmt.Default)
   241  	data = []string{"aa", "bbb", "ccc"}
   242  	err = validator.Validate(data)
   243  	assert.True(t, err.HasErrors())
   244  	require.NotEmpty(t, err.Errors)
   245  	require.EqualError(t, minLengthErrorItems("tags.0", tagsParam.In, strItems, data[0]), err.Errors[0].Error())
   246  
   247  	// Not required in a parameter or items
   248  	// Additional items
   249  	// AllOf
   250  	// AnyOf
   251  	// OneOf
   252  	// Not
   253  	// Definitions
   254  }
   255  

View as plain text