test and fix internal/reqdata #8
|
@ -545,3 +545,238 @@ func TestJsonParameters(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMultipartParameters(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
RawMultipart string
|
||||||
|
|
||||||
|
InvalidNames []string
|
||||||
|
ParamNames []string
|
||||||
|
ParamValues []interface{}
|
||||||
|
}{
|
||||||
|
// no need to fully check json because it is parsed with the standard library
|
||||||
|
{
|
||||||
|
RawMultipart: ``,
|
||||||
|
InvalidNames: []string{},
|
||||||
|
ParamNames: []string{},
|
||||||
|
ParamValues: []interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
`,
|
||||||
|
InvalidNames: []string{},
|
||||||
|
ParamNames: []string{},
|
||||||
|
ParamValues: []interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{},
|
||||||
|
ParamNames: []string{},
|
||||||
|
ParamValues: []interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="a"
|
||||||
|
|
||||||
|
b
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{},
|
||||||
|
ParamNames: []string{"a"},
|
||||||
|
ParamValues: []interface{}{"b"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="a"
|
||||||
|
|
||||||
|
b
|
||||||
|
--xxx
|
||||||
|
Content-Disposition: form-data; name="c"
|
||||||
|
|
||||||
|
d
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{},
|
||||||
|
ParamNames: []string{"a", "c"},
|
||||||
|
ParamValues: []interface{}{"b", "d"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="_invalid"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"_invalid"},
|
||||||
|
ParamNames: []string{"_invalid"},
|
||||||
|
ParamValues: []interface{}{nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="a"
|
||||||
|
|
||||||
|
b
|
||||||
|
--xxx
|
||||||
|
Content-Disposition: form-data; name="_invalid"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"_invalid"},
|
||||||
|
ParamNames: []string{"a", "_invalid"},
|
||||||
|
ParamValues: []interface{}{"b", nil},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="invalid_"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"invalid_"},
|
||||||
|
ParamNames: []string{"invalid_"},
|
||||||
|
ParamValues: []interface{}{nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="a"
|
||||||
|
|
||||||
|
b
|
||||||
|
--xxx
|
||||||
|
Content-Disposition: form-data; name="invalid_"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"invalid_"},
|
||||||
|
ParamNames: []string{"a", "invalid_"},
|
||||||
|
ParamValues: []interface{}{"b", nil},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="GET@injection"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"GET@injection"},
|
||||||
|
ParamNames: []string{"GET@injection"},
|
||||||
|
ParamValues: []interface{}{nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="a"
|
||||||
|
|
||||||
|
b
|
||||||
|
--xxx
|
||||||
|
Content-Disposition: form-data; name="GET@injection"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"GET@injection"},
|
||||||
|
ParamNames: []string{"a", "GET@injection"},
|
||||||
|
ParamValues: []interface{}{"b", nil},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="URL#injection"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"URL#injection"},
|
||||||
|
ParamNames: []string{"URL#injection"},
|
||||||
|
ParamValues: []interface{}{nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawMultipart: `--xxx
|
||||||
|
Content-Disposition: form-data; name="a"
|
||||||
|
|
||||||
|
b
|
||||||
|
--xxx
|
||||||
|
Content-Disposition: form-data; name="URL#injection"
|
||||||
|
|
||||||
|
x
|
||||||
|
--xxx--`,
|
||||||
|
InvalidNames: []string{"URL#injection"},
|
||||||
|
ParamNames: []string{"a", "URL#injection"},
|
||||||
|
ParamValues: []interface{}{"b", nil},
|
||||||
|
},
|
||||||
|
// json parse error
|
||||||
|
{
|
||||||
|
RawMultipart: "{ \"a\": \"b\", }",
|
||||||
|
InvalidNames: []string{},
|
||||||
|
ParamNames: []string{},
|
||||||
|
ParamValues: []interface{}{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
t.Run(fmt.Sprintf("request.%d", i), func(t *testing.T) {
|
||||||
|
body := bytes.NewBufferString(test.RawMultipart)
|
||||||
|
req := httptest.NewRequest(http.MethodPost, "http://host.com", body)
|
||||||
|
req.Header.Add("Content-Type", "multipart/form-data; boundary=xxx")
|
||||||
|
defer req.Body.Close()
|
||||||
|
store := New(nil, req)
|
||||||
|
|
||||||
|
if test.ParamNames == nil || test.ParamValues == nil {
|
||||||
|
if len(store.Set) != 0 {
|
||||||
|
t.Errorf("expected no JSON parameters and got %d", len(store.Get))
|
||||||
|
t.Failed()
|
||||||
|
}
|
||||||
|
|
||||||
|
// no param to check
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(test.ParamNames) != len(test.ParamValues) {
|
||||||
|
t.Errorf("invalid test: names and values differ in size (%d vs %d)", len(test.ParamNames), len(test.ParamValues))
|
||||||
|
t.Failed()
|
||||||
|
}
|
||||||
|
|
||||||
|
for pi, pName := range test.ParamNames {
|
||||||
|
key := pName
|
||||||
|
value := test.ParamValues[pi]
|
||||||
|
|
||||||
|
isNameValid := true
|
||||||
|
for _, invalid := range test.InvalidNames {
|
||||||
|
if pName == invalid {
|
||||||
|
isNameValid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(key, func(t *testing.T) {
|
||||||
|
|
||||||
|
param, isset := store.Set[key]
|
||||||
|
if !isset {
|
||||||
|
if isNameValid {
|
||||||
|
t.Errorf("store should contain element with key '%s'", key)
|
||||||
|
t.Failed()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if should be invalid
|
||||||
|
if isset && !isNameValid {
|
||||||
|
t.Errorf("store should NOT contain element with key '%s' (invalid name)", key)
|
||||||
|
t.Failed()
|
||||||
|
}
|
||||||
|
|
||||||
|
valueType := reflect.TypeOf(value)
|
||||||
|
|
||||||
|
paramValue := param.Value
|
||||||
|
paramValueType := reflect.TypeOf(param.Value)
|
||||||
|
|
||||||
|
if valueType != paramValueType {
|
||||||
|
t.Errorf("should be of type %v (got '%v')", valueType, paramValueType)
|
||||||
|
t.Failed()
|
||||||
|
}
|
||||||
|
|
||||||
|
if paramValue != value {
|
||||||
|
t.Errorf("should return %v (got '%v')", value, paramValue)
|
||||||
|
t.Failed()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue