github.com/mayra-cabrera/buffalo@v0.9.4-0.20170814145312-66d2e7772f11/router_test.go (about) 1 package buffalo 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "net/http/httptest" 8 "path/filepath" 9 "testing" 10 11 "github.com/gobuffalo/buffalo/render" 12 "github.com/gobuffalo/packr" 13 "github.com/gobuffalo/plush" 14 "github.com/markbates/willie" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func testApp() *App { 19 a := New(Options{}) 20 a.Redirect(301, "/foo", "/bar") 21 a.GET("/bar", func(c Context) error { 22 return c.Render(200, render.String("bar")) 23 }) 24 25 rt := a.Group("/router/tests") 26 27 h := func(c Context) error { 28 return c.Render(200, render.String(c.Request().Method+"|"+c.Value("current_path").(string))) 29 } 30 31 rt.GET("/", h) 32 rt.POST("/", h) 33 rt.PUT("/", h) 34 rt.DELETE("/", h) 35 rt.OPTIONS("/", h) 36 rt.PATCH("/", h) 37 return a 38 } 39 40 func Test_Router(t *testing.T) { 41 r := require.New(t) 42 43 table := []string{ 44 "GET", 45 "POST", 46 "PUT", 47 "DELETE", 48 "OPTIONS", 49 "PATCH", 50 } 51 52 ts := httptest.NewServer(testApp()) 53 defer ts.Close() 54 55 for _, v := range table { 56 req, err := http.NewRequest(v, fmt.Sprintf("%s/router/tests", ts.URL), nil) 57 r.NoError(err) 58 res, err := http.DefaultClient.Do(req) 59 r.NoError(err) 60 b, _ := ioutil.ReadAll(res.Body) 61 r.Equal(fmt.Sprintf("%s|/router/tests", v), string(b)) 62 } 63 } 64 65 func Test_Router_Group(t *testing.T) { 66 r := require.New(t) 67 68 a := testApp() 69 g := a.Group("/api/v1") 70 g.GET("/users", func(c Context) error { 71 return c.Render(201, nil) 72 }) 73 74 w := willie.New(a) 75 res := w.Request("/api/v1/users").Get() 76 r.Equal(201, res.Code) 77 } 78 79 func Test_Router_Group_on_Group(t *testing.T) { 80 r := require.New(t) 81 82 a := testApp() 83 g := a.Group("/api/v1") 84 g.GET("/users", func(c Context) error { 85 return c.Render(201, nil) 86 }) 87 f := g.Group("/foo") 88 f.GET("/bar", func(c Context) error { 89 return c.Render(420, nil) 90 }) 91 92 w := willie.New(a) 93 res := w.Request("/api/v1/foo/bar").Get() 94 r.Equal(420, res.Code) 95 } 96 97 func Test_Router_Group_Middleware(t *testing.T) { 98 r := require.New(t) 99 100 a := testApp() 101 a.Use(func(h Handler) Handler { return h }) 102 r.Len(a.Middleware.stack, 1) 103 104 g := a.Group("/api/v1") 105 r.Len(a.Middleware.stack, 1) 106 r.Len(g.Middleware.stack, 1) 107 108 g.Use(func(h Handler) Handler { return h }) 109 r.Len(a.Middleware.stack, 1) 110 r.Len(g.Middleware.stack, 2) 111 } 112 113 func Test_Router_Redirect(t *testing.T) { 114 r := require.New(t) 115 w := willie.New(testApp()) 116 res := w.Request("/foo").Get() 117 r.Equal(301, res.Code) 118 r.Equal("/bar", res.Location()) 119 } 120 121 func Test_Router_ServeFiles(t *testing.T) { 122 r := require.New(t) 123 124 tmpFile, err := ioutil.TempFile("", "assets") 125 r.NoError(err) 126 127 af := []byte("hi") 128 _, err = tmpFile.Write(af) 129 r.NoError(err) 130 131 a := New(Options{}) 132 a.ServeFiles("/assets", http.Dir(filepath.Dir(tmpFile.Name()))) 133 134 w := willie.New(a) 135 res := w.Request("/assets/%s", filepath.Base(tmpFile.Name())).Get() 136 137 r.Equal(200, res.Code) 138 r.Equal(af, res.Body.Bytes()) 139 } 140 141 func Test_App_NamedRoutes(t *testing.T) { 142 143 type CarsResource struct { 144 *BaseResource 145 } 146 147 r := require.New(t) 148 a := Automatic(Options{}) 149 150 var carsResource Resource 151 carsResource = CarsResource{&BaseResource{}} 152 153 rr := render.New(render.Options{ 154 HTMLLayout: "application.html", 155 TemplateEngine: plush.BuffaloRenderer, 156 TemplatesBox: packr.NewBox("../templates"), 157 Helpers: map[string]interface{}{}, 158 }) 159 160 sampleHandler := func(c Context) error { 161 c.Set("opts", map[string]interface{}{}) 162 return c.Render(200, rr.String(` 163 1. <%= rootPath() %> 164 2. <%= usersPath() %> 165 3. <%= userPath({user_id: 1}) %> 166 4. <%= myPeepsPath() %> 167 5. <%= userPath(opts) %> 168 6. <%= carPath({car_id: 1}) %> 169 7. <%= newCarPath() %> 170 8. <%= editCarPath({car_id: 1}) %> 171 9. <%= editCarPath({car_id: 1, other: 12}) %> 172 10. <%= rootPath({"some":"variable","other": 12}) %> 173 11. <%= rootPath() %> 174 12. <%= rootPath({"special/":"12=ss"}) %> 175 `)) 176 } 177 178 a.GET("/", sampleHandler) 179 a.GET("/users", sampleHandler) 180 a.GET("/users/{user_id}", sampleHandler) 181 a.GET("/peeps", sampleHandler).Name("myPeeps") 182 a.Resource("/car", carsResource) 183 184 w := willie.New(a) 185 res := w.Request("/").Get() 186 187 r.Equal(200, res.Code) 188 r.Contains(res.Body.String(), "1. /") 189 r.Contains(res.Body.String(), "2. /users") 190 r.Contains(res.Body.String(), "3. /users/1") 191 r.Contains(res.Body.String(), "4. /peeps") 192 r.Contains(res.Body.String(), "5. /users/{user_id}") 193 r.Contains(res.Body.String(), "6. /car/1") 194 r.Contains(res.Body.String(), "7. /car/new") 195 r.Contains(res.Body.String(), "8. /car/1/edit") 196 r.Contains(res.Body.String(), "9. /car/1/edit?other=12") 197 r.Contains(res.Body.String(), "10. /?other=12&some=variable") 198 r.Contains(res.Body.String(), "11. /") 199 r.Contains(res.Body.String(), "12. /?special%2F=12%3Dss") 200 } 201 202 func Test_Resource(t *testing.T) { 203 r := require.New(t) 204 205 type trs struct { 206 Method string 207 Path string 208 Result string 209 } 210 211 tests := []trs{ 212 { 213 Method: "GET", 214 Path: "", 215 Result: "list", 216 }, 217 { 218 Method: "GET", 219 Path: "/new", 220 Result: "new", 221 }, 222 { 223 Method: "GET", 224 Path: "/1", 225 Result: "show 1", 226 }, 227 { 228 Method: "GET", 229 Path: "/1/edit", 230 Result: "edit 1", 231 }, 232 { 233 Method: "POST", 234 Path: "", 235 Result: "create", 236 }, 237 { 238 Method: "PUT", 239 Path: "/1", 240 Result: "update 1", 241 }, 242 { 243 Method: "DELETE", 244 Path: "/1", 245 Result: "destroy 1", 246 }, 247 } 248 249 a := Automatic(Options{}) 250 a.Resource("/users", &userResource{}) 251 a.Resource("/api/v1/users", &userResource{}) 252 253 ts := httptest.NewServer(a) 254 defer ts.Close() 255 256 c := http.Client{} 257 for _, path := range []string{"/users", "/api/v1/users"} { 258 for _, test := range tests { 259 u := ts.URL + path + test.Path 260 req, err := http.NewRequest(test.Method, u, nil) 261 r.NoError(err) 262 res, err := c.Do(req) 263 r.NoError(err) 264 b, err := ioutil.ReadAll(res.Body) 265 r.NoError(err) 266 r.Equal(test.Result, string(b)) 267 } 268 } 269 270 } 271 272 type userResource struct{} 273 274 func (u *userResource) List(c Context) error { 275 return c.Render(200, render.String("list")) 276 } 277 278 func (u *userResource) Show(c Context) error { 279 return c.Render(200, render.String(`show <%=params["user_id"] %>`)) 280 } 281 282 func (u *userResource) New(c Context) error { 283 return c.Render(200, render.String("new")) 284 } 285 286 func (u *userResource) Create(c Context) error { 287 return c.Render(200, render.String("create")) 288 } 289 290 func (u *userResource) Edit(c Context) error { 291 return c.Render(200, render.String(`edit <%=params["user_id"] %>`)) 292 } 293 294 func (u *userResource) Update(c Context) error { 295 return c.Render(200, render.String(`update <%=params["user_id"] %>`)) 296 } 297 298 func (u *userResource) Destroy(c Context) error { 299 return c.Render(200, render.String(`destroy <%=params["user_id"] %>`)) 300 } 301 302 func Test_buildRouteName(t *testing.T) { 303 r := require.New(t) 304 cases := map[string]string{ 305 "/": "root", 306 "/users": "users", 307 "/users/new": "newUsers", 308 "/users/{user_id}": "user", 309 "/users/{user_id}/children": "userChildren", 310 "/users/{user_id}/children/{child_id}": "userChild", 311 "/users/{user_id}/children/new": "newUserChildren", 312 "/users/{user_id}/children/{child_id}/build": "userChildBuild", 313 "/admin/planes": "adminPlanes", 314 "/admin/planes/{plane_id}": "adminPlane", 315 "/admin/planes/{plane_id}/edit": "editAdminPlane", 316 } 317 318 a := Automatic(Options{}) 319 320 for input, result := range cases { 321 fResult := a.buildRouteName(input) 322 r.Equal(result, fResult, input) 323 } 324 325 a = Automatic(Options{Prefix: "/test"}) 326 cases = map[string]string{ 327 "/test": "test", 328 "/test/users": "testUsers", 329 } 330 331 for input, result := range cases { 332 fResult := a.buildRouteName(input) 333 r.Equal(result, fResult, input) 334 } 335 } 336 337 func Test_CatchAll_Route(t *testing.T) { 338 r := require.New(t) 339 rr := render.New(render.Options{}) 340 341 a := Automatic(Options{}) 342 a.GET("/{name:.+}", func(c Context) error { 343 name := c.Param("name") 344 return c.Render(200, rr.String(name)) 345 }) 346 347 w := willie.New(a) 348 res := w.Request("/john").Get() 349 350 r.Contains(res.Body.String(), "john") 351 }