trpc.group/trpc-go/trpc-go@v1.0.2/http/serialization_form_test.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 package http_test 15 16 import ( 17 "fmt" 18 "net/url" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/require" 23 24 "trpc.group/trpc-go/trpc-go/codec" 25 "trpc.group/trpc-go/trpc-go/http" 26 ) 27 28 // go test -v -coverprofile=cover.out 29 // go tool cover -func=cover.out 30 31 func TestFormSerializerRegister(t *testing.T) { 32 defer func() { 33 e := recover() 34 require.Nil(t, e) 35 }() 36 37 s := codec.GetSerializer(codec.SerializationTypeForm) 38 defer func() { 39 codec.RegisterSerializer(codec.SerializationTypeForm, s) 40 }() 41 codec.RegisterSerializer(codec.SerializationTypeForm, http.NewFormSerialization("json")) 42 formSerializer := codec.GetSerializer(codec.SerializationTypeForm) 43 require.NotNil(t, formSerializer) 44 } 45 46 func TestFormSerializer(t *testing.T) { 47 require := require.New(t) 48 formSerializer := codec.GetSerializer(codec.SerializationTypeForm) 49 50 type FormStruct struct { 51 X int `json:"x"` 52 Y string `json:"y"` 53 Z []string `json:"z"` 54 } 55 56 var queries = []string{ 57 "x=1&y=nice&z=3", 58 "x=1&y=2&z", 59 "x=1&y=2", 60 "x=1&y=2&z=z1&z=z2", 61 } 62 63 var expects = []*FormStruct{ 64 { 65 X: 1, 66 Y: "nice", 67 Z: []string{"3"}, 68 }, 69 { 70 X: 1, 71 Y: "2", 72 Z: []string{""}, 73 }, 74 { 75 X: 1, 76 Y: "2", 77 Z: nil, 78 }, 79 { 80 X: 1, 81 Y: "2", 82 Z: []string{"z1", "z2"}, 83 }, 84 } 85 86 var expectedQueries = []string{ 87 "x=1&y=nice&z=3", 88 "x=1&y=2&z=", 89 "x=1&y=2", 90 "x=1&y=2&z=z1&z=z2", 91 } 92 93 for i, query := range queries { 94 form := &FormStruct{} 95 formSerializer.Unmarshal([]byte(query), &form) 96 require.Equal(form.X, expects[i].X, "x should be equal") 97 require.Equal(form.Y, expects[i].Y, "y should be equal") 98 require.Equal(form.Z, expects[i].Z, "z should be equal") 99 100 m := make(map[string]interface{}) 101 formSerializer.Unmarshal([]byte(query), &m) 102 require.Equal(m["y"], expects[i].Y, "y should be equal") 103 } 104 105 for i, query := range expects { 106 buf, _ := formSerializer.Marshal(&query) 107 require.Equal(string(buf), expectedQueries[i], "x should be equal") 108 } 109 110 } 111 112 func TestUnmarshal(t *testing.T) { 113 require := require.New(t) 114 s := codec.GetSerializer(codec.SerializationTypeForm) 115 116 type formStruct struct{} 117 form := &formStruct{} 118 119 require.NotNil(s.Unmarshal([]byte("%gh&%ij"), &form)) 120 require.NotNil(s.Unmarshal([]byte("x=1&y=2"), (map[string]interface{})(nil))) 121 } 122 123 func TestMarshal(t *testing.T) { 124 require := require.New(t) 125 s := codec.GetSerializer(codec.SerializationTypeForm) 126 127 v := make(url.Values) 128 buf, err := s.Marshal(v) 129 require.NotNil(buf) 130 require.Nil(err) 131 132 type testError struct { 133 Time time.Time 134 BadMapKey map[time.Time]string 135 Iface map[interface{}]string 136 Struct map[struct{}]string 137 } 138 139 test := testError{ 140 Iface: map[interface{}]string{nil: "time"}, 141 Struct: map[struct{}]string{{}: "str"}, 142 } 143 _, err = s.Marshal(&test) 144 require.NotNil(err) 145 146 nestedMap := map[string]interface{}{ 147 "id": "123", 148 "attr": map[string]interface{}{ 149 "name": "haha", 150 }, 151 } 152 _, err = s.Marshal(nestedMap) 153 require.Nil(err) 154 } 155 156 type queryRequest struct { 157 Ints []int `json:"ints"` 158 Query []byte `json:"query"` 159 } 160 161 func TestUnmarshalBytes(t *testing.T) { 162 query := &queryRequest{} 163 s := codec.GetSerializer(codec.SerializationTypeForm) 164 require.NotNil(t, s.Unmarshal([]byte("%gh&%ij"), &query)) 165 require.Nil(t, s.Unmarshal([]byte("x=1&y=2"), &query)) 166 } 167 168 func TestUnmarshalChinese(t *testing.T) { 169 query := &queryRequest{} 170 s := codec.GetSerializer(codec.SerializationTypeForm) 171 err := s.Unmarshal([]byte("ints=1&ints=2&query=中文"), &query) 172 require.Nil(t, err, fmt.Sprintf("err: %+v", err)) 173 require.Equal(t, []byte("中文"), query.Query) 174 require.Equal(t, []int{1, 2}, query.Ints) 175 } 176 177 func TestUnmarshalNested(t *testing.T) { 178 type Nested struct { 179 Msg string `json:"msg"` 180 } 181 type nested struct { 182 Nest Nested `json:"nest"` 183 } 184 q := &nested{} 185 s := codec.GetSerializer(codec.SerializationTypeForm) 186 err := s.Unmarshal([]byte("nest.msg=hhh"), &q) 187 require.Nil(t, err, fmt.Sprintf("err: %+v", err)) 188 require.Equal(t, "hhh", q.Nest.Msg) 189 }