func TestTypeDetectionInvalidItems(t *testing.T) { withoutItems := spec.QueryParam("without").CollectionOf(nil, "") binder := &untypedParamBinder{ Name: "without", parameter: withoutItems, } assert.Nil(t, binder.Type()) items := new(spec.Items) items.Type = "array" withInvalidItems := spec.QueryParam("invalidItems").CollectionOf(items, "") binder = &untypedParamBinder{ Name: "invalidItems", parameter: withInvalidItems, } assert.Nil(t, binder.Type()) noType := spec.QueryParam("invalidType") noType.Type = "invalid" binder = &untypedParamBinder{ Name: "invalidType", parameter: noType, } assert.Nil(t, binder.Type()) }
func TestSliceConversion(t *testing.T) { actual := new(SomeOperationParams) val := reflect.ValueOf(actual).Elem() // prefsField := val.FieldByName("Prefs") // cData := "yada,2,3" // _, _, err := readFormattedSliceFieldValue("Prefs", prefsField, cData, "csv", nil) // assert.Error(t, err) sliced := []string{"some", "string", "values"} seps := map[string]string{"ssv": " ", "tsv": "\t", "pipes": "|", "csv": ",", "": ","} tagsField := val.FieldByName("Tags") for k, sep := range seps { binder := &untypedParamBinder{ Name: "Tags", parameter: spec.QueryParam("tags").CollectionOf(stringItems, k), } actual.Tags = nil cData := strings.Join(sliced, sep) tags, _, err := binder.readFormattedSliceFieldValue(cData, tagsField) assert.NoError(t, err) assert.Equal(t, sliced, tags) cData = strings.Join(sliced, " "+sep+" ") tags, _, err = binder.readFormattedSliceFieldValue(cData, tagsField) assert.NoError(t, err) assert.Equal(t, sliced, tags) tags, _, err = binder.readFormattedSliceFieldValue("", tagsField) assert.NoError(t, err) assert.Empty(t, tags) } assert.Nil(t, swag.SplitByFormat("yada", "multi")) assert.Nil(t, swag.SplitByFormat("", "")) categoriesField := val.FieldByName("Categories") binder := &untypedParamBinder{ Name: "Categories", parameter: spec.QueryParam("categories").CollectionOf(stringItems, "csv"), } cData := strings.Join(sliced, ",") categories, custom, err := binder.readFormattedSliceFieldValue(cData, categoriesField) assert.NoError(t, err) assert.EqualValues(t, sliced, actual.Categories) assert.True(t, custom) assert.Empty(t, categories) categories, custom, err = binder.readFormattedSliceFieldValue("", categoriesField) assert.Error(t, err) assert.True(t, custom) assert.Empty(t, categories) }
func TestArrayItemsValidation(t *testing.T) { items := spec.NewItems().CollectionOf(stringItems, "").WithMinItems(1).WithMaxItems(5).UniqueValues() items.WithEnum("aaa", "bbb", "ccc") parent := spec.QueryParam("tags").CollectionOf(items, "") path := parent.Name + ".1" validator := newItemsValidator(parent.Name, parent.In, items, parent, strfmt.Default) // MinItems err := validator.Validate(1, []string{}) assert.True(t, err.HasErrors()) assert.EqualError(t, minItemsErrorItems(path, validator.in, items), err.Errors[0].Error()) // MaxItems err = validator.Validate(1, []string{"a", "b", "c", "d", "e", "f"}) assert.True(t, err.HasErrors()) assert.EqualError(t, maxItemsErrorItems(path, validator.in, items), err.Errors[0].Error()) // UniqueItems err = validator.Validate(1, []string{"a", "a"}) assert.True(t, err.HasErrors()) assert.EqualError(t, duplicatesErrorItems(path, validator.in), err.Errors[0].Error()) // Enum err = validator.Validate(1, []string{"a", "b", "c"}) assert.True(t, err.HasErrors()) assert.EqualError(t, enumFailItems(path, validator.in, items, []string{"a", "b", "c"}), err.Errors[0].Error()) // Items strItems := spec.NewItems().WithMinLength(3).WithMaxLength(5).WithPattern(`^[a-z]+$`) items = spec.NewItems().CollectionOf(strItems, "").WithMinItems(1).WithMaxItems(5).UniqueValues() validator = newItemsValidator(parent.Name, parent.In, items, parent, strfmt.Default) err = validator.Validate(1, []string{"aa", "bbb", "ccc"}) assert.True(t, err.HasErrors()) assert.EqualError(t, minLengthErrorItems(path+".0", parent.In, strItems), err.Errors[0].Error()) }
func TestInvalidCollectionFormat(t *testing.T) { validCf1 := spec.QueryParam("validFmt").CollectionOf(stringItems, "multi") validCf2 := spec.FormDataParam("validFmt2").CollectionOf(stringItems, "multi") invalidCf1 := spec.HeaderParam("invalidHdr").CollectionOf(stringItems, "multi") invalidCf2 := spec.PathParam("invalidPath").CollectionOf(stringItems, "multi") testCollectionFormat(t, validCf1, true) testCollectionFormat(t, validCf2, true) testCollectionFormat(t, invalidCf1, false) testCollectionFormat(t, invalidCf2, false) }
func TestArrayParameterValidation(t *testing.T) { tagsParam := spec.QueryParam("tags").CollectionOf(stringItems, "").WithMinItems(1).WithMaxItems(5).UniqueValues() tagsParam.WithEnum([]string{"a", "a", "a"}, []string{"b", "b", "b"}, []string{"c", "c", "c"}) validator := NewParamValidator(tagsParam, strfmt.Default) // MinItems err := validator.Validate([]string{}) assert.True(t, err.HasErrors()) assert.EqualError(t, minItemsError(tagsParam), err.Errors[0].Error()) // MaxItems err = validator.Validate([]string{"a", "b", "c", "d", "e", "f"}) assert.True(t, err.HasErrors()) assert.EqualError(t, maxItemsError(tagsParam), err.Errors[0].Error()) // UniqueItems err = validator.Validate([]string{"a", "a"}) assert.True(t, err.HasErrors()) assert.EqualError(t, duplicatesError(tagsParam), err.Errors[0].Error()) // Enum err = validator.Validate([]string{"a", "b", "c"}) assert.True(t, err.HasErrors()) assert.EqualError(t, enumFail(tagsParam, []string{"a", "b", "c"}), err.Errors[0].Error()) // Items strItems := spec.NewItems().WithMinLength(3).WithMaxLength(5).WithPattern(`^[a-z]+$`) tagsParam = spec.QueryParam("tags").CollectionOf(strItems, "").WithMinItems(1).WithMaxItems(5).UniqueValues() validator = NewParamValidator(tagsParam, strfmt.Default) err = validator.Validate([]string{"aa", "bbb", "ccc"}) assert.True(t, err.HasErrors()) assert.EqualError(t, minLengthErrorItems("tags.0", tagsParam.In, strItems), err.Errors[0].Error()) // Not required in a parameter or items // Additional items // AllOf // AnyOf // OneOf // Not // Definitions }
func IntParamTest(t *testing.T, pName string, val reflect.Value, defVal, expectedDef interface{}, actual func() interface{}) { fld := val.FieldByName(pName) binder := &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("integer", "int64").WithDefault(defVal), Name: pName, } err := binder.setFieldValue(fld, defVal, "5") assert.NoError(t, err) assert.EqualValues(t, 5, actual()) err = binder.setFieldValue(fld, defVal, "") assert.NoError(t, err) assert.EqualValues(t, expectedDef, actual()) err = binder.setFieldValue(fld, defVal, "yada") assert.Error(t, err) }
func TestRequiredValidation(t *testing.T) { strParam := spec.QueryParam("name").Typed("string", "").AsRequired() validateRequiredTest(t, strParam, reflect.ValueOf("")) intParam := spec.QueryParam("id").Typed("integer", "int32").AsRequired() validateRequiredTest(t, intParam, reflect.ValueOf(int32(0))) longParam := spec.QueryParam("id").Typed("integer", "int64").AsRequired() validateRequiredTest(t, longParam, reflect.ValueOf(int64(0))) floatParam := spec.QueryParam("score").Typed("number", "float").AsRequired() validateRequiredTest(t, floatParam, reflect.ValueOf(float32(0))) doubleParam := spec.QueryParam("score").Typed("number", "double").AsRequired() validateRequiredTest(t, doubleParam, reflect.ValueOf(float64(0))) dateTimeParam := spec.QueryParam("registered").Typed("string", "date-time").AsRequired() validateRequiredTest(t, dateTimeParam, reflect.ValueOf(strfmt.DateTime{})) dateParam := spec.QueryParam("registered").Typed("string", "date").AsRequired() validateRequiredTest(t, dateParam, reflect.ValueOf(strfmt.DateTime{})) sliceParam := spec.QueryParam("tags").CollectionOf(stringItems, "").AsRequired() validateRequiredTest(t, sliceParam, reflect.ValueOf([]string{})) }
func TestStringParameterValidation(t *testing.T) { nameParam := spec.QueryParam("name").AsRequired().WithMinLength(3).WithMaxLength(5).WithPattern(`^[a-z]+$`) nameParam.WithEnum("aaa", "bbb", "ccc") validator := NewParamValidator(nameParam, strfmt.Default) // required err := validator.Validate("") assert.True(t, err.HasErrors()) assert.EqualError(t, requiredError(nameParam), err.Errors[0].Error()) // MaxLength err = validator.Validate("abcdef") assert.True(t, err.HasErrors()) assert.EqualError(t, maxLengthError(nameParam), err.Errors[0].Error()) // MinLength err = validator.Validate("a") assert.True(t, err.HasErrors()) assert.EqualError(t, minLengthError(nameParam), err.Errors[0].Error()) // Pattern err = validator.Validate("a394") assert.True(t, err.HasErrors()) assert.EqualError(t, patternFail(nameParam), err.Errors[0].Error()) // Enum err = validator.Validate("abcde") assert.True(t, err.HasErrors()) assert.EqualError(t, enumFail(nameParam, "abcde"), err.Errors[0].Error()) // Valid passes err = validator.Validate("bbb") assert.True(t, err == nil || err.IsValid()) // Not required in a parameter or items // AllOf // AnyOf // OneOf // Not // Definitions }
func TestStringItemsValidation(t *testing.T) { items := spec.NewItems().WithMinLength(3).WithMaxLength(5).WithPattern(`^[a-z]+$`) items.WithEnum("aaa", "bbb", "ccc") parent := spec.QueryParam("tags").CollectionOf(items, "") path := parent.Name + ".1" validator := newItemsValidator(parent.Name, parent.In, items, parent, strfmt.Default) // required err := validator.Validate(1, "") assert.True(t, err.HasErrors()) assert.EqualError(t, minLengthErrorItems(path, validator.in, items), err.Errors[0].Error()) // MaxLength err = validator.Validate(1, "abcdef") assert.True(t, err.HasErrors()) assert.EqualError(t, maxLengthErrorItems(path, validator.in, items), err.Errors[0].Error()) // MinLength err = validator.Validate(1, "a") assert.True(t, err.HasErrors()) assert.EqualError(t, minLengthErrorItems(path, validator.in, items), err.Errors[0].Error()) // Pattern err = validator.Validate(1, "a394") assert.True(t, err.HasErrors()) assert.EqualError(t, patternFailItems(path, validator.in, items), err.Errors[0].Error()) // Enum err = validator.Validate(1, "abcde") assert.True(t, err.HasErrors()) assert.EqualError(t, enumFailItems(path, validator.in, items, "abcde"), err.Errors[0].Error()) // Valid passes err = validator.Validate(1, "bbb") assert.True(t, err == nil || err.IsValid()) }
func TestNumberParameterValidation(t *testing.T) { values := [][]interface{}{ []interface{}{23, 49, 56, 21, 14, 35, 28, 7, 42}, []interface{}{uint(23), uint(49), uint(56), uint(21), uint(14), uint(35), uint(28), uint(7), uint(42)}, []interface{}{float64(23), float64(49), float64(56), float64(21), float64(14), float64(35), float64(28), float64(7), float64(42)}, } for _, v := range values { factorParam := spec.QueryParam("factor") factorParam.WithMaximum(makeFloat(v[1]), false) factorParam.WithMinimum(makeFloat(v[3]), false) factorParam.WithMultipleOf(makeFloat(v[7])) factorParam.WithEnum(v[3], v[6], v[8], v[1]) validator := NewParamValidator(factorParam, strfmt.Default) // MultipleOf err := validator.Validate(v[0]) assert.True(t, err.HasErrors()) assert.EqualError(t, multipleOfError(factorParam), err.Errors[0].Error()) // Maximum err = validator.Validate(v[1]) assert.True(t, err == nil || err.IsValid()) if err != nil { assert.Empty(t, err.Errors) } err = validator.Validate(v[2]) assert.True(t, err.HasErrors()) assert.EqualError(t, maxError(factorParam), err.Errors[0].Error()) // ExclusiveMaximum factorParam.ExclusiveMaximum = true // requires a new items validator because this is set a creation time validator = NewParamValidator(factorParam, strfmt.Default) err = validator.Validate(v[1]) assert.True(t, err.HasErrors()) assert.EqualError(t, maxError(factorParam), err.Errors[0].Error()) // Minimum err = validator.Validate(v[3]) assert.True(t, err == nil || err.IsValid()) err = validator.Validate(v[4]) assert.True(t, err.HasErrors()) assert.EqualError(t, minError(factorParam), err.Errors[0].Error()) // ExclusiveMinimum factorParam.ExclusiveMinimum = true // requires a new items validator because this is set a creation time validator = NewParamValidator(factorParam, strfmt.Default) err = validator.Validate(v[3]) assert.True(t, err.HasErrors()) assert.EqualError(t, minError(factorParam), err.Errors[0].Error()) // Enum err = validator.Validate(v[5]) assert.True(t, err.HasErrors()) assert.EqualError(t, enumFail(factorParam, v[5]), err.Errors[0].Error()) err = validator.Validate(v[6]) assert.True(t, err == nil || err.IsValid()) } // Not required in a parameter or items // AllOf // AnyOf // OneOf // Not // Definitions }
func TestNumberItemsValidation(t *testing.T) { values := [][]interface{}{ []interface{}{23, 49, 56, 21, 14, 35, 28, 7, 42}, []interface{}{uint(23), uint(49), uint(56), uint(21), uint(14), uint(35), uint(28), uint(7), uint(42)}, []interface{}{float64(23), float64(49), float64(56), float64(21), float64(14), float64(35), float64(28), float64(7), float64(42)}, } for i, v := range values { items := spec.NewItems() items.WithMaximum(makeFloat(v[1]), false) items.WithMinimum(makeFloat(v[3]), false) items.WithMultipleOf(makeFloat(v[7])) items.WithEnum(v[3], v[6], v[8], v[1]) parent := spec.QueryParam("factors").CollectionOf(items, "") path := fmt.Sprintf("factors.%d", i) validator := newItemsValidator(parent.Name, parent.In, items, parent, strfmt.Default) // MultipleOf err := validator.Validate(i, v[0]) assert.True(t, err.HasErrors()) assert.EqualError(t, multipleOfErrorItems(path, validator.in, items), err.Errors[0].Error()) // Maximum err = validator.Validate(i, v[1]) assert.True(t, err == nil || err.IsValid()) err = validator.Validate(i, v[2]) assert.True(t, err.HasErrors()) assert.EqualError(t, maxErrorItems(path, validator.in, items), err.Errors[0].Error()) // ExclusiveMaximum items.ExclusiveMaximum = true // requires a new items validator because this is set a creation time validator = newItemsValidator(parent.Name, parent.In, items, parent, strfmt.Default) err = validator.Validate(i, v[1]) assert.True(t, err.HasErrors()) assert.EqualError(t, maxErrorItems(path, validator.in, items), err.Errors[0].Error()) // Minimum err = validator.Validate(i, v[3]) assert.True(t, err == nil || err.IsValid()) err = validator.Validate(i, v[4]) assert.True(t, err.HasErrors()) assert.EqualError(t, minErrorItems(path, validator.in, items), err.Errors[0].Error()) // ExclusiveMinimum items.ExclusiveMinimum = true // requires a new items validator because this is set a creation time validator = newItemsValidator(parent.Name, parent.In, items, parent, strfmt.Default) err = validator.Validate(i, v[3]) assert.True(t, err.HasErrors()) assert.EqualError(t, minErrorItems(path, validator.in, items), err.Errors[0].Error()) // Enum err = validator.Validate(i, v[5]) assert.True(t, err.HasErrors()) assert.EqualError(t, enumFailItems(path, validator.in, items, v[5]), err.Errors[0].Error()) // Valid passes err = validator.Validate(i, v[6]) assert.True(t, err == nil || err.IsValid()) } }
func TestParamBinding(t *testing.T) { actual := new(SomeOperationParams) val := reflect.ValueOf(actual).Elem() pName := "Name" fld := val.FieldByName(pName) binder := &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("string", "").WithDefault("some-name"), Name: pName, } err := binder.setFieldValue(fld, "some-name", "the name value") assert.NoError(t, err) assert.Equal(t, "the name value", actual.Name) err = binder.setFieldValue(fld, "some-name", "") assert.NoError(t, err) assert.Equal(t, "some-name", actual.Name) IntParamTest(t, "ID", val, 1, 1, func() interface{} { return actual.ID }) IntParamTest(t, "ID", val, nil, 0, func() interface{} { return actual.ID }) IntParamTest(t, "Age", val, 1, 1, func() interface{} { return actual.Age }) IntParamTest(t, "Age", val, nil, 0, func() interface{} { return actual.Age }) IntParamTest(t, "Visits", val, 1, 1, func() interface{} { return actual.Visits }) IntParamTest(t, "Visits", val, nil, 0, func() interface{} { return actual.Visits }) IntParamTest(t, "Count", val, 1, 1, func() interface{} { return actual.Count }) IntParamTest(t, "Count", val, nil, 0, func() interface{} { return actual.Count }) IntParamTest(t, "Seq", val, 1, 1, func() interface{} { return actual.Seq }) IntParamTest(t, "Seq", val, nil, 0, func() interface{} { return actual.Seq }) IntParamTest(t, "UID", val, uint64(1), 1, func() interface{} { return actual.UID }) IntParamTest(t, "UID", val, uint64(0), 0, func() interface{} { return actual.UID }) IntParamTest(t, "UAge", val, uint(1), 1, func() interface{} { return actual.UAge }) IntParamTest(t, "UAge", val, nil, 0, func() interface{} { return actual.UAge }) IntParamTest(t, "UVisits", val, uint32(1), 1, func() interface{} { return actual.UVisits }) IntParamTest(t, "UVisits", val, nil, 0, func() interface{} { return actual.UVisits }) IntParamTest(t, "UCount", val, uint16(1), 1, func() interface{} { return actual.UCount }) IntParamTest(t, "UCount", val, nil, 0, func() interface{} { return actual.UCount }) IntParamTest(t, "USeq", val, uint8(1), 1, func() interface{} { return actual.USeq }) IntParamTest(t, "USeq", val, nil, 0, func() interface{} { return actual.USeq }) FloatParamTest(t, "score", "Score", "float", val, 1.0, 1, func() interface{} { return actual.Score }) FloatParamTest(t, "score", "Score", "float", val, nil, 0, func() interface{} { return actual.Score }) FloatParamTest(t, "rate", "Rate", "double", val, 1.0, 1, func() interface{} { return actual.Rate }) FloatParamTest(t, "rate", "Rate", "double", val, nil, 0, func() interface{} { return actual.Rate }) pName = "Confirmed" confirmedField := val.FieldByName(pName) binder = &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("boolean", "").WithDefault(true), Name: pName, } for _, tv := range evaluatesAsTrue { err = binder.setFieldValue(confirmedField, true, tv) assert.NoError(t, err) assert.True(t, actual.Confirmed) } err = binder.setFieldValue(confirmedField, true, "") assert.NoError(t, err) assert.True(t, actual.Confirmed) err = binder.setFieldValue(confirmedField, true, "0") assert.NoError(t, err) assert.False(t, actual.Confirmed) pName = "Timestamp" timeField := val.FieldByName(pName) dt := strfmt.DateTime{Time: time.Date(2014, 3, 19, 2, 9, 0, 0, time.UTC)} binder = &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("string", "date-time").WithDefault(dt), Name: pName, } exp := strfmt.DateTime{Time: time.Date(2014, 5, 14, 2, 9, 0, 0, time.UTC)} err = binder.setFieldValue(timeField, dt, exp.String()) assert.NoError(t, err) assert.Equal(t, exp, actual.Timestamp) err = binder.setFieldValue(timeField, dt, "") assert.NoError(t, err) assert.Equal(t, dt, actual.Timestamp) err = binder.setFieldValue(timeField, dt, "yada") assert.Error(t, err) ddt := strfmt.Date{Time: time.Date(2014, 3, 19, 0, 0, 0, 0, time.UTC)} pName = "Birthdate" dateField := val.FieldByName(pName) binder = &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("string", "date").WithDefault(ddt), Name: pName, } expd := strfmt.Date{Time: time.Date(2014, 5, 14, 0, 0, 0, 0, time.UTC)} err = binder.setFieldValue(dateField, ddt, expd.String()) assert.NoError(t, err) assert.Equal(t, expd, actual.Birthdate) err = binder.setFieldValue(dateField, ddt, "") assert.NoError(t, err) assert.Equal(t, ddt, actual.Birthdate) err = binder.setFieldValue(dateField, ddt, "yada") assert.Error(t, err) fdt := &strfmt.DateTime{Time: time.Date(2014, 3, 19, 2, 9, 0, 0, time.UTC)} pName = "LastFailure" ftimeField := val.FieldByName(pName) binder = &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("string", "date").WithDefault(fdt), Name: pName, } fexp := &strfmt.DateTime{Time: time.Date(2014, 5, 14, 2, 9, 0, 0, time.UTC)} err = binder.setFieldValue(ftimeField, fdt, fexp.String()) assert.NoError(t, err) assert.Equal(t, fexp, actual.LastFailure) err = binder.setFieldValue(ftimeField, fdt, "") assert.NoError(t, err) assert.Equal(t, fdt, actual.LastFailure) err = binder.setFieldValue(ftimeField, fdt, "") assert.NoError(t, err) assert.Equal(t, fdt, actual.LastFailure) actual.LastFailure = nil err = binder.setFieldValue(ftimeField, fdt, "yada") assert.Error(t, err) assert.Nil(t, actual.LastFailure) pName = "Unsupported" unsupportedField := val.FieldByName(pName) binder = &untypedParamBinder{ parameter: spec.QueryParam(pName).Typed("string", ""), Name: pName, } err = binder.setFieldValue(unsupportedField, nil, "") assert.Error(t, err) }