binding_test.go 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
  2. // Use of this source code is governed by a MIT style
  3. // license that can be found in the LICENSE file.
  4. package binding
  5. import (
  6. "bytes"
  7. "encoding/json"
  8. "errors"
  9. "io"
  10. "io/ioutil"
  11. "mime/multipart"
  12. "net/http"
  13. "os"
  14. "strconv"
  15. "strings"
  16. "testing"
  17. "time"
  18. "github.com/gin-gonic/gin/testdata/protoexample"
  19. "github.com/golang/protobuf/proto"
  20. "github.com/stretchr/testify/assert"
  21. "github.com/ugorji/go/codec"
  22. )
  23. type appkey struct {
  24. Appkey string `json:"appkey" form:"appkey"`
  25. }
  26. type QueryTest struct {
  27. Page int `json:"page" form:"page"`
  28. Size int `json:"size" form:"size"`
  29. appkey
  30. }
  31. type FooStruct struct {
  32. Foo string `msgpack:"foo" json:"foo" form:"foo" xml:"foo" binding:"required"`
  33. }
  34. type FooBarStruct struct {
  35. FooStruct
  36. Bar string `msgpack:"bar" json:"bar" form:"bar" xml:"bar" binding:"required"`
  37. }
  38. type FooBarFileStruct struct {
  39. FooBarStruct
  40. File *multipart.FileHeader `form:"file" binding:"required"`
  41. }
  42. type FooBarFileFailStruct struct {
  43. FooBarStruct
  44. File *multipart.FileHeader `invalid_name:"file" binding:"required"`
  45. // for unexport test
  46. data *multipart.FileHeader `form:"data" binding:"required"`
  47. }
  48. type FooDefaultBarStruct struct {
  49. FooStruct
  50. Bar string `msgpack:"bar" json:"bar" form:"bar,default=hello" xml:"bar" binding:"required"`
  51. }
  52. type FooStructUseNumber struct {
  53. Foo interface{} `json:"foo" binding:"required"`
  54. }
  55. type FooStructDisallowUnknownFields struct {
  56. Foo interface{} `json:"foo" binding:"required"`
  57. }
  58. type FooBarStructForTimeType struct {
  59. TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_utc:"1" time_location:"Asia/Chongqing"`
  60. TimeBar time.Time `form:"time_bar" time_format:"2006-01-02" time_utc:"1"`
  61. CreateTime time.Time `form:"createTime" time_format:"unixNano"`
  62. UnixTime time.Time `form:"unixTime" time_format:"unix"`
  63. }
  64. type FooStructForTimeTypeNotUnixFormat struct {
  65. CreateTime time.Time `form:"createTime" time_format:"unixNano"`
  66. UnixTime time.Time `form:"unixTime" time_format:"unix"`
  67. }
  68. type FooStructForTimeTypeNotFormat struct {
  69. TimeFoo time.Time `form:"time_foo"`
  70. }
  71. type FooStructForTimeTypeFailFormat struct {
  72. TimeFoo time.Time `form:"time_foo" time_format:"2017-11-15"`
  73. }
  74. type FooStructForTimeTypeFailLocation struct {
  75. TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_location:"/asia/chongqing"`
  76. }
  77. type FooStructForMapType struct {
  78. MapFoo map[string]interface{} `form:"map_foo"`
  79. }
  80. type FooStructForIgnoreFormTag struct {
  81. Foo *string `form:"-"`
  82. }
  83. type InvalidNameType struct {
  84. TestName string `invalid_name:"test_name"`
  85. }
  86. type InvalidNameMapType struct {
  87. TestName struct {
  88. MapFoo map[string]interface{} `form:"map_foo"`
  89. }
  90. }
  91. type FooStructForSliceType struct {
  92. SliceFoo []int `form:"slice_foo"`
  93. }
  94. type FooStructForStructType struct {
  95. StructFoo struct {
  96. Idx int `form:"idx"`
  97. }
  98. }
  99. type FooStructForStructPointerType struct {
  100. StructPointerFoo *struct {
  101. Name string `form:"name"`
  102. }
  103. }
  104. type FooStructForSliceMapType struct {
  105. // Unknown type: not support map
  106. SliceMapFoo []map[string]interface{} `form:"slice_map_foo"`
  107. }
  108. type FooStructForBoolType struct {
  109. BoolFoo bool `form:"bool_foo"`
  110. }
  111. type FooStructForStringPtrType struct {
  112. PtrFoo *string `form:"ptr_foo"`
  113. PtrBar *string `form:"ptr_bar" binding:"required"`
  114. }
  115. type FooStructForMapPtrType struct {
  116. PtrBar *map[string]interface{} `form:"ptr_bar"`
  117. }
  118. func TestBindingDefault(t *testing.T) {
  119. assert.Equal(t, Form, Default("GET", ""))
  120. assert.Equal(t, Form, Default("GET", MIMEJSON))
  121. assert.Equal(t, JSON, Default("POST", MIMEJSON))
  122. assert.Equal(t, JSON, Default("PUT", MIMEJSON))
  123. assert.Equal(t, XML, Default("POST", MIMEXML))
  124. assert.Equal(t, XML, Default("PUT", MIMEXML2))
  125. assert.Equal(t, Form, Default("POST", MIMEPOSTForm))
  126. assert.Equal(t, Form, Default("PUT", MIMEPOSTForm))
  127. assert.Equal(t, FormMultipart, Default("POST", MIMEMultipartPOSTForm))
  128. assert.Equal(t, FormMultipart, Default("PUT", MIMEMultipartPOSTForm))
  129. assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
  130. assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
  131. assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
  132. assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
  133. assert.Equal(t, YAML, Default("POST", MIMEYAML))
  134. assert.Equal(t, YAML, Default("PUT", MIMEYAML))
  135. }
  136. func TestBindingJSONNilBody(t *testing.T) {
  137. var obj FooStruct
  138. req, _ := http.NewRequest(http.MethodPost, "/", nil)
  139. err := JSON.Bind(req, &obj)
  140. assert.Error(t, err)
  141. }
  142. func TestBindingJSON(t *testing.T) {
  143. testBodyBinding(t,
  144. JSON, "json",
  145. "/", "/",
  146. `{"foo": "bar"}`, `{"bar": "foo"}`)
  147. }
  148. func TestBindingJSONUseNumber(t *testing.T) {
  149. testBodyBindingUseNumber(t,
  150. JSON, "json",
  151. "/", "/",
  152. `{"foo": 123}`, `{"bar": "foo"}`)
  153. }
  154. func TestBindingJSONUseNumber2(t *testing.T) {
  155. testBodyBindingUseNumber2(t,
  156. JSON, "json",
  157. "/", "/",
  158. `{"foo": 123}`, `{"bar": "foo"}`)
  159. }
  160. func TestBindingJSONDisallowUnknownFields(t *testing.T) {
  161. testBodyBindingDisallowUnknownFields(t, JSON,
  162. "/", "/",
  163. `{"foo": "bar"}`, `{"foo": "bar", "what": "this"}`)
  164. }
  165. func TestBindingForm(t *testing.T) {
  166. testFormBinding(t, "POST",
  167. "/", "/",
  168. "foo=bar&bar=foo", "bar2=foo")
  169. }
  170. func TestBindingForm2(t *testing.T) {
  171. testFormBinding(t, "GET",
  172. "/?foo=bar&bar=foo", "/?bar2=foo",
  173. "", "")
  174. }
  175. func TestBindingFormEmbeddedStruct(t *testing.T) {
  176. testFormBindingEmbeddedStruct(t, "POST",
  177. "/", "/",
  178. "page=1&size=2&appkey=test-appkey", "bar2=foo")
  179. }
  180. func TestBindingFormEmbeddedStruct2(t *testing.T) {
  181. testFormBindingEmbeddedStruct(t, "GET",
  182. "/?page=1&size=2&appkey=test-appkey", "/?bar2=foo",
  183. "", "")
  184. }
  185. func TestBindingFormDefaultValue(t *testing.T) {
  186. testFormBindingDefaultValue(t, "POST",
  187. "/", "/",
  188. "foo=bar", "bar2=foo")
  189. }
  190. func TestBindingFormDefaultValue2(t *testing.T) {
  191. testFormBindingDefaultValue(t, "GET",
  192. "/?foo=bar", "/?bar2=foo",
  193. "", "")
  194. }
  195. func TestBindingFormForTime(t *testing.T) {
  196. testFormBindingForTime(t, "POST",
  197. "/", "/",
  198. "time_foo=2017-11-15&time_bar=&createTime=1562400033000000123&unixTime=1562400033", "bar2=foo")
  199. testFormBindingForTimeNotUnixFormat(t, "POST",
  200. "/", "/",
  201. "time_foo=2017-11-15&createTime=bad&unixTime=bad", "bar2=foo")
  202. testFormBindingForTimeNotFormat(t, "POST",
  203. "/", "/",
  204. "time_foo=2017-11-15", "bar2=foo")
  205. testFormBindingForTimeFailFormat(t, "POST",
  206. "/", "/",
  207. "time_foo=2017-11-15", "bar2=foo")
  208. testFormBindingForTimeFailLocation(t, "POST",
  209. "/", "/",
  210. "time_foo=2017-11-15", "bar2=foo")
  211. }
  212. func TestBindingFormForTime2(t *testing.T) {
  213. testFormBindingForTime(t, "GET",
  214. "/?time_foo=2017-11-15&time_bar=&createTime=1562400033000000123&unixTime=1562400033", "/?bar2=foo",
  215. "", "")
  216. testFormBindingForTimeNotUnixFormat(t, "POST",
  217. "/", "/",
  218. "time_foo=2017-11-15&createTime=bad&unixTime=bad", "bar2=foo")
  219. testFormBindingForTimeNotFormat(t, "GET",
  220. "/?time_foo=2017-11-15", "/?bar2=foo",
  221. "", "")
  222. testFormBindingForTimeFailFormat(t, "GET",
  223. "/?time_foo=2017-11-15", "/?bar2=foo",
  224. "", "")
  225. testFormBindingForTimeFailLocation(t, "GET",
  226. "/?time_foo=2017-11-15", "/?bar2=foo",
  227. "", "")
  228. }
  229. func TestFormBindingIgnoreField(t *testing.T) {
  230. testFormBindingIgnoreField(t, "POST",
  231. "/", "/",
  232. "-=bar", "")
  233. }
  234. func TestBindingFormInvalidName(t *testing.T) {
  235. testFormBindingInvalidName(t, "POST",
  236. "/", "/",
  237. "test_name=bar", "bar2=foo")
  238. }
  239. func TestBindingFormInvalidName2(t *testing.T) {
  240. testFormBindingInvalidName2(t, "POST",
  241. "/", "/",
  242. "map_foo=bar", "bar2=foo")
  243. }
  244. func TestBindingFormForType(t *testing.T) {
  245. testFormBindingForType(t, "POST",
  246. "/", "/",
  247. "map_foo={\"bar\":123}", "map_foo=1", "Map")
  248. testFormBindingForType(t, "POST",
  249. "/", "/",
  250. "slice_foo=1&slice_foo=2", "bar2=1&bar2=2", "Slice")
  251. testFormBindingForType(t, "GET",
  252. "/?slice_foo=1&slice_foo=2", "/?bar2=1&bar2=2",
  253. "", "", "Slice")
  254. testFormBindingForType(t, "POST",
  255. "/", "/",
  256. "slice_map_foo=1&slice_map_foo=2", "bar2=1&bar2=2", "SliceMap")
  257. testFormBindingForType(t, "GET",
  258. "/?slice_map_foo=1&slice_map_foo=2", "/?bar2=1&bar2=2",
  259. "", "", "SliceMap")
  260. testFormBindingForType(t, "POST",
  261. "/", "/",
  262. "ptr_bar=test", "bar2=test", "Ptr")
  263. testFormBindingForType(t, "GET",
  264. "/?ptr_bar=test", "/?bar2=test",
  265. "", "", "Ptr")
  266. testFormBindingForType(t, "POST",
  267. "/", "/",
  268. "idx=123", "id1=1", "Struct")
  269. testFormBindingForType(t, "GET",
  270. "/?idx=123", "/?id1=1",
  271. "", "", "Struct")
  272. testFormBindingForType(t, "POST",
  273. "/", "/",
  274. "name=thinkerou", "name1=ou", "StructPointer")
  275. testFormBindingForType(t, "GET",
  276. "/?name=thinkerou", "/?name1=ou",
  277. "", "", "StructPointer")
  278. }
  279. func TestBindingQuery(t *testing.T) {
  280. testQueryBinding(t, "POST",
  281. "/?foo=bar&bar=foo", "/",
  282. "foo=unused", "bar2=foo")
  283. }
  284. func TestBindingQuery2(t *testing.T) {
  285. testQueryBinding(t, "GET",
  286. "/?foo=bar&bar=foo", "/?bar2=foo",
  287. "foo=unused", "")
  288. }
  289. func TestBindingQueryFail(t *testing.T) {
  290. testQueryBindingFail(t, "POST",
  291. "/?map_foo=", "/",
  292. "map_foo=unused", "bar2=foo")
  293. }
  294. func TestBindingQueryFail2(t *testing.T) {
  295. testQueryBindingFail(t, "GET",
  296. "/?map_foo=", "/?bar2=foo",
  297. "map_foo=unused", "")
  298. }
  299. func TestBindingQueryBoolFail(t *testing.T) {
  300. testQueryBindingBoolFail(t, "GET",
  301. "/?bool_foo=fasl", "/?bar2=foo",
  302. "bool_foo=unused", "")
  303. }
  304. func TestBindingXML(t *testing.T) {
  305. testBodyBinding(t,
  306. XML, "xml",
  307. "/", "/",
  308. "<map><foo>bar</foo></map>", "<map><bar>foo</bar></map>")
  309. }
  310. func TestBindingXMLFail(t *testing.T) {
  311. testBodyBindingFail(t,
  312. XML, "xml",
  313. "/", "/",
  314. "<map><foo>bar<foo></map>", "<map><bar>foo</bar></map>")
  315. }
  316. func TestBindingYAML(t *testing.T) {
  317. testBodyBinding(t,
  318. YAML, "yaml",
  319. "/", "/",
  320. `foo: bar`, `bar: foo`)
  321. }
  322. func TestBindingYAMLFail(t *testing.T) {
  323. testBodyBindingFail(t,
  324. YAML, "yaml",
  325. "/", "/",
  326. `foo:\nbar`, `bar: foo`)
  327. }
  328. func createFormPostRequest(t *testing.T) *http.Request {
  329. req, err := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo"))
  330. assert.NoError(t, err)
  331. req.Header.Set("Content-Type", MIMEPOSTForm)
  332. return req
  333. }
  334. func createDefaultFormPostRequest(t *testing.T) *http.Request {
  335. req, err := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar"))
  336. assert.NoError(t, err)
  337. req.Header.Set("Content-Type", MIMEPOSTForm)
  338. return req
  339. }
  340. func createFormPostRequestForMap(t *testing.T) *http.Request {
  341. req, err := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo={\"bar\":123}"))
  342. assert.NoError(t, err)
  343. req.Header.Set("Content-Type", MIMEPOSTForm)
  344. return req
  345. }
  346. func createFormPostRequestForMapFail(t *testing.T) *http.Request {
  347. req, err := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=hello"))
  348. assert.NoError(t, err)
  349. req.Header.Set("Content-Type", MIMEPOSTForm)
  350. return req
  351. }
  352. func createFormFilesMultipartRequest(t *testing.T) *http.Request {
  353. boundary := "--testboundary"
  354. body := new(bytes.Buffer)
  355. mw := multipart.NewWriter(body)
  356. defer mw.Close()
  357. assert.NoError(t, mw.SetBoundary(boundary))
  358. assert.NoError(t, mw.WriteField("foo", "bar"))
  359. assert.NoError(t, mw.WriteField("bar", "foo"))
  360. f, err := os.Open("form.go")
  361. assert.NoError(t, err)
  362. defer f.Close()
  363. fw, err1 := mw.CreateFormFile("file", "form.go")
  364. assert.NoError(t, err1)
  365. io.Copy(fw, f)
  366. req, err2 := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
  367. assert.NoError(t, err2)
  368. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  369. return req
  370. }
  371. func createFormFilesMultipartRequestFail(t *testing.T) *http.Request {
  372. boundary := "--testboundary"
  373. body := new(bytes.Buffer)
  374. mw := multipart.NewWriter(body)
  375. defer mw.Close()
  376. assert.NoError(t, mw.SetBoundary(boundary))
  377. assert.NoError(t, mw.WriteField("foo", "bar"))
  378. assert.NoError(t, mw.WriteField("bar", "foo"))
  379. f, err := os.Open("form.go")
  380. assert.NoError(t, err)
  381. defer f.Close()
  382. fw, err1 := mw.CreateFormFile("file_foo", "form_foo.go")
  383. assert.NoError(t, err1)
  384. io.Copy(fw, f)
  385. req, err2 := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
  386. assert.NoError(t, err2)
  387. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  388. return req
  389. }
  390. func createFormMultipartRequest(t *testing.T) *http.Request {
  391. boundary := "--testboundary"
  392. body := new(bytes.Buffer)
  393. mw := multipart.NewWriter(body)
  394. defer mw.Close()
  395. assert.NoError(t, mw.SetBoundary(boundary))
  396. assert.NoError(t, mw.WriteField("foo", "bar"))
  397. assert.NoError(t, mw.WriteField("bar", "foo"))
  398. req, err := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
  399. assert.NoError(t, err)
  400. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  401. return req
  402. }
  403. func createFormMultipartRequestForMap(t *testing.T) *http.Request {
  404. boundary := "--testboundary"
  405. body := new(bytes.Buffer)
  406. mw := multipart.NewWriter(body)
  407. defer mw.Close()
  408. assert.NoError(t, mw.SetBoundary(boundary))
  409. assert.NoError(t, mw.WriteField("map_foo", "{\"bar\":123, \"name\":\"thinkerou\", \"pai\": 3.14}"))
  410. req, err := http.NewRequest("POST", "/?map_foo=getfoo", body)
  411. assert.NoError(t, err)
  412. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  413. return req
  414. }
  415. func createFormMultipartRequestForMapFail(t *testing.T) *http.Request {
  416. boundary := "--testboundary"
  417. body := new(bytes.Buffer)
  418. mw := multipart.NewWriter(body)
  419. defer mw.Close()
  420. assert.NoError(t, mw.SetBoundary(boundary))
  421. assert.NoError(t, mw.WriteField("map_foo", "3.14"))
  422. req, err := http.NewRequest("POST", "/?map_foo=getfoo", body)
  423. assert.NoError(t, err)
  424. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  425. return req
  426. }
  427. func TestBindingFormPost(t *testing.T) {
  428. req := createFormPostRequest(t)
  429. var obj FooBarStruct
  430. assert.NoError(t, FormPost.Bind(req, &obj))
  431. assert.Equal(t, "form-urlencoded", FormPost.Name())
  432. assert.Equal(t, "bar", obj.Foo)
  433. assert.Equal(t, "foo", obj.Bar)
  434. }
  435. func TestBindingDefaultValueFormPost(t *testing.T) {
  436. req := createDefaultFormPostRequest(t)
  437. var obj FooDefaultBarStruct
  438. assert.NoError(t, FormPost.Bind(req, &obj))
  439. assert.Equal(t, "bar", obj.Foo)
  440. assert.Equal(t, "hello", obj.Bar)
  441. }
  442. func TestBindingFormPostForMap(t *testing.T) {
  443. req := createFormPostRequestForMap(t)
  444. var obj FooStructForMapType
  445. err := FormPost.Bind(req, &obj)
  446. assert.NoError(t, err)
  447. assert.Equal(t, float64(123), obj.MapFoo["bar"].(float64))
  448. }
  449. func TestBindingFormPostForMapFail(t *testing.T) {
  450. req := createFormPostRequestForMapFail(t)
  451. var obj FooStructForMapType
  452. err := FormPost.Bind(req, &obj)
  453. assert.Error(t, err)
  454. }
  455. func TestBindingFormFilesMultipart(t *testing.T) {
  456. req := createFormFilesMultipartRequest(t)
  457. var obj FooBarFileStruct
  458. FormMultipart.Bind(req, &obj)
  459. // file from os
  460. f, _ := os.Open("form.go")
  461. defer f.Close()
  462. fileActual, _ := ioutil.ReadAll(f)
  463. // file from multipart
  464. mf, _ := obj.File.Open()
  465. defer mf.Close()
  466. fileExpect, _ := ioutil.ReadAll(mf)
  467. assert.Equal(t, FormMultipart.Name(), "multipart/form-data")
  468. assert.Equal(t, obj.Foo, "bar")
  469. assert.Equal(t, obj.Bar, "foo")
  470. assert.Equal(t, fileExpect, fileActual)
  471. }
  472. func TestBindingFormFilesMultipartFail(t *testing.T) {
  473. req := createFormFilesMultipartRequestFail(t)
  474. var obj FooBarFileFailStruct
  475. err := FormMultipart.Bind(req, &obj)
  476. assert.Error(t, err)
  477. }
  478. func TestBindingFormMultipart(t *testing.T) {
  479. req := createFormMultipartRequest(t)
  480. var obj FooBarStruct
  481. assert.NoError(t, FormMultipart.Bind(req, &obj))
  482. assert.Equal(t, "multipart/form-data", FormMultipart.Name())
  483. assert.Equal(t, "bar", obj.Foo)
  484. assert.Equal(t, "foo", obj.Bar)
  485. }
  486. func TestBindingFormMultipartForMap(t *testing.T) {
  487. req := createFormMultipartRequestForMap(t)
  488. var obj FooStructForMapType
  489. err := FormMultipart.Bind(req, &obj)
  490. assert.NoError(t, err)
  491. assert.Equal(t, float64(123), obj.MapFoo["bar"].(float64))
  492. assert.Equal(t, "thinkerou", obj.MapFoo["name"].(string))
  493. assert.Equal(t, float64(3.14), obj.MapFoo["pai"].(float64))
  494. }
  495. func TestBindingFormMultipartForMapFail(t *testing.T) {
  496. req := createFormMultipartRequestForMapFail(t)
  497. var obj FooStructForMapType
  498. err := FormMultipart.Bind(req, &obj)
  499. assert.Error(t, err)
  500. }
  501. func TestBindingProtoBuf(t *testing.T) {
  502. test := &protoexample.Test{
  503. Label: proto.String("yes"),
  504. }
  505. data, _ := proto.Marshal(test)
  506. testProtoBodyBinding(t,
  507. ProtoBuf, "protobuf",
  508. "/", "/",
  509. string(data), string(data[1:]))
  510. }
  511. func TestBindingProtoBufFail(t *testing.T) {
  512. test := &protoexample.Test{
  513. Label: proto.String("yes"),
  514. }
  515. data, _ := proto.Marshal(test)
  516. testProtoBodyBindingFail(t,
  517. ProtoBuf, "protobuf",
  518. "/", "/",
  519. string(data), string(data[1:]))
  520. }
  521. func TestBindingMsgPack(t *testing.T) {
  522. test := FooStruct{
  523. Foo: "bar",
  524. }
  525. h := new(codec.MsgpackHandle)
  526. assert.NotNil(t, h)
  527. buf := bytes.NewBuffer([]byte{})
  528. assert.NotNil(t, buf)
  529. err := codec.NewEncoder(buf, h).Encode(test)
  530. assert.NoError(t, err)
  531. data := buf.Bytes()
  532. testMsgPackBodyBinding(t,
  533. MsgPack, "msgpack",
  534. "/", "/",
  535. string(data), string(data[1:]))
  536. }
  537. func TestValidationFails(t *testing.T) {
  538. var obj FooStruct
  539. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  540. err := JSON.Bind(req, &obj)
  541. assert.Error(t, err)
  542. }
  543. func TestValidationDisabled(t *testing.T) {
  544. backup := Validator
  545. Validator = nil
  546. defer func() { Validator = backup }()
  547. var obj FooStruct
  548. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  549. err := JSON.Bind(req, &obj)
  550. assert.NoError(t, err)
  551. }
  552. func TestRequiredSucceeds(t *testing.T) {
  553. type HogeStruct struct {
  554. Hoge *int `json:"hoge" binding:"required"`
  555. }
  556. var obj HogeStruct
  557. req := requestWithBody("POST", "/", `{"hoge": 0}`)
  558. err := JSON.Bind(req, &obj)
  559. assert.NoError(t, err)
  560. }
  561. func TestRequiredFails(t *testing.T) {
  562. type HogeStruct struct {
  563. Hoge *int `json:"foo" binding:"required"`
  564. }
  565. var obj HogeStruct
  566. req := requestWithBody("POST", "/", `{"boen": 0}`)
  567. err := JSON.Bind(req, &obj)
  568. assert.Error(t, err)
  569. }
  570. func TestHeaderBinding(t *testing.T) {
  571. h := Header
  572. assert.Equal(t, "header", h.Name())
  573. type tHeader struct {
  574. Limit int `header:"limit"`
  575. }
  576. var theader tHeader
  577. req := requestWithBody("GET", "/", "")
  578. req.Header.Add("limit", "1000")
  579. assert.NoError(t, h.Bind(req, &theader))
  580. assert.Equal(t, 1000, theader.Limit)
  581. req = requestWithBody("GET", "/", "")
  582. req.Header.Add("fail", `{fail:fail}`)
  583. type failStruct struct {
  584. Fail map[string]interface{} `header:"fail"`
  585. }
  586. err := h.Bind(req, &failStruct{})
  587. assert.Error(t, err)
  588. }
  589. func TestUriBinding(t *testing.T) {
  590. b := Uri
  591. assert.Equal(t, "uri", b.Name())
  592. type Tag struct {
  593. Name string `uri:"name"`
  594. }
  595. var tag Tag
  596. m := make(map[string][]string)
  597. m["name"] = []string{"thinkerou"}
  598. assert.NoError(t, b.BindUri(m, &tag))
  599. assert.Equal(t, "thinkerou", tag.Name)
  600. type NotSupportStruct struct {
  601. Name map[string]interface{} `uri:"name"`
  602. }
  603. var not NotSupportStruct
  604. assert.Error(t, b.BindUri(m, &not))
  605. assert.Equal(t, map[string]interface{}(nil), not.Name)
  606. }
  607. func TestUriInnerBinding(t *testing.T) {
  608. type Tag struct {
  609. Name string `uri:"name"`
  610. S struct {
  611. Age int `uri:"age"`
  612. }
  613. }
  614. expectedName := "mike"
  615. expectedAge := 25
  616. m := map[string][]string{
  617. "name": {expectedName},
  618. "age": {strconv.Itoa(expectedAge)},
  619. }
  620. var tag Tag
  621. assert.NoError(t, Uri.BindUri(m, &tag))
  622. assert.Equal(t, tag.Name, expectedName)
  623. assert.Equal(t, tag.S.Age, expectedAge)
  624. }
  625. func testFormBindingEmbeddedStruct(t *testing.T, method, path, badPath, body, badBody string) {
  626. b := Form
  627. assert.Equal(t, "form", b.Name())
  628. obj := QueryTest{}
  629. req := requestWithBody(method, path, body)
  630. if method == "POST" {
  631. req.Header.Add("Content-Type", MIMEPOSTForm)
  632. }
  633. err := b.Bind(req, &obj)
  634. assert.NoError(t, err)
  635. assert.Equal(t, 1, obj.Page)
  636. assert.Equal(t, 2, obj.Size)
  637. assert.Equal(t, "test-appkey", obj.Appkey)
  638. }
  639. func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) {
  640. b := Form
  641. assert.Equal(t, "form", b.Name())
  642. obj := FooBarStruct{}
  643. req := requestWithBody(method, path, body)
  644. if method == "POST" {
  645. req.Header.Add("Content-Type", MIMEPOSTForm)
  646. }
  647. err := b.Bind(req, &obj)
  648. assert.NoError(t, err)
  649. assert.Equal(t, "bar", obj.Foo)
  650. assert.Equal(t, "foo", obj.Bar)
  651. obj = FooBarStruct{}
  652. req = requestWithBody(method, badPath, badBody)
  653. err = JSON.Bind(req, &obj)
  654. assert.Error(t, err)
  655. }
  656. func testFormBindingDefaultValue(t *testing.T, method, path, badPath, body, badBody string) {
  657. b := Form
  658. assert.Equal(t, "form", b.Name())
  659. obj := FooDefaultBarStruct{}
  660. req := requestWithBody(method, path, body)
  661. if method == "POST" {
  662. req.Header.Add("Content-Type", MIMEPOSTForm)
  663. }
  664. err := b.Bind(req, &obj)
  665. assert.NoError(t, err)
  666. assert.Equal(t, "bar", obj.Foo)
  667. assert.Equal(t, "hello", obj.Bar)
  668. obj = FooDefaultBarStruct{}
  669. req = requestWithBody(method, badPath, badBody)
  670. err = JSON.Bind(req, &obj)
  671. assert.Error(t, err)
  672. }
  673. func TestFormBindingFail(t *testing.T) {
  674. b := Form
  675. assert.Equal(t, "form", b.Name())
  676. obj := FooBarStruct{}
  677. req, _ := http.NewRequest("POST", "/", nil)
  678. err := b.Bind(req, &obj)
  679. assert.Error(t, err)
  680. }
  681. func TestFormBindingMultipartFail(t *testing.T) {
  682. obj := FooBarStruct{}
  683. req, err := http.NewRequest("POST", "/", strings.NewReader("foo=bar"))
  684. assert.NoError(t, err)
  685. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+";boundary=testboundary")
  686. _, err = req.MultipartReader()
  687. assert.NoError(t, err)
  688. err = Form.Bind(req, &obj)
  689. assert.Error(t, err)
  690. }
  691. func TestFormPostBindingFail(t *testing.T) {
  692. b := FormPost
  693. assert.Equal(t, "form-urlencoded", b.Name())
  694. obj := FooBarStruct{}
  695. req, _ := http.NewRequest("POST", "/", nil)
  696. err := b.Bind(req, &obj)
  697. assert.Error(t, err)
  698. }
  699. func TestFormMultipartBindingFail(t *testing.T) {
  700. b := FormMultipart
  701. assert.Equal(t, "multipart/form-data", b.Name())
  702. obj := FooBarStruct{}
  703. req, _ := http.NewRequest("POST", "/", nil)
  704. err := b.Bind(req, &obj)
  705. assert.Error(t, err)
  706. }
  707. func testFormBindingForTime(t *testing.T, method, path, badPath, body, badBody string) {
  708. b := Form
  709. assert.Equal(t, "form", b.Name())
  710. obj := FooBarStructForTimeType{}
  711. req := requestWithBody(method, path, body)
  712. if method == "POST" {
  713. req.Header.Add("Content-Type", MIMEPOSTForm)
  714. }
  715. err := b.Bind(req, &obj)
  716. assert.NoError(t, err)
  717. assert.Equal(t, int64(1510675200), obj.TimeFoo.Unix())
  718. assert.Equal(t, "Asia/Chongqing", obj.TimeFoo.Location().String())
  719. assert.Equal(t, int64(-62135596800), obj.TimeBar.Unix())
  720. assert.Equal(t, "UTC", obj.TimeBar.Location().String())
  721. assert.Equal(t, int64(1562400033000000123), obj.CreateTime.UnixNano())
  722. assert.Equal(t, int64(1562400033), obj.UnixTime.Unix())
  723. obj = FooBarStructForTimeType{}
  724. req = requestWithBody(method, badPath, badBody)
  725. err = JSON.Bind(req, &obj)
  726. assert.Error(t, err)
  727. }
  728. func testFormBindingForTimeNotUnixFormat(t *testing.T, method, path, badPath, body, badBody string) {
  729. b := Form
  730. assert.Equal(t, "form", b.Name())
  731. obj := FooStructForTimeTypeNotUnixFormat{}
  732. req := requestWithBody(method, path, body)
  733. if method == "POST" {
  734. req.Header.Add("Content-Type", MIMEPOSTForm)
  735. }
  736. err := b.Bind(req, &obj)
  737. assert.Error(t, err)
  738. obj = FooStructForTimeTypeNotUnixFormat{}
  739. req = requestWithBody(method, badPath, badBody)
  740. err = JSON.Bind(req, &obj)
  741. assert.Error(t, err)
  742. }
  743. func testFormBindingForTimeNotFormat(t *testing.T, method, path, badPath, body, badBody string) {
  744. b := Form
  745. assert.Equal(t, "form", b.Name())
  746. obj := FooStructForTimeTypeNotFormat{}
  747. req := requestWithBody(method, path, body)
  748. if method == "POST" {
  749. req.Header.Add("Content-Type", MIMEPOSTForm)
  750. }
  751. err := b.Bind(req, &obj)
  752. assert.Error(t, err)
  753. obj = FooStructForTimeTypeNotFormat{}
  754. req = requestWithBody(method, badPath, badBody)
  755. err = JSON.Bind(req, &obj)
  756. assert.Error(t, err)
  757. }
  758. func testFormBindingForTimeFailFormat(t *testing.T, method, path, badPath, body, badBody string) {
  759. b := Form
  760. assert.Equal(t, "form", b.Name())
  761. obj := FooStructForTimeTypeFailFormat{}
  762. req := requestWithBody(method, path, body)
  763. if method == "POST" {
  764. req.Header.Add("Content-Type", MIMEPOSTForm)
  765. }
  766. err := b.Bind(req, &obj)
  767. assert.Error(t, err)
  768. obj = FooStructForTimeTypeFailFormat{}
  769. req = requestWithBody(method, badPath, badBody)
  770. err = JSON.Bind(req, &obj)
  771. assert.Error(t, err)
  772. }
  773. func testFormBindingForTimeFailLocation(t *testing.T, method, path, badPath, body, badBody string) {
  774. b := Form
  775. assert.Equal(t, "form", b.Name())
  776. obj := FooStructForTimeTypeFailLocation{}
  777. req := requestWithBody(method, path, body)
  778. if method == "POST" {
  779. req.Header.Add("Content-Type", MIMEPOSTForm)
  780. }
  781. err := b.Bind(req, &obj)
  782. assert.Error(t, err)
  783. obj = FooStructForTimeTypeFailLocation{}
  784. req = requestWithBody(method, badPath, badBody)
  785. err = JSON.Bind(req, &obj)
  786. assert.Error(t, err)
  787. }
  788. func testFormBindingIgnoreField(t *testing.T, method, path, badPath, body, badBody string) {
  789. b := Form
  790. assert.Equal(t, "form", b.Name())
  791. obj := FooStructForIgnoreFormTag{}
  792. req := requestWithBody(method, path, body)
  793. if method == "POST" {
  794. req.Header.Add("Content-Type", MIMEPOSTForm)
  795. }
  796. err := b.Bind(req, &obj)
  797. assert.NoError(t, err)
  798. assert.Nil(t, obj.Foo)
  799. }
  800. func testFormBindingInvalidName(t *testing.T, method, path, badPath, body, badBody string) {
  801. b := Form
  802. assert.Equal(t, "form", b.Name())
  803. obj := InvalidNameType{}
  804. req := requestWithBody(method, path, body)
  805. if method == "POST" {
  806. req.Header.Add("Content-Type", MIMEPOSTForm)
  807. }
  808. err := b.Bind(req, &obj)
  809. assert.NoError(t, err)
  810. assert.Equal(t, "", obj.TestName)
  811. obj = InvalidNameType{}
  812. req = requestWithBody(method, badPath, badBody)
  813. err = JSON.Bind(req, &obj)
  814. assert.Error(t, err)
  815. }
  816. func testFormBindingInvalidName2(t *testing.T, method, path, badPath, body, badBody string) {
  817. b := Form
  818. assert.Equal(t, "form", b.Name())
  819. obj := InvalidNameMapType{}
  820. req := requestWithBody(method, path, body)
  821. if method == "POST" {
  822. req.Header.Add("Content-Type", MIMEPOSTForm)
  823. }
  824. err := b.Bind(req, &obj)
  825. assert.Error(t, err)
  826. obj = InvalidNameMapType{}
  827. req = requestWithBody(method, badPath, badBody)
  828. err = JSON.Bind(req, &obj)
  829. assert.Error(t, err)
  830. }
  831. func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody string, typ string) {
  832. b := Form
  833. assert.Equal(t, "form", b.Name())
  834. req := requestWithBody(method, path, body)
  835. if method == "POST" {
  836. req.Header.Add("Content-Type", MIMEPOSTForm)
  837. }
  838. switch typ {
  839. case "Slice":
  840. obj := FooStructForSliceType{}
  841. err := b.Bind(req, &obj)
  842. assert.NoError(t, err)
  843. assert.Equal(t, []int{1, 2}, obj.SliceFoo)
  844. obj = FooStructForSliceType{}
  845. req = requestWithBody(method, badPath, badBody)
  846. err = JSON.Bind(req, &obj)
  847. assert.Error(t, err)
  848. case "Struct":
  849. obj := FooStructForStructType{}
  850. err := b.Bind(req, &obj)
  851. assert.NoError(t, err)
  852. assert.Equal(t,
  853. struct {
  854. Idx int "form:\"idx\""
  855. }(struct {
  856. Idx int "form:\"idx\""
  857. }{Idx: 123}),
  858. obj.StructFoo)
  859. case "StructPointer":
  860. obj := FooStructForStructPointerType{}
  861. err := b.Bind(req, &obj)
  862. assert.NoError(t, err)
  863. assert.Equal(t,
  864. struct {
  865. Name string "form:\"name\""
  866. }(struct {
  867. Name string "form:\"name\""
  868. }{Name: "thinkerou"}),
  869. *obj.StructPointerFoo)
  870. case "Map":
  871. obj := FooStructForMapType{}
  872. err := b.Bind(req, &obj)
  873. assert.NoError(t, err)
  874. assert.Equal(t, float64(123), obj.MapFoo["bar"].(float64))
  875. case "SliceMap":
  876. obj := FooStructForSliceMapType{}
  877. err := b.Bind(req, &obj)
  878. assert.Error(t, err)
  879. case "Ptr":
  880. obj := FooStructForStringPtrType{}
  881. err := b.Bind(req, &obj)
  882. assert.NoError(t, err)
  883. assert.Nil(t, obj.PtrFoo)
  884. assert.Equal(t, "test", *obj.PtrBar)
  885. obj = FooStructForStringPtrType{}
  886. obj.PtrBar = new(string)
  887. err = b.Bind(req, &obj)
  888. assert.NoError(t, err)
  889. assert.Equal(t, "test", *obj.PtrBar)
  890. objErr := FooStructForMapPtrType{}
  891. err = b.Bind(req, &objErr)
  892. assert.Error(t, err)
  893. obj = FooStructForStringPtrType{}
  894. req = requestWithBody(method, badPath, badBody)
  895. err = b.Bind(req, &obj)
  896. assert.Error(t, err)
  897. }
  898. }
  899. func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) {
  900. b := Query
  901. assert.Equal(t, "query", b.Name())
  902. obj := FooBarStruct{}
  903. req := requestWithBody(method, path, body)
  904. if method == "POST" {
  905. req.Header.Add("Content-Type", MIMEPOSTForm)
  906. }
  907. err := b.Bind(req, &obj)
  908. assert.NoError(t, err)
  909. assert.Equal(t, "bar", obj.Foo)
  910. assert.Equal(t, "foo", obj.Bar)
  911. }
  912. func testQueryBindingFail(t *testing.T, method, path, badPath, body, badBody string) {
  913. b := Query
  914. assert.Equal(t, "query", b.Name())
  915. obj := FooStructForMapType{}
  916. req := requestWithBody(method, path, body)
  917. if method == "POST" {
  918. req.Header.Add("Content-Type", MIMEPOSTForm)
  919. }
  920. err := b.Bind(req, &obj)
  921. assert.Error(t, err)
  922. }
  923. func testQueryBindingBoolFail(t *testing.T, method, path, badPath, body, badBody string) {
  924. b := Query
  925. assert.Equal(t, "query", b.Name())
  926. obj := FooStructForBoolType{}
  927. req := requestWithBody(method, path, body)
  928. if method == "POST" {
  929. req.Header.Add("Content-Type", MIMEPOSTForm)
  930. }
  931. err := b.Bind(req, &obj)
  932. assert.Error(t, err)
  933. }
  934. func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  935. assert.Equal(t, name, b.Name())
  936. obj := FooStruct{}
  937. req := requestWithBody("POST", path, body)
  938. err := b.Bind(req, &obj)
  939. assert.NoError(t, err)
  940. assert.Equal(t, "bar", obj.Foo)
  941. obj = FooStruct{}
  942. req = requestWithBody("POST", badPath, badBody)
  943. err = JSON.Bind(req, &obj)
  944. assert.Error(t, err)
  945. }
  946. func testBodyBindingUseNumber(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  947. assert.Equal(t, name, b.Name())
  948. obj := FooStructUseNumber{}
  949. req := requestWithBody("POST", path, body)
  950. EnableDecoderUseNumber = true
  951. err := b.Bind(req, &obj)
  952. assert.NoError(t, err)
  953. // we hope it is int64(123)
  954. v, e := obj.Foo.(json.Number).Int64()
  955. assert.NoError(t, e)
  956. assert.Equal(t, int64(123), v)
  957. obj = FooStructUseNumber{}
  958. req = requestWithBody("POST", badPath, badBody)
  959. err = JSON.Bind(req, &obj)
  960. assert.Error(t, err)
  961. }
  962. func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  963. assert.Equal(t, name, b.Name())
  964. obj := FooStructUseNumber{}
  965. req := requestWithBody("POST", path, body)
  966. EnableDecoderUseNumber = false
  967. err := b.Bind(req, &obj)
  968. assert.NoError(t, err)
  969. // it will return float64(123) if not use EnableDecoderUseNumber
  970. // maybe it is not hoped
  971. assert.Equal(t, float64(123), obj.Foo)
  972. obj = FooStructUseNumber{}
  973. req = requestWithBody("POST", badPath, badBody)
  974. err = JSON.Bind(req, &obj)
  975. assert.Error(t, err)
  976. }
  977. func testBodyBindingDisallowUnknownFields(t *testing.T, b Binding, path, badPath, body, badBody string) {
  978. EnableDecoderDisallowUnknownFields = true
  979. defer func() {
  980. EnableDecoderDisallowUnknownFields = false
  981. }()
  982. obj := FooStructDisallowUnknownFields{}
  983. req := requestWithBody("POST", path, body)
  984. err := b.Bind(req, &obj)
  985. assert.NoError(t, err)
  986. assert.Equal(t, "bar", obj.Foo)
  987. obj = FooStructDisallowUnknownFields{}
  988. req = requestWithBody("POST", badPath, badBody)
  989. err = JSON.Bind(req, &obj)
  990. assert.Error(t, err)
  991. assert.Contains(t, err.Error(), "what")
  992. }
  993. func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  994. assert.Equal(t, name, b.Name())
  995. obj := FooStruct{}
  996. req := requestWithBody("POST", path, body)
  997. err := b.Bind(req, &obj)
  998. assert.Error(t, err)
  999. assert.Equal(t, "", obj.Foo)
  1000. obj = FooStruct{}
  1001. req = requestWithBody("POST", badPath, badBody)
  1002. err = JSON.Bind(req, &obj)
  1003. assert.Error(t, err)
  1004. }
  1005. func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1006. assert.Equal(t, name, b.Name())
  1007. obj := protoexample.Test{}
  1008. req := requestWithBody("POST", path, body)
  1009. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1010. err := b.Bind(req, &obj)
  1011. assert.NoError(t, err)
  1012. assert.Equal(t, "yes", *obj.Label)
  1013. obj = protoexample.Test{}
  1014. req = requestWithBody("POST", badPath, badBody)
  1015. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1016. err = ProtoBuf.Bind(req, &obj)
  1017. assert.Error(t, err)
  1018. }
  1019. type hook struct{}
  1020. func (h hook) Read([]byte) (int, error) {
  1021. return 0, errors.New("error")
  1022. }
  1023. func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1024. assert.Equal(t, name, b.Name())
  1025. obj := protoexample.Test{}
  1026. req := requestWithBody("POST", path, body)
  1027. req.Body = ioutil.NopCloser(&hook{})
  1028. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1029. err := b.Bind(req, &obj)
  1030. assert.Error(t, err)
  1031. obj = protoexample.Test{}
  1032. req = requestWithBody("POST", badPath, badBody)
  1033. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1034. err = ProtoBuf.Bind(req, &obj)
  1035. assert.Error(t, err)
  1036. }
  1037. func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1038. assert.Equal(t, name, b.Name())
  1039. obj := FooStruct{}
  1040. req := requestWithBody("POST", path, body)
  1041. req.Header.Add("Content-Type", MIMEMSGPACK)
  1042. err := b.Bind(req, &obj)
  1043. assert.NoError(t, err)
  1044. assert.Equal(t, "bar", obj.Foo)
  1045. obj = FooStruct{}
  1046. req = requestWithBody("POST", badPath, badBody)
  1047. req.Header.Add("Content-Type", MIMEMSGPACK)
  1048. err = MsgPack.Bind(req, &obj)
  1049. assert.Error(t, err)
  1050. }
  1051. func requestWithBody(method, path, body string) (req *http.Request) {
  1052. req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
  1053. return
  1054. }