routes_test.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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 gin
  5. import (
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "net/http/httptest"
  10. "os"
  11. "path"
  12. "testing"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func performRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
  16. req, _ := http.NewRequest(method, path, nil)
  17. w := httptest.NewRecorder()
  18. r.ServeHTTP(w, req)
  19. return w
  20. }
  21. func testRouteOK(method string, t *testing.T) {
  22. // SETUP
  23. passed := false
  24. r := New()
  25. r.Handle(method, "/test", HandlersChain{func(c *Context) {
  26. passed = true
  27. }})
  28. // RUN
  29. w := performRequest(r, method, "/test")
  30. // TEST
  31. assert.True(t, passed)
  32. assert.Equal(t, w.Code, http.StatusOK)
  33. }
  34. // TestSingleRouteOK tests that POST route is correctly invoked.
  35. func testRouteNotOK(method string, t *testing.T) {
  36. // SETUP
  37. passed := false
  38. router := New()
  39. router.Handle(method, "/test_2", HandlersChain{func(c *Context) {
  40. passed = true
  41. }})
  42. // RUN
  43. w := performRequest(router, method, "/test")
  44. // TEST
  45. assert.False(t, passed)
  46. assert.Equal(t, w.Code, http.StatusNotFound)
  47. }
  48. // TestSingleRouteOK tests that POST route is correctly invoked.
  49. func testRouteNotOK2(method string, t *testing.T) {
  50. // SETUP
  51. passed := false
  52. router := New()
  53. var methodRoute string
  54. if method == "POST" {
  55. methodRoute = "GET"
  56. } else {
  57. methodRoute = "POST"
  58. }
  59. router.Handle(methodRoute, "/test", HandlersChain{func(c *Context) {
  60. passed = true
  61. }})
  62. // RUN
  63. w := performRequest(router, method, "/test")
  64. // TEST
  65. assert.False(t, passed)
  66. assert.Equal(t, w.Code, http.StatusMethodNotAllowed)
  67. }
  68. func TestRouterGroupRouteOK(t *testing.T) {
  69. testRouteOK("POST", t)
  70. testRouteOK("DELETE", t)
  71. testRouteOK("PATCH", t)
  72. testRouteOK("PUT", t)
  73. testRouteOK("OPTIONS", t)
  74. testRouteOK("HEAD", t)
  75. }
  76. // TestSingleRouteOK tests that POST route is correctly invoked.
  77. func TestRouteNotOK(t *testing.T) {
  78. testRouteNotOK("POST", t)
  79. testRouteNotOK("DELETE", t)
  80. testRouteNotOK("PATCH", t)
  81. testRouteNotOK("PUT", t)
  82. testRouteNotOK("OPTIONS", t)
  83. testRouteNotOK("HEAD", t)
  84. }
  85. // TestSingleRouteOK tests that POST route is correctly invoked.
  86. func TestRouteNotOK2(t *testing.T) {
  87. testRouteNotOK2("POST", t)
  88. testRouteNotOK2("DELETE", t)
  89. testRouteNotOK2("PATCH", t)
  90. testRouteNotOK2("PUT", t)
  91. testRouteNotOK2("OPTIONS", t)
  92. testRouteNotOK2("HEAD", t)
  93. }
  94. // TestContextParamsGet tests that a parameter can be parsed from the URL.
  95. func TestRouteParamsByName(t *testing.T) {
  96. name := ""
  97. lastName := ""
  98. wild := ""
  99. router := New()
  100. router.GET("/test/:name/:last_name/*wild", func(c *Context) {
  101. name = c.Params.ByName("name")
  102. lastName = c.Params.ByName("last_name")
  103. wild = c.Params.ByName("wild")
  104. assert.Equal(t, name, c.ParamValue("name"))
  105. assert.Equal(t, lastName, c.ParamValue("last_name"))
  106. assert.Equal(t, name, c.DefaultParamValue("name", "nothing"))
  107. assert.Equal(t, lastName, c.DefaultParamValue("last_name", "nothing"))
  108. assert.Equal(t, c.DefaultParamValue("noKey", "default"), "default")
  109. })
  110. // RUN
  111. w := performRequest(router, "GET", "/test/john/smith/is/super/great")
  112. // TEST
  113. assert.Equal(t, w.Code, 200)
  114. assert.Equal(t, name, "john")
  115. assert.Equal(t, lastName, "smith")
  116. assert.Equal(t, wild, "/is/super/great")
  117. }
  118. // TestHandleStaticFile - ensure the static file handles properly
  119. func TestRouteStaticFile(t *testing.T) {
  120. // SETUP file
  121. testRoot, _ := os.Getwd()
  122. f, err := ioutil.TempFile(testRoot, "")
  123. if err != nil {
  124. t.Error(err)
  125. }
  126. defer os.Remove(f.Name())
  127. filePath := path.Join("/", path.Base(f.Name()))
  128. f.WriteString("Gin Web Framework")
  129. f.Close()
  130. // SETUP gin
  131. r := New()
  132. r.Static("./", testRoot)
  133. // RUN
  134. w := performRequest(r, "GET", filePath)
  135. // TEST
  136. assert.Equal(t, w.Code, 200)
  137. assert.Equal(t, w.Body.String(), "Gin Web Framework")
  138. assert.Equal(t, w.HeaderMap.Get("Content-Type"), "text/plain; charset=utf-8")
  139. }
  140. // TestHandleStaticDir - ensure the root/sub dir handles properly
  141. func TestRouteStaticDir(t *testing.T) {
  142. // SETUP
  143. r := New()
  144. r.Static("/", "./")
  145. // RUN
  146. w := performRequest(r, "GET", "/")
  147. // TEST
  148. bodyAsString := w.Body.String()
  149. assert.Equal(t, w.Code, 200)
  150. assert.NotEmpty(t, bodyAsString)
  151. assert.Contains(t, bodyAsString, "gin.go")
  152. assert.Equal(t, w.HeaderMap.Get("Content-Type"), "text/html; charset=utf-8")
  153. }
  154. // TestHandleHeadToDir - ensure the root/sub dir handles properly
  155. func TestRouteHeadToDir(t *testing.T) {
  156. // SETUP
  157. router := New()
  158. router.Static("/", "./")
  159. // RUN
  160. w := performRequest(router, "HEAD", "/")
  161. // TEST
  162. bodyAsString := w.Body.String()
  163. assert.Equal(t, w.Code, 200)
  164. assert.NotEmpty(t, bodyAsString)
  165. assert.Contains(t, bodyAsString, "gin.go")
  166. assert.Equal(t, w.HeaderMap.Get("Content-Type"), "text/html; charset=utf-8")
  167. }
  168. func TestRouteNotAllowed(t *testing.T) {
  169. router := New()
  170. router.POST("/path", func(c *Context) {})
  171. w := performRequest(router, "GET", "/path")
  172. assert.Equal(t, w.Code, http.StatusMethodNotAllowed)
  173. router.NoMethod(func(c *Context) {
  174. c.String(http.StatusTeapot, "responseText")
  175. })
  176. w = performRequest(router, "GET", "/path")
  177. assert.Equal(t, w.Body.String(), "responseText")
  178. assert.Equal(t, w.Code, http.StatusTeapot)
  179. }
  180. func TestRouterNotFound(t *testing.T) {
  181. router := New()
  182. router.GET("/path", func(c *Context) {})
  183. router.GET("/dir/", func(c *Context) {})
  184. router.GET("/", func(c *Context) {})
  185. testRoutes := []struct {
  186. route string
  187. code int
  188. header string
  189. }{
  190. {"/path/", 301, "map[Location:[/path]]"}, // TSR -/
  191. {"/dir", 301, "map[Location:[/dir/]]"}, // TSR +/
  192. {"", 301, "map[Location:[/]]"}, // TSR +/
  193. {"/PATH", 301, "map[Location:[/path]]"}, // Fixed Case
  194. {"/DIR/", 301, "map[Location:[/dir/]]"}, // Fixed Case
  195. {"/PATH/", 301, "map[Location:[/path]]"}, // Fixed Case -/
  196. {"/DIR", 301, "map[Location:[/dir/]]"}, // Fixed Case +/
  197. {"/../path", 301, "map[Location:[/path]]"}, // CleanPath
  198. {"/nope", 404, ""}, // NotFound
  199. }
  200. for _, tr := range testRoutes {
  201. w := performRequest(router, "GET", tr.route)
  202. assert.Equal(t, w.Code, tr.code)
  203. if w.Code != 404 {
  204. assert.Equal(t, fmt.Sprint(w.Header()), tr.header)
  205. }
  206. }
  207. // Test custom not found handler
  208. var notFound bool
  209. router.NoRoute(func(c *Context) {
  210. c.AbortWithStatus(404)
  211. notFound = true
  212. })
  213. w := performRequest(router, "GET", "/nope")
  214. assert.Equal(t, w.Code, 404)
  215. assert.True(t, notFound)
  216. // Test other method than GET (want 307 instead of 301)
  217. router.PATCH("/path", func(c *Context) {})
  218. w = performRequest(router, "PATCH", "/path/")
  219. assert.Equal(t, w.Code, 307)
  220. assert.Equal(t, fmt.Sprint(w.Header()), "map[Location:[/path]]")
  221. // Test special case where no node for the prefix "/" exists
  222. router = New()
  223. router.GET("/a", func(c *Context) {})
  224. w = performRequest(router, "GET", "/")
  225. assert.Equal(t, w.Code, 404)
  226. }