1
2
3
4
5
6
7
8
9
10
11
12
13
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
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
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
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
91 factorParam.ExclusiveMaximum = true
92
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
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
107 factorParam.ExclusiveMinimum = true
108
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
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
126
127
128
129
130
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
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
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
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
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
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
187 err = validator.Validate("bbb")
188 assert.True(t, err == nil || err.IsValid())
189
190
191
192
193
194
195
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
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
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
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
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
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
248
249
250
251
252
253
254 }
255
View as plain text