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