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  }