func (r *Route) parseInfo(path string) error { ri, err := schema.NewRequestInfo(reflect.TypeOf(r.Handler), path, r.Description, r.Returns) if err != nil { return err } // search for custom unmarshallers in the request info for _, param := range ri.Params { if param.Type.Kind() == reflect.Struct { logging.Debug("Checking unmarshaller for %s", param.Type) val := reflect.Zero(param.Type).Interface() if unm, ok := val.(Unmarshaler); ok { logging.Info("Registering unmarshaller for %#v", val) schemaDecoder.RegisterConverter(val, gorilla.Converter(func(s string) reflect.Value { return reflect.ValueOf(unm.UnmarshalRequestData(s)) })) } } } r.requestInfo = ri return nil }
func TestValidation(t *testing.T) { //t.SkipNow() req, err := http.NewRequest("GET", "http://example.com/foo?int=4&float=1.4&string=word&bool=true&list=foo&list=bar", nil) if err != nil { t.Fatal(err) } if err := req.ParseForm(); err != nil { t.Fatal(err) } h := MockHandlerV{ Int: 4, Float: 3.14, Bool: true, Lst: []string{"foo", "bar"}, String: "word", } ri, err := schema.NewRequestInfo(reflect.TypeOf(MockHandlerV{}), "/foo", "bar", nil) if err != nil { t.Error(err) } v := NewRequestValidator(ri) if v == nil { t.Fatal("nil request validator") } if err = v.Validate(h, req); err != nil { t.Errorf("Failed validation: %s", err) } // fail on missing param badreq, _ := http.NewRequest("GET", "http://example.com/foo?float=1.4&string=word&bool=true&list=foo&list=bar", nil) badreq.ParseForm() if err = v.Validate(h, badreq); err == nil { t.Errorf("We didn't fail on missing int from request: %s", err) } // fail on bad string value h.String = " wat" // spaces not allowed if err = v.Validate(h, req); err == nil || err.Error() != "string does not match regex pattern" { t.Errorf("We didn't fail on regex: %s", err) } h.String = "watwatwat" // spaces not allowed if err = v.Validate(h, req); err == nil || err.Error() != "string is too long" { t.Errorf("We didn't fail on maxlen: %s", err) } h.String = "" if err = v.Validate(h, req); err == nil || err.Error() != "string is too short" { t.Errorf("We didn't fail on minlen: %s", err) } h.String = "wat" // Fail on bad int value h.Int = -1000 if err = v.Validate(h, req); err == nil || err.Error() != "Value too small for int" { t.Errorf("We didn't fail on min: %s", err) } h.Int = 1000 if err = v.Validate(h, req); err == nil || err.Error() != "Value too large for int" { t.Errorf("We didn't fail on max: %s", err) } h.Int = 5 // Fail on bad float value h.Float = -1000 if err = v.Validate(h, req); err == nil || err.Error() != "Value too small for float" { t.Errorf("We didn't fail on min: %s", err) } h.Float = 1000 if err = v.Validate(h, req); err == nil || err.Error() != "Value too large for float" { t.Errorf("We didn't fail on max: %s", err) } }