github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/courier/transport_http/decode_test.go (about)

     1  package transport_http
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"io"
     7  	"io/ioutil"
     8  	"mime/multipart"
     9  	"net/http"
    10  	"testing"
    11  
    12  	"github.com/go-courier/ptr"
    13  	"github.com/stretchr/testify/assert"
    14  
    15  	"github.com/artisanhe/tools/courier"
    16  	"github.com/artisanhe/tools/courier/httpx"
    17  	"github.com/artisanhe/tools/courier/transport_http/transform"
    18  )
    19  
    20  type GetItem struct {
    21  	httpx.MethodGet
    22  	ID     int      `name:"id" in:"path"`
    23  	Ping   *string  `name:"ping" in:"query"`
    24  	Header *string  `name:"header" default:"" in:"header"`
    25  	Slice  []string `name:"slice" default:"" in:"query"`
    26  	Body   struct {
    27  		String string `json:"body" default:"" in:"query"`
    28  	} `in:"body"`
    29  }
    30  
    31  func (getItem GetItem) MarshalDefaults(v interface{}) {
    32  	v.(*GetItem).Ping = getItem.Ping
    33  }
    34  
    35  func (getItem GetItem) Path() string {
    36  	return "/:id"
    37  }
    38  
    39  func (getItem GetItem) Output(ctx context.Context) (resp interface{}, err error) {
    40  	return
    41  }
    42  
    43  func TestCreateHttpRequestDecoder(t *testing.T) {
    44  	tt := assert.New(t)
    45  
    46  	request := GetItem{
    47  		ID:    1,
    48  		Ping:  ptr.String("1"),
    49  		Slice: []string{"1", "2", "3"},
    50  	}
    51  	request.Body.String = "111"
    52  
    53  	req, err := transform.NewRequest(request.Method(), request.Path(), request)
    54  	if ok := tt.NoError(err); !ok {
    55  		return
    56  	}
    57  	t.Log(req.URL.String())
    58  
    59  	getItem := GetItem{}
    60  	err = MarshalOperator(req, &getItem)
    61  	tt.Nil(err)
    62  
    63  	tt.Equal(request, getItem)
    64  }
    65  
    66  func TestCreateHttpRequestDecoder_VersionSwitch(t *testing.T) {
    67  	tt := assert.New(t)
    68  
    69  	{
    70  		respData := struct {
    71  			courier.WithVersionSwitch
    72  			courier.EmptyOperator
    73  		}{}
    74  
    75  		req, _ := transform.NewRequest("GET", "/", nil, courier.MetadataWithVersionSwitch("VERSION"))
    76  
    77  		err := MarshalOperator(req, &respData)
    78  		tt.NoError(err)
    79  
    80  		tt.Equal(respData.XVersion, "VERSION")
    81  	}
    82  
    83  	{
    84  		respData := struct {
    85  			courier.WithVersionSwitch
    86  			courier.EmptyOperator
    87  		}{}
    88  
    89  		req, _ := transform.NewRequest("GET", "/", nil, courier.Metadata{
    90  			httpx.HeaderRequestID: []string{courier.ModifyRequestIDWithVersionSwitch("adadasd", "VERSION")},
    91  		})
    92  
    93  		err := MarshalOperator(req, &respData)
    94  		tt.NoError(err)
    95  
    96  		tt.Equal(respData.XVersion, "VERSION")
    97  	}
    98  }
    99  
   100  type PostForm struct {
   101  	httpx.MethodPost
   102  	ID       int `name:"id" in:"path"`
   103  	FormData struct {
   104  		FirstFile  *multipart.FileHeader `name:"firstFile"`
   105  		SecondFile *multipart.FileHeader `name:"secondFile"`
   106  		Data       struct {
   107  			Value string `json:"value"`
   108  		} `name:"data"`
   109  	} `in:"formData,multipart"`
   110  }
   111  
   112  func (postForm PostForm) Path() string {
   113  	return "/:id"
   114  }
   115  
   116  func (postForm PostForm) Output(ctx context.Context) (resp interface{}, err error) {
   117  	return
   118  }
   119  
   120  func TestCreateHttpRequestDecoderWithForm(t *testing.T) {
   121  	tt := assert.New(t)
   122  
   123  	request := PostForm{}
   124  	request.ID = 2
   125  	request.FormData.Data.Value = "1111"
   126  	request.FormData.FirstFile, _ = transform.NewFileHeader("firstFile", "SingleFile", []byte("1"))
   127  	request.FormData.SecondFile, _ = transform.NewFileHeader("secondFile", "SecondFile", []byte("2"))
   128  
   129  	req, err := transform.NewRequest(request.Method(), request.Path(), request)
   130  	if ok := tt.NoError(err); !ok {
   131  		return
   132  	}
   133  	t.Log(req.URL.String())
   134  
   135  	postForm := PostForm{}
   136  	err = MarshalOperator(req, &postForm)
   137  	tt.NoError(err)
   138  	tt.Equal(request, postForm)
   139  
   140  	{
   141  		actualFile, _ := postForm.FormData.FirstFile.Open()
   142  		actualBytes, _ := ioutil.ReadAll(actualFile)
   143  		tt.Equal([]byte("1"), actualBytes)
   144  	}
   145  
   146  	{
   147  		actualFile, _ := postForm.FormData.SecondFile.Open()
   148  		actualBytes, _ := ioutil.ReadAll(actualFile)
   149  		tt.Equal([]byte("2"), actualBytes)
   150  	}
   151  }
   152  
   153  type PostFormURLEncoded struct {
   154  	httpx.MethodPost
   155  	FormData struct {
   156  		String string   `name:"string"`
   157  		Slice  []string `name:"slice"`
   158  		Data   struct {
   159  			Value string `json:"value"`
   160  		} `name:"data"`
   161  	} `in:"formData,urlencoded"`
   162  }
   163  
   164  func (PostFormURLEncoded) Path() string {
   165  	return "/"
   166  }
   167  
   168  func (PostFormURLEncoded) TransformHttpRequest(req *http.Request) {
   169  	req.Header.Set(httpx.HeaderContentType, "application/x-www-form-urlencoded; param=value")
   170  }
   171  
   172  func (postForm PostFormURLEncoded) Output(ctx context.Context) (resp interface{}, err error) {
   173  	return
   174  }
   175  
   176  func TestCreateHttpRequestDecoderWithPostFormURLEncoded(t *testing.T) {
   177  	tt := assert.New(t)
   178  
   179  	request := PostFormURLEncoded{}
   180  	request.FormData.String = "1111"
   181  	request.FormData.Slice = []string{"1111", "2222"}
   182  	request.FormData.Data.Value = "1"
   183  
   184  	req, err := transform.NewRequest(request.Method(), request.Path(), request)
   185  	if ok := tt.NoError(err); !ok {
   186  		return
   187  	}
   188  	t.Log(req.URL.String())
   189  
   190  	postForm := PostFormURLEncoded{}
   191  	err = MarshalOperator(req, &postForm)
   192  	tt.NoError(err)
   193  
   194  	tt.Equal(request, postForm)
   195  }
   196  
   197  func TestCreateHttpRequestDecoderWithPostFormURLEncodedLimitContentType(t *testing.T) {
   198  	tt := assert.New(t)
   199  
   200  	request := PostFormURLEncoded{}
   201  	request.FormData.String = "1111"
   202  	request.FormData.Slice = []string{"1111", "2222"}
   203  	request.FormData.Data.Value = "1"
   204  
   205  	req, err := transform.NewRequest(request.Method(), request.Path(), request)
   206  	if ok := tt.NoError(err); !ok {
   207  		return
   208  	}
   209  
   210  	buf := &bytes.Buffer{}
   211  
   212  	io.Copy(buf, req.Body)
   213  
   214  	finalRequest, err := http.NewRequest(
   215  		request.Method(),
   216  		request.Path(),
   217  		buf,
   218  	)
   219  
   220  	t.Log(req.Header.Get(httpx.HeaderContentType))
   221  
   222  	postForm := PostFormURLEncoded{}
   223  	err = MarshalOperator(finalRequest, &postForm)
   224  	tt.NoError(err)
   225  
   226  	tt.Equal(request, postForm)
   227  }