fiber/binder/binder_test.go
Juan Calderon-Perez 3b2af61152
🧹 chore: Improve Binder tests coverage (#3529)
* Move binder tests into existing file

* Fix lint issues and race condition

* Add nolint directive
2025-06-19 08:28:49 +02:00

138 lines
3.9 KiB
Go

package binder
import (
"mime/multipart"
"reflect"
"strconv"
"testing"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
)
func Test_GetAndPutToThePool(t *testing.T) {
t.Parallel()
// Panics in case we get from another pool
require.Panics(t, func() {
_ = GetFromThePool[*HeaderBinding](&CookieBinderPool)
})
// We get from the pool
binder := GetFromThePool[*HeaderBinding](&HeaderBinderPool)
PutToThePool(&HeaderBinderPool, binder)
_ = GetFromThePool[*RespHeaderBinding](&RespHeaderBinderPool)
_ = GetFromThePool[*QueryBinding](&QueryBinderPool)
_ = GetFromThePool[*FormBinding](&FormBinderPool)
_ = GetFromThePool[*URIBinding](&URIBinderPool)
_ = GetFromThePool[*XMLBinding](&XMLBinderPool)
_ = GetFromThePool[*JSONBinding](&JSONBinderPool)
_ = GetFromThePool[*CBORBinding](&CBORBinderPool)
}
func Test_Binders_ErrorPaths(t *testing.T) {
t.Run("query binder invalid key", func(t *testing.T) {
b := &QueryBinding{}
req := fasthttp.AcquireRequest()
req.URI().SetQueryString("invalid[%3Dval&name=john")
defer fasthttp.ReleaseRequest(req)
err := b.Bind(req, &struct{}{})
require.Error(t, err)
require.Contains(t, err.Error(), "unmatched brackets")
})
t.Run("form binder invalid key", func(t *testing.T) {
b := &FormBinding{}
req := fasthttp.AcquireRequest()
req.SetBodyString("invalid[=val")
req.Header.SetContentType("application/x-www-form-urlencoded")
defer fasthttp.ReleaseRequest(req)
err := b.Bind(req, &struct{}{})
require.Error(t, err)
require.Contains(t, err.Error(), "unmatched brackets")
})
t.Run("form binder bad multipart", func(t *testing.T) {
b := &FormBinding{}
req := fasthttp.AcquireRequest()
req.Header.SetContentType(MIMEMultipartForm)
defer fasthttp.ReleaseRequest(req)
err := b.Bind(req, &struct{}{})
require.Error(t, err)
})
}
func Test_GetFieldCache_Panic(t *testing.T) {
t.Parallel()
require.Panics(t, func() { getFieldCache("unknown") })
}
func Test_parseToMap_defaultCase(t *testing.T) {
t.Parallel()
m := map[string]int{}
err := parseToMap(m, map[string][]string{"a": {"1"}})
require.NoError(t, err)
require.Empty(t, m)
m2 := map[string]string{}
err = parseToMap(m2, map[string][]string{"empty": {}})
require.NoError(t, err)
require.Equal(t, "", m2["empty"])
}
func Test_parse_function_maps(t *testing.T) {
t.Parallel()
m := map[string][]string{}
err := parse("query", &m, map[string][]string{"a": {"b"}})
require.NoError(t, err)
require.Equal(t, []string{"b"}, m["a"])
m2 := map[string]string{}
err = parse("query", &m2, map[string][]string{"a": {"b"}})
require.NoError(t, err)
require.Equal(t, "b", m2["a"])
}
func Test_SetParserDecoder_UnknownKeys(t *testing.T) {
SetParserDecoder(ParserConfig{IgnoreUnknownKeys: false})
defer SetParserDecoder(ParserConfig{IgnoreUnknownKeys: true, ZeroEmpty: true})
type user struct {
Name string `query:"name"`
}
data := map[string][]string{"name": {"john"}, "foo": {"bar"}}
err := parseToStruct("query", &user{}, data)
require.Error(t, err)
SetParserDecoder(ParserConfig{IgnoreUnknownKeys: true, ZeroEmpty: true})
}
func Test_SetParserDecoder_CustomConverter(t *testing.T) {
type myInt int
conv := func(s string) reflect.Value {
v, _ := strconv.Atoi(s) //nolint:errcheck // not needed
mi := myInt(v)
return reflect.ValueOf(mi)
}
SetParserDecoder(ParserConfig{ParserType: []ParserType{{CustomType: myInt(0), Converter: conv}}})
defer SetParserDecoder(ParserConfig{IgnoreUnknownKeys: true, ZeroEmpty: true})
type data struct {
V myInt `query:"v"`
}
d := new(data)
err := parse("query", d, map[string][]string{"v": {"5"}})
require.NoError(t, err)
require.Equal(t, myInt(5), d.V)
}
func Test_formatBindData_typeMismatch(t *testing.T) {
t.Parallel()
out := struct{}{}
files := map[string][]*multipart.FileHeader{}
err := formatBindData("query", out, files, "file", 123, false, false)
require.Error(t, err)
require.Equal(t, "unsupported value type: int", err.Error())
}