context_test.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package gin
  2. import (
  3. "errors"
  4. "html/template"
  5. "net/http"
  6. "net/http/httptest"
  7. "testing"
  8. )
  9. // TestContextParamsGet tests that a parameter can be parsed from the URL.
  10. func TestContextParamsByName(t *testing.T) {
  11. req, _ := http.NewRequest("GET", "/test/alexandernyquist", nil)
  12. w := httptest.NewRecorder()
  13. name := ""
  14. r := Default()
  15. r.GET("/test/:name", func(c *Context) {
  16. name = c.Params.ByName("name")
  17. })
  18. r.ServeHTTP(w, req)
  19. if name != "alexandernyquist" {
  20. t.Errorf("Url parameter was not correctly parsed. Should be alexandernyquist, was %s.", name)
  21. }
  22. }
  23. // TestContextSetGet tests that a parameter is set correctly on the
  24. // current context and can be retrieved using Get.
  25. func TestContextSetGet(t *testing.T) {
  26. req, _ := http.NewRequest("GET", "/test", nil)
  27. w := httptest.NewRecorder()
  28. r := Default()
  29. r.GET("/test", func(c *Context) {
  30. // Key should be lazily created
  31. if c.Keys != nil {
  32. t.Error("Keys should be nil")
  33. }
  34. // Set
  35. c.Set("foo", "bar")
  36. v, err := c.Get("foo")
  37. if err != nil {
  38. t.Errorf("Error on exist key")
  39. }
  40. if v != "bar" {
  41. t.Errorf("Value should be bar, was %s", v)
  42. }
  43. })
  44. r.ServeHTTP(w, req)
  45. }
  46. // TestContextJSON tests that the response is serialized as JSON
  47. // and Content-Type is set to application/json
  48. func TestContextJSON(t *testing.T) {
  49. req, _ := http.NewRequest("GET", "/test", nil)
  50. w := httptest.NewRecorder()
  51. r := Default()
  52. r.GET("/test", func(c *Context) {
  53. c.JSON(200, H{"foo": "bar"})
  54. })
  55. r.ServeHTTP(w, req)
  56. if w.Body.String() != "{\"foo\":\"bar\"}\n" {
  57. t.Errorf("Response should be {\"foo\":\"bar\"}, was: %s", w.Body.String())
  58. }
  59. if w.HeaderMap.Get("Content-Type") != "application/json" {
  60. t.Errorf("Content-Type should be application/json, was %s", w.HeaderMap.Get("Content-Type"))
  61. }
  62. }
  63. // TestContextHTML tests that the response executes the templates
  64. // and responds with Content-Type set to text/html
  65. func TestContextHTML(t *testing.T) {
  66. req, _ := http.NewRequest("GET", "/test", nil)
  67. w := httptest.NewRecorder()
  68. r := Default()
  69. templ, _ := template.New("t").Parse(`Hello {{.Name}}`)
  70. r.SetHTMLTemplate(templ)
  71. type TestData struct{ Name string }
  72. r.GET("/test", func(c *Context) {
  73. c.HTML(200, "t", TestData{"alexandernyquist"})
  74. })
  75. r.ServeHTTP(w, req)
  76. if w.Body.String() != "Hello alexandernyquist" {
  77. t.Errorf("Response should be Hello alexandernyquist, was: %s", w.Body.String())
  78. }
  79. if w.HeaderMap.Get("Content-Type") != "text/html" {
  80. t.Errorf("Content-Type should be text/html, was %s", w.HeaderMap.Get("Content-Type"))
  81. }
  82. }
  83. // TestContextString tests that the response is returned
  84. // with Content-Type set to text/plain
  85. func TestContextString(t *testing.T) {
  86. req, _ := http.NewRequest("GET", "/test", nil)
  87. w := httptest.NewRecorder()
  88. r := Default()
  89. r.GET("/test", func(c *Context) {
  90. c.String(200, "test")
  91. })
  92. r.ServeHTTP(w, req)
  93. if w.Body.String() != "test" {
  94. t.Errorf("Response should be test, was: %s", w.Body.String())
  95. }
  96. if w.HeaderMap.Get("Content-Type") != "text/plain" {
  97. t.Errorf("Content-Type should be text/plain, was %s", w.HeaderMap.Get("Content-Type"))
  98. }
  99. }
  100. // TestContextXML tests that the response is serialized as XML
  101. // and Content-Type is set to application/xml
  102. func TestContextXML(t *testing.T) {
  103. req, _ := http.NewRequest("GET", "/test", nil)
  104. w := httptest.NewRecorder()
  105. r := Default()
  106. r.GET("/test", func(c *Context) {
  107. c.XML(200, H{"foo": "bar"})
  108. })
  109. r.ServeHTTP(w, req)
  110. if w.Body.String() != "<map><foo>bar</foo></map>" {
  111. t.Errorf("Response should be <map><foo>bar</foo></map>, was: %s", w.Body.String())
  112. }
  113. if w.HeaderMap.Get("Content-Type") != "application/xml" {
  114. t.Errorf("Content-Type should be application/xml, was %s", w.HeaderMap.Get("Content-Type"))
  115. }
  116. }
  117. // TestContextData tests that the response can be written from `bytesting`
  118. // with specified MIME type
  119. func TestContextData(t *testing.T) {
  120. req, _ := http.NewRequest("GET", "/test/csv", nil)
  121. w := httptest.NewRecorder()
  122. r := Default()
  123. r.GET("/test/csv", func(c *Context) {
  124. c.Data(200, "text/csv", []byte(`foo,bar`))
  125. })
  126. r.ServeHTTP(w, req)
  127. if w.Body.String() != "foo,bar" {
  128. t.Errorf("Response should be foo&bar, was: %s", w.Body.String())
  129. }
  130. if w.HeaderMap.Get("Content-Type") != "text/csv" {
  131. t.Errorf("Content-Type should be text/csv, was %s", w.HeaderMap.Get("Content-Type"))
  132. }
  133. }
  134. func TestContextFile(t *testing.T) {
  135. req, _ := http.NewRequest("GET", "/test/file", nil)
  136. w := httptest.NewRecorder()
  137. r := Default()
  138. r.GET("/test/file", func(c *Context) {
  139. c.File("./gin.go")
  140. })
  141. r.ServeHTTP(w, req)
  142. bodyAsString := w.Body.String()
  143. if len(bodyAsString) == 0 {
  144. t.Errorf("Got empty body instead of file data")
  145. }
  146. if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
  147. t.Errorf("Content-Type should be text/plain; charset=utf-8, was %s", w.HeaderMap.Get("Content-Type"))
  148. }
  149. }
  150. // TestHandlerFunc - ensure that custom middleware works properly
  151. func TestHandlerFunc(t *testing.T) {
  152. req, _ := http.NewRequest("GET", "/", nil)
  153. w := httptest.NewRecorder()
  154. r := Default()
  155. var stepsPassed int = 0
  156. r.Use(func(context *Context) {
  157. stepsPassed += 1
  158. context.Next()
  159. stepsPassed += 1
  160. })
  161. r.ServeHTTP(w, req)
  162. if w.Code != 404 {
  163. t.Errorf("Response code should be Not found, was: %s", w.Code)
  164. }
  165. if stepsPassed != 2 {
  166. t.Errorf("Falied to switch context in handler function: %s", stepsPassed)
  167. }
  168. }
  169. // TestBadAbortHandlersChain - ensure that Abort after switch context will not interrupt pending handlers
  170. func TestBadAbortHandlersChain(t *testing.T) {
  171. req, _ := http.NewRequest("GET", "/", nil)
  172. w := httptest.NewRecorder()
  173. r := Default()
  174. var stepsPassed int = 0
  175. r.Use(func(context *Context) {
  176. stepsPassed += 1
  177. context.Next()
  178. stepsPassed += 1
  179. // after check and abort
  180. context.Abort(409)
  181. },
  182. func(context *Context) {
  183. stepsPassed += 1
  184. context.Next()
  185. stepsPassed += 1
  186. context.Abort(403)
  187. },
  188. )
  189. r.ServeHTTP(w, req)
  190. if w.Code != 403 {
  191. t.Errorf("Response code should be Forbiden, was: %s", w.Code)
  192. }
  193. if stepsPassed != 4 {
  194. t.Errorf("Falied to switch context in handler function: %s", stepsPassed)
  195. }
  196. }
  197. // TestAbortHandlersChain - ensure that Abort interrupt used middlewares in fifo order
  198. func TestAbortHandlersChain(t *testing.T) {
  199. req, _ := http.NewRequest("GET", "/", nil)
  200. w := httptest.NewRecorder()
  201. r := Default()
  202. var stepsPassed int = 0
  203. r.Use(func(context *Context) {
  204. stepsPassed += 1
  205. context.Abort(409)
  206. },
  207. func(context *Context) {
  208. stepsPassed += 1
  209. context.Next()
  210. stepsPassed += 1
  211. },
  212. )
  213. r.ServeHTTP(w, req)
  214. if w.Code != 409 {
  215. t.Errorf("Response code should be Conflict, was: %s", w.Code)
  216. }
  217. if stepsPassed != 1 {
  218. t.Errorf("Falied to switch context in handler function: %s", stepsPassed)
  219. }
  220. }
  221. // TestFailHandlersChain - ensure that Fail interrupt used middlewares in fifo order as
  222. // as well as Abort
  223. func TestFailHandlersChain(t *testing.T) {
  224. req, _ := http.NewRequest("GET", "/", nil)
  225. w := httptest.NewRecorder()
  226. r := Default()
  227. var stepsPassed int = 0
  228. r.Use(func(context *Context) {
  229. stepsPassed += 1
  230. context.Fail(500, errors.New("foo"))
  231. },
  232. func(context *Context) {
  233. stepsPassed += 1
  234. context.Next()
  235. stepsPassed += 1
  236. },
  237. )
  238. r.ServeHTTP(w, req)
  239. if w.Code != 500 {
  240. t.Errorf("Response code should be Server error, was: %s", w.Code)
  241. }
  242. if stepsPassed != 1 {
  243. t.Errorf("Falied to switch context in handler function: %s", stepsPassed)
  244. }
  245. }