binding_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. "github.com/gin-gonic/gin/binding/example"
  8. "github.com/golang/protobuf/proto"
  9. "net/http"
  10. "testing"
  11. "github.com/stretchr/testify/assert"
  12. )
  13. type FooStruct struct {
  14. Foo string `json:"foo" form:"foo" xml:"foo" binding:"required"`
  15. }
  16. type FooBarStruct struct {
  17. FooStruct
  18. Bar string `json:"bar" form:"bar" xml:"bar" binding:"required"`
  19. }
  20. func TestBindingDefault(t *testing.T) {
  21. assert.Equal(t, Default("GET", ""), Form)
  22. assert.Equal(t, Default("GET", MIMEJSON), Form)
  23. assert.Equal(t, Default("POST", MIMEJSON), JSON)
  24. assert.Equal(t, Default("PUT", MIMEJSON), JSON)
  25. assert.Equal(t, Default("POST", MIMEXML), XML)
  26. assert.Equal(t, Default("PUT", MIMEXML2), XML)
  27. assert.Equal(t, Default("POST", MIMEPOSTForm), Form)
  28. assert.Equal(t, Default("PUT", MIMEPOSTForm), Form)
  29. assert.Equal(t, Default("POST", MIMEMultipartPOSTForm), Form)
  30. assert.Equal(t, Default("PUT", MIMEMultipartPOSTForm), Form)
  31. assert.Equal(t, Default("POST", MIMEPROTOBUF), ProtoBuf)
  32. assert.Equal(t, Default("PUT", MIMEPROTOBUF), ProtoBuf)
  33. }
  34. func TestBindingJSON(t *testing.T) {
  35. testBodyBinding(t,
  36. JSON, "json",
  37. "/", "/",
  38. `{"foo": "bar"}`, `{"bar": "foo"}`)
  39. }
  40. func TestBindingForm(t *testing.T) {
  41. testFormBinding(t, "POST",
  42. "/", "/",
  43. "foo=bar&bar=foo", "bar2=foo")
  44. }
  45. func TestBindingForm2(t *testing.T) {
  46. testFormBinding(t, "GET",
  47. "/?foo=bar&bar=foo", "/?bar2=foo",
  48. "", "")
  49. }
  50. func TestBindingXML(t *testing.T) {
  51. testBodyBinding(t,
  52. XML, "xml",
  53. "/", "/",
  54. "<map><foo>bar</foo></map>", "<map><bar>foo</bar></map>")
  55. }
  56. func TestBindingProtoBuf(t *testing.T) {
  57. test := &example.Test{
  58. Label: proto.String("yes"),
  59. }
  60. data, _ := proto.Marshal(test)
  61. testProtoBodyBinding(t,
  62. ProtoBuf, "protobuf",
  63. "/", "/",
  64. string(data), string(data[1:]))
  65. }
  66. func TestValidationFails(t *testing.T) {
  67. var obj FooStruct
  68. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  69. err := JSON.Bind(req, &obj)
  70. assert.Error(t, err)
  71. }
  72. func TestValidationDisabled(t *testing.T) {
  73. backup := Validator
  74. Validator = nil
  75. defer func() { Validator = backup }()
  76. var obj FooStruct
  77. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  78. err := JSON.Bind(req, &obj)
  79. assert.NoError(t, err)
  80. }
  81. func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) {
  82. b := Form
  83. assert.Equal(t, b.Name(), "form")
  84. obj := FooBarStruct{}
  85. req := requestWithBody(method, path, body)
  86. if method == "POST" {
  87. req.Header.Add("Content-Type", MIMEPOSTForm)
  88. }
  89. err := b.Bind(req, &obj)
  90. assert.NoError(t, err)
  91. assert.Equal(t, obj.Foo, "bar")
  92. assert.Equal(t, obj.Bar, "foo")
  93. obj = FooBarStruct{}
  94. req = requestWithBody(method, badPath, badBody)
  95. err = JSON.Bind(req, &obj)
  96. assert.Error(t, err)
  97. }
  98. func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  99. assert.Equal(t, b.Name(), name)
  100. obj := FooStruct{}
  101. req := requestWithBody("POST", path, body)
  102. err := b.Bind(req, &obj)
  103. assert.NoError(t, err)
  104. assert.Equal(t, obj.Foo, "bar")
  105. obj = FooStruct{}
  106. req = requestWithBody("POST", badPath, badBody)
  107. err = JSON.Bind(req, &obj)
  108. assert.Error(t, err)
  109. }
  110. func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  111. assert.Equal(t, b.Name(), name)
  112. obj := example.Test{}
  113. req := requestWithBody("POST", path, body)
  114. req.Header.Add("Content-Type", MIMEPROTOBUF)
  115. err := b.Bind(req, &obj)
  116. assert.NoError(t, err)
  117. assert.Equal(t, *obj.Label, "yes")
  118. obj = example.Test{}
  119. req = requestWithBody("POST", badPath, badBody)
  120. req.Header.Add("Content-Type", MIMEPROTOBUF)
  121. err = ProtoBuf.Bind(req, &obj)
  122. assert.Error(t, err)
  123. }
  124. func requestWithBody(method, path, body string) (req *http.Request) {
  125. req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
  126. return
  127. }