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 }