trpc.group/trpc-go/trpc-go@v1.0.3/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 func TestFromSerializerURLValues(t *testing.T) { 112 in := make(url.Values) 113 const ( 114 key = "key" 115 val = "val" 116 ) 117 in.Add(key, val) 118 bs, err := codec.Marshal(codec.SerializationTypeForm, in) 119 require.Nil(t, err) 120 out := make(url.Values) 121 require.Nil(t, codec.Unmarshal(codec.SerializationTypeForm, bs, out)) 122 require.Equal(t, val, out.Get(key)) 123 124 out2 := make(url.Values) 125 require.Nil(t, codec.Unmarshal(codec.SerializationTypeForm, bs, &out2)) 126 require.Equal(t, val, out2.Get(key)) 127 128 var out3 url.Values 129 require.NotNil(t, codec.Unmarshal(codec.SerializationTypeForm, bs, out3)) 130 } 131 132 func TestUnmarshal(t *testing.T) { 133 require := require.New(t) 134 s := codec.GetSerializer(codec.SerializationTypeForm) 135 136 type formStruct struct{} 137 form := &formStruct{} 138 139 require.NotNil(s.Unmarshal([]byte("%gh&%ij"), &form)) 140 require.NotNil(s.Unmarshal([]byte("x=1&y=2"), (map[string]interface{})(nil))) 141 } 142 143 func TestMarshal(t *testing.T) { 144 require := require.New(t) 145 s := codec.GetSerializer(codec.SerializationTypeForm) 146 147 v := make(url.Values) 148 buf, err := s.Marshal(v) 149 require.NotNil(buf) 150 require.Nil(err) 151 152 type testError struct { 153 Time time.Time 154 BadMapKey map[time.Time]string 155 Iface map[interface{}]string 156 Struct map[struct{}]string 157 } 158 159 test := testError{ 160 Iface: map[interface{}]string{nil: "time"}, 161 Struct: map[struct{}]string{{}: "str"}, 162 } 163 _, err = s.Marshal(&test) 164 require.NotNil(err) 165 166 nestedMap := map[string]interface{}{ 167 "id": "123", 168 "attr": map[string]interface{}{ 169 "name": "haha", 170 }, 171 } 172 _, err = s.Marshal(nestedMap) 173 require.Nil(err) 174 } 175 176 type queryRequest struct { 177 Ints []int `json:"ints"` 178 Query []byte `json:"query"` 179 } 180 181 func TestUnmarshalBytes(t *testing.T) { 182 query := &queryRequest{} 183 s := codec.GetSerializer(codec.SerializationTypeForm) 184 require.NotNil(t, s.Unmarshal([]byte("%gh&%ij"), &query)) 185 require.Nil(t, s.Unmarshal([]byte("x=1&y=2"), &query)) 186 } 187 188 func TestUnmarshalChinese(t *testing.T) { 189 query := &queryRequest{} 190 s := codec.GetSerializer(codec.SerializationTypeForm) 191 err := s.Unmarshal([]byte("ints=1&ints=2&query=中文"), &query) 192 require.Nil(t, err, fmt.Sprintf("err: %+v", err)) 193 require.Equal(t, []byte("中文"), query.Query) 194 require.Equal(t, []int{1, 2}, query.Ints) 195 } 196 197 func TestUnmarshalNested(t *testing.T) { 198 type Nested struct { 199 Msg string `json:"msg"` 200 } 201 type nested struct { 202 Nest Nested `json:"nest"` 203 } 204 q := &nested{} 205 s := codec.GetSerializer(codec.SerializationTypeForm) 206 err := s.Unmarshal([]byte("nest.msg=hhh"), &q) 207 require.Nil(t, err, fmt.Sprintf("err: %+v", err)) 208 require.Equal(t, "hhh", q.Nest.Msg) 209 } 210 211 func TestDecoderPanic(t *testing.T) { 212 defer func() { 213 if r := recover(); r != nil { 214 t.Errorf("Test panicked: %v", r) 215 } 216 }() 217 s := codec.GetSerializer(codec.SerializationTypeForm) 218 type msg struct { 219 Words []string 220 } 221 req := &msg{} 222 require.Nil(t, s.Unmarshal([]byte("xx]"), req)) 223 }