gin/binding/form_mapping_encoding_test.go

122 lines
3.7 KiB
Go

//go:build gin_bind_encoding
package binding
import (
"encoding"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// In gin_bind_encoding mode, TextUnmarshaler is used automatically when present, even without an
// explicit parser tag.
func TestMappingUsingBindUnmarshalerAndTextUnmarshalerWhenOnlyTextUnmarshalerDefined_DefaultEncodingUnmarshalText(t *testing.T) {
var s struct {
Hex customUnmarshalTextHex `form:"hex"`
HexByUnmarshalText customUnmarshalTextHex `form:"hex2,parser=encoding.TextUnmarshaler"`
}
err := mappingByPtr(&s, formSource{
"hex": {`11`},
"hex2": {`11`},
}, "form")
require.NoError(t, err)
assert.EqualValues(t, 0x11, s.Hex)
assert.EqualValues(t, 0x11, s.HexByUnmarshalText)
}
// ==== Automatic TextUnmarshaler binding tests (no parser tag required) ====
func TestMappingTextUnmarshalerAutoBindForm(t *testing.T) {
var s struct {
ID objectIDUnmarshalText `form:"id"`
}
err := mappingByPtr(&s, formSource{"id": {"664a062ac74a8ad104e0e80f"}}, "form")
require.NoError(t, err)
expected, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80f")
assert.Equal(t, expected, s.ID)
}
func TestMappingTextUnmarshalerAutoBindURI(t *testing.T) {
var s struct {
ID objectIDUnmarshalText `uri:"id"`
}
err := mappingByPtr(&s, formSource{"id": {"664a062ac74a8ad104e0e80f"}}, "uri")
require.NoError(t, err)
expected, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80f")
assert.Equal(t, expected, s.ID)
}
func TestMappingTextUnmarshalerAutoBindSlice(t *testing.T) {
var s struct {
IDs []objectIDUnmarshalText `form:"ids" collection_format:"csv"`
}
err := mappingByPtr(&s, formSource{"ids": {"664a062ac74a8ad104e0e80e,664a062ac74a8ad104e0e80f"}}, "form")
require.NoError(t, err)
id1, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80e")
id2, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80f")
expected := []objectIDUnmarshalText{id1, id2}
assert.Equal(t, expected, s.IDs)
}
func TestMappingTextUnmarshalerAutoBindMultipleValues(t *testing.T) {
var s struct {
IDs []objectIDUnmarshalText `form:"ids"`
}
err := mappingByPtr(&s, formSource{"ids": {
"664a062ac74a8ad104e0e80e",
"664a062ac74a8ad104e0e80f",
}}, "form")
require.NoError(t, err)
id1, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80e")
id2, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80f")
assert.Equal(t, []objectIDUnmarshalText{id1, id2}, s.IDs)
}
func TestMappingTextUnmarshalerAutoBindDefault(t *testing.T) {
var s struct {
ID objectIDUnmarshalText `form:"id,default=664a062ac74a8ad104e0e80f"`
}
err := mappingByPtr(&s, formSource{}, "form")
require.NoError(t, err)
expected, _ := convertToOidUnmarshalText("664a062ac74a8ad104e0e80f")
assert.Equal(t, expected, s.ID)
}
func TestMappingTextUnmarshalerAutoBindInvalidValue(t *testing.T) {
var s struct {
ID objectIDUnmarshalText `form:"id"`
}
err := mappingByPtr(&s, formSource{"id": {"not-a-valid-objectid"}}, "form")
require.Error(t, err)
}
// BindUnmarshaler should take precedence over TextUnmarshaler
type testDualUnmarshaler struct {
Value string
}
func (d *testDualUnmarshaler) UnmarshalParam(param string) error {
d.Value = "param:" + param
return nil
}
func (d *testDualUnmarshaler) UnmarshalText(text []byte) error {
d.Value = "text:" + string(text)
return nil
}
var _ BindUnmarshaler = (*testDualUnmarshaler)(nil)
var _ encoding.TextUnmarshaler = (*testDualUnmarshaler)(nil)
func TestMappingBindUnmarshalerTakesPrecedenceOverTextUnmarshaler(t *testing.T) {
var s struct {
Field testDualUnmarshaler `form:"field"`
}
err := mappingByPtr(&s, formSource{"field": {"hello"}}, "form")
require.NoError(t, err)
assert.Equal(t, "param:hello", s.Field.Value) // BindUnmarshaler wins
}