github.com/naoina/kocha@v0.7.1-0.20171129072645-78c7a531f799/controller_test.go (about) 1 package kocha_test 2 3 import ( 4 "bytes" 5 "encoding/xml" 6 "fmt" 7 "io/ioutil" 8 "mime" 9 "net/http" 10 "net/http/httptest" 11 "os" 12 "path/filepath" 13 "reflect" 14 "strings" 15 "testing" 16 17 "github.com/naoina/kocha" 18 "github.com/naoina/kocha/log" 19 ) 20 21 func TestMimeTypeFormats(t *testing.T) { 22 var actual interface{} = len(kocha.MimeTypeFormats) 23 var expected interface{} = 4 24 if !reflect.DeepEqual(actual, expected) { 25 t.Errorf(`len(TestMimeTypeFormats) => %#v; want %#v`, actual, expected) 26 } 27 for k, v := range map[string]string{ 28 29 "application/json": "json", 30 "application/xml": "xml", 31 "text/html": "html", 32 "text/plain": "txt", 33 } { 34 if _, found := kocha.MimeTypeFormats[k]; !found { 35 t.Errorf(`MimeTypeFormats["%#v"] => notfound; want %v`, k, v) 36 } 37 } 38 } 39 40 func TestMimeTypeFormats_Get(t *testing.T) { 41 actual := kocha.MimeTypeFormats.Get("application/json") 42 expected := "json" 43 if !reflect.DeepEqual(actual, expected) { 44 t.Errorf("Expect %v, but %v", expected, actual) 45 } 46 47 actual = kocha.MimeTypeFormats.Get("text/plain") 48 expected = "txt" 49 if !reflect.DeepEqual(actual, expected) { 50 t.Errorf("Expect %v, but %v", expected, actual) 51 } 52 } 53 54 func TestMimeTypeFormats_Set(t *testing.T) { 55 mimeType := "test/mime" 56 if kocha.MimeTypeFormats[mimeType] != "" { 57 t.Fatalf("Expect none, but %v", kocha.MimeTypeFormats[mimeType]) 58 } 59 expected := "testmimetype" 60 kocha.MimeTypeFormats.Set(mimeType, expected) 61 defer delete(kocha.MimeTypeFormats, mimeType) 62 actual := kocha.MimeTypeFormats[mimeType] 63 if !reflect.DeepEqual(actual, expected) { 64 t.Errorf("Expect %v, but %v", expected, actual) 65 } 66 } 67 68 func TestMimeTypeFormats_Del(t *testing.T) { 69 if kocha.MimeTypeFormats["text/html"] == "" { 70 t.Fatal("Expect exists, but not exists") 71 } 72 kocha.MimeTypeFormats.Del("text/html") 73 defer func() { 74 kocha.MimeTypeFormats["text/html"] = "html" 75 }() 76 actual := kocha.MimeTypeFormats["text/html"] 77 expected := "" 78 if !reflect.DeepEqual(actual, expected) { 79 t.Errorf("Expect %v, but %v", expected, actual) 80 } 81 } 82 83 func newTestContext(name, layout string) *kocha.Context { 84 app, err := kocha.New(&kocha.Config{ 85 AppPath: "testdata", 86 AppName: "appname", 87 DefaultLayout: "", 88 Template: &kocha.Template{ 89 PathInfo: kocha.TemplatePathInfo{ 90 Name: "appname", 91 Paths: []string{ 92 filepath.Join("testdata", "app", "view"), 93 }, 94 }, 95 }, 96 RouteTable: []*kocha.Route{ 97 { 98 Name: name, 99 Path: "/", 100 Controller: &kocha.FixtureRootTestCtrl{}, 101 }, 102 }, 103 Logger: &kocha.LoggerConfig{ 104 Writer: ioutil.Discard, 105 }, 106 }) 107 if err != nil { 108 panic(err) 109 } 110 req, err := http.NewRequest("GET", "/", nil) 111 if err != nil { 112 panic(err) 113 } 114 return &kocha.Context{ 115 Name: name, 116 Layout: layout, 117 Request: &kocha.Request{Request: req}, 118 Response: &kocha.Response{ResponseWriter: httptest.NewRecorder()}, 119 Params: &kocha.Params{}, 120 App: app, 121 } 122 } 123 124 func TestContext_Render(t *testing.T) { 125 func() { 126 c := newTestContext("testctrlr_ctx", "") 127 data := kocha.OrderedOutputMap{ 128 "c1": "v1", 129 "c2": "v2", 130 } 131 w := httptest.NewRecorder() 132 c.Response = &kocha.Response{ResponseWriter: w} 133 if err := c.Render(data); err != nil { 134 t.Fatal(err) 135 } 136 buf, err := ioutil.ReadAll(w.Body) 137 if err != nil { 138 t.Fatal(err) 139 } 140 actual := string(buf) 141 expect1 := "tmpl_ctx: map[c1:v1 c2:v2]\n" 142 expect2 := "tmpl_ctx: map[c2:v2 c1:v1]\n" 143 if !reflect.DeepEqual(actual, expect1) && !reflect.DeepEqual(actual, expect2) { 144 t.Errorf(`c.Render(%#v) => %#v; want %#v or %#v`, data, actual, expect1, expect2) 145 } 146 if !reflect.DeepEqual(c.Response.ContentType, "text/html") { 147 t.Errorf("Expect %v, but %v", "text/html", c.Response.ContentType) 148 } 149 }() 150 151 func() { 152 c := newTestContext("testctrlr_ctx", "") 153 c.Data = kocha.OrderedOutputMap{ 154 "c3": "v3", 155 "c4": "v4", 156 } 157 w := httptest.NewRecorder() 158 c.Response = &kocha.Response{ResponseWriter: w} 159 if err := c.Render(nil); err != nil { 160 t.Fatal(err) 161 } 162 buf, err := ioutil.ReadAll(w.Body) 163 if err != nil { 164 t.Fatal(err) 165 } 166 actual := string(buf) 167 expected := fmt.Sprintf("tmpl_ctx: %v\n", c.Data) 168 if !reflect.DeepEqual(actual, expected) { 169 t.Errorf("Expect %q, but %q", expected, actual) 170 } 171 }() 172 173 func() { 174 c := newTestContext("testctrlr_ctx", "") 175 c.Data = kocha.OrderedOutputMap{ 176 "c5": "v5", 177 "c6": "v6", 178 } 179 ctx := kocha.OrderedOutputMap{ 180 "c6": "test", 181 "c7": "v7", 182 } 183 w := httptest.NewRecorder() 184 c.Response = &kocha.Response{ResponseWriter: w} 185 if err := c.Render(ctx); err != nil { 186 t.Fatal(err) 187 } 188 buf, err := ioutil.ReadAll(w.Body) 189 if err != nil { 190 t.Fatal(err) 191 } 192 actual := string(buf) 193 expected := fmt.Sprintf("tmpl_ctx: %v\n", kocha.OrderedOutputMap{ 194 "c5": "v5", 195 "c6": "test", 196 "c7": "v7", 197 }) 198 if !reflect.DeepEqual(actual, expected) { 199 t.Errorf("Expect %q, but %q", expected, actual) 200 } 201 }() 202 203 func() { 204 c := newTestContext("testctrlr_ctx", "") 205 ctx := "test_ctx" 206 w := httptest.NewRecorder() 207 c.Response = &kocha.Response{ResponseWriter: w} 208 if err := c.Render(ctx); err != nil { 209 t.Fatal(err) 210 } 211 buf, err := ioutil.ReadAll(w.Body) 212 if err != nil { 213 t.Fatal(err) 214 } 215 actual := string(buf) 216 expected := "tmpl_ctx: test_ctx\n" 217 if !reflect.DeepEqual(actual, expected) { 218 t.Errorf("Expect %q, but %q", expected, actual) 219 } 220 }() 221 222 func() { 223 c := newTestContext("testctrlr_ctx", "") 224 c.Data = map[interface{}]interface{}{"c1": "v1"} 225 ctx := "test_ctx_override" 226 w := httptest.NewRecorder() 227 c.Response = &kocha.Response{ResponseWriter: w} 228 if err := c.Render(ctx); err != nil { 229 t.Fatal(err) 230 } 231 buf, err := ioutil.ReadAll(w.Body) 232 if err != nil { 233 t.Fatal(err) 234 } 235 actual := string(buf) 236 expected := "tmpl_ctx: test_ctx_override\n" 237 if !reflect.DeepEqual(actual, expected) { 238 t.Errorf("Expect %q, but %q", expected, actual) 239 } 240 }() 241 242 func() { 243 c := newTestContext("testctrlr_ctx", "") 244 c.Data = map[interface{}]interface{}{"c1": "v1"} 245 if err := c.Render(nil); err != nil { 246 t.Fatal(err) 247 } 248 actual := c.Data 249 expected := map[interface{}]interface{}{ 250 "c1": "v1", 251 } 252 if !reflect.DeepEqual(actual, expected) { 253 t.Errorf("Context.Data => %#v, want %#v", actual, expected) 254 } 255 }() 256 257 func() { 258 c := newTestContext("testctrlr_ctx", "") 259 ctx := map[interface{}]interface{}{"c1": "v1"} 260 if err := c.Render(ctx); err != nil { 261 t.Fatal(err) 262 } 263 actual := c.Data 264 expected := map[interface{}]interface{}{ 265 "c1": "v1", 266 } 267 if !reflect.DeepEqual(actual, expected) { 268 t.Errorf("Context.Data => %#v, want %#v", actual, expected) 269 } 270 }() 271 } 272 273 func TestContext_Render_withDifferentKeyType(t *testing.T) { 274 for _, v := range []struct { 275 data interface{} 276 ctx interface{} 277 expect error 278 }{ 279 {map[interface{}]interface{}{"c1": "v1"}, map[string]interface{}{"c2": "v2"}, nil}, 280 {map[string]interface{}{"c1": "v1"}, map[interface{}]interface{}{"c2": "v2"}, fmt.Errorf("kocha: context: key of type interface {} is not assignable to type string")}, 281 {map[int]interface{}{1: "v1"}, map[string]interface{}{"2": "v2"}, fmt.Errorf("kocha: context: key of type string is not assignable to type int")}, 282 {map[string]string{"c1": "v1"}, map[string]interface{}{"c2": "v2"}, fmt.Errorf("kocha: context: value of type interface {} is not assignable to type string")}, 283 {map[string]int{"c1": 1}, map[string]string{"c2": "v2"}, fmt.Errorf("kocha: context: value of type string is not assignable to type int")}, 284 {map[string]string{"c1": "v1"}, map[string][]byte{"c2": []byte("v2")}, nil}, 285 {map[string]interface{}{"c1": "v1"}, map[string]int{"c2": 2}, nil}, 286 } { 287 c := newTestContext("testctrlr_ctx", "") 288 c.Data = v.data 289 ctx := v.ctx 290 actual := fmt.Sprint(c.Render(ctx)) 291 expect := fmt.Sprint(v.expect) 292 if !reflect.DeepEqual(actual, expect) { 293 t.Errorf(`c.Render(%#v) => %+v; want %+v`, ctx, actual, expect) 294 } 295 } 296 } 297 298 func TestContext_Render_withContentType(t *testing.T) { 299 c := newTestContext("testctrlr", "") 300 w := httptest.NewRecorder() 301 c.Response.ResponseWriter = w 302 c.Response.ContentType = "application/json" 303 if err := c.Render(nil); err != nil { 304 t.Fatal(err) 305 } 306 buf, err := ioutil.ReadAll(w.Body) 307 if err != nil { 308 t.Fatal(err) 309 } 310 actual := string(buf) 311 expected := `{"tmpl2":"content"}` + "\n" 312 if !reflect.DeepEqual(actual, expected) { 313 t.Errorf("Expect %q, but %q", expected, actual) 314 } 315 } 316 317 func TestContext_Render_withMissingTemplateInAppName(t *testing.T) { 318 c := newTestContext("testctrlr", "") 319 c.App.Config.AppName = "unknownAppName" 320 actual := fmt.Sprint(c.Render(nil)) 321 expect := "kocha: template not found: unknownAppName:testctrlr.html" 322 if !reflect.DeepEqual(actual, expect) { 323 t.Errorf(`kocha.Render(%#v, %#v) => %+v; want %+v`, c, nil, actual, expect) 324 } 325 } 326 327 func TestContext_Render_withMissingTemplate(t *testing.T) { 328 c := newTestContext("testctrlr", "") 329 c.Name = "unknownctrlr" 330 actual := fmt.Sprint(c.Render(nil)) 331 expect := "kocha: template not found: appname:unknownctrlr.html" 332 if !reflect.DeepEqual(actual, expect) { 333 t.Errorf(`kocha.Render(%#v, %#v) => %#v; want %#v`, c, nil, actual, expect) 334 } 335 } 336 337 func TestContext_Render_withAnotherLayout(t *testing.T) { 338 c := newTestContext("testctrlr", "another_layout") 339 w := httptest.NewRecorder() 340 c.Response = &kocha.Response{ResponseWriter: w} 341 if err := c.Render(nil); err != nil { 342 t.Fatal(err) 343 } 344 buf, err := ioutil.ReadAll(w.Body) 345 if err != nil { 346 t.Fatal(err) 347 } 348 actual := string(buf) 349 expected := "Another layout\n" 350 if !reflect.DeepEqual(actual, expected) { 351 t.Errorf("Expect %q, but %q", expected, actual) 352 } 353 } 354 355 func TestContext_RenderJSON(t *testing.T) { 356 c := newTestContext("testctrlr", "") 357 w := httptest.NewRecorder() 358 c.Response = &kocha.Response{ResponseWriter: w} 359 if err := c.RenderJSON(struct{ A, B string }{"hoge", "foo"}); err != nil { 360 t.Fatal(err) 361 } 362 buf, err := ioutil.ReadAll(w.Body) 363 if err != nil { 364 t.Fatal(err) 365 } 366 actual := string(buf) 367 expected := `{"A":"hoge","B":"foo"}` 368 if !reflect.DeepEqual(actual, expected) { 369 t.Errorf("Expect %v, but %v", expected, actual) 370 } 371 if !reflect.DeepEqual(c.Response.ContentType, "application/json") { 372 t.Errorf("Expect %v, but %v", "application/json", c.Response.ContentType) 373 } 374 } 375 376 func TestContext_RenderXML(t *testing.T) { 377 c := newTestContext("testctrlr", "") 378 ctx := struct { 379 XMLName xml.Name `xml:"user"` 380 A string `xml:"id"` 381 B string `xml:"name"` 382 }{A: "hoge", B: "foo"} 383 w := httptest.NewRecorder() 384 c.Response = &kocha.Response{ResponseWriter: w} 385 if err := c.RenderXML(ctx); err != nil { 386 t.Fatal(err) 387 } 388 buf, err := ioutil.ReadAll(w.Body) 389 if err != nil { 390 t.Fatal(err) 391 } 392 actual := string(buf) 393 expected := "<user><id>hoge</id><name>foo</name></user>" 394 if !reflect.DeepEqual(actual, expected) { 395 t.Errorf("Expect %v, but %v", expected, actual) 396 } 397 if !reflect.DeepEqual(c.Response.ContentType, "application/xml") { 398 t.Errorf("Expect %v, but %v", "application/xml", c.Response.ContentType) 399 } 400 } 401 402 func TestContext_RenderText(t *testing.T) { 403 c := newTestContext("testctrlr", "") 404 w := httptest.NewRecorder() 405 c.Response = &kocha.Response{ResponseWriter: w} 406 if err := c.RenderText("test_content_data"); err != nil { 407 t.Fatal(err) 408 } 409 buf, err := ioutil.ReadAll(w.Body) 410 if err != nil { 411 t.Fatal(err) 412 } 413 actual := string(buf) 414 expected := "test_content_data" 415 if !reflect.DeepEqual(actual, expected) { 416 t.Errorf("Expect %v, but %v", expected, actual) 417 } 418 if !reflect.DeepEqual(c.Response.ContentType, "text/plain") { 419 t.Errorf("Expect %v, but %v", "text/plain", c.Response.ContentType) 420 } 421 } 422 423 func TestContext_RenderError(t *testing.T) { 424 for _, v := range []struct { 425 status int 426 contentType string 427 expect string 428 }{ 429 {http.StatusInternalServerError, "text/html", "500 error\n"}, 430 {http.StatusBadRequest, "text/html", "400 error\n"}, 431 {http.StatusInternalServerError, "application/json", "{\"error\":500}\n"}, 432 {http.StatusTeapot, "text/html", http.StatusText(http.StatusTeapot)}, 433 } { 434 c := newTestContext("testctrlr", "") 435 w := httptest.NewRecorder() 436 c.Response = &kocha.Response{ResponseWriter: w} 437 c.Response.ContentType = v.contentType 438 if err := c.RenderError(v.status, nil, nil); err != nil { 439 t.Fatal(err) 440 } 441 buf, err := ioutil.ReadAll(w.Body) 442 if err != nil { 443 t.Fatal(err) 444 } 445 var actual interface{} = string(buf) 446 var expect interface{} = v.expect 447 if !reflect.DeepEqual(actual, expect) { 448 t.Errorf(`Context.RenderError(%#v, %#v, %#v) => %#v; want %#v`, v.status, nil, nil, actual, expect) 449 } 450 451 actual = c.Response.StatusCode 452 expect = v.status 453 if !reflect.DeepEqual(actual, expect) { 454 t.Errorf(`Context.RenderError(%#v, %#v, %#v); HTTP status => %#v; want %#v`, v.status, nil, nil, actual, expect) 455 } 456 } 457 458 for _, v := range []struct { 459 err error 460 contentType string 461 expect error 462 }{ 463 {nil, "unknown/content-type", fmt.Errorf("kocha: unknown Content-Type: unknown/content-type")}, 464 {fmt.Errorf("expected error"), "unknown/content-type", fmt.Errorf("kocha: unknown Content-Type: unknown/content-type")}, 465 } { 466 c := newTestContext("testctrlr", "") 467 var buf bytes.Buffer 468 c.App.Logger = log.New(&buf, c.App.Config.Logger.Formatter, c.App.Config.Logger.Level) 469 c.Response.ContentType = v.contentType 470 var actual interface{} = fmt.Sprint(c.RenderError(http.StatusInternalServerError, v.err, nil)) 471 var expect interface{} = fmt.Sprint(v.expect) 472 if !reflect.DeepEqual(actual, expect) { 473 t.Errorf(`Context.RenderError(%#v, %#v, %#v) => %+v; want %+v`, http.StatusInternalServerError, nil, nil, actual, expect) 474 } 475 476 func() { 477 actual := buf.String() 478 expect := fmt.Sprintf("message:%v", v.err) 479 if v.err != nil && !strings.Contains(actual, expect) { 480 t.Errorf(`Context.RenderError(%#v, %#v, %#v); log => %#v; want %#v`, http.StatusInternalServerError, v.err, nil, actual, expect) 481 } 482 }() 483 } 484 } 485 486 func TestContext_SendFile(t *testing.T) { 487 // general test 488 func() { 489 tmpFile, err := ioutil.TempFile("", "TestContextSendFile") 490 if err != nil { 491 t.Fatal(err) 492 } 493 defer tmpFile.Close() 494 defer os.Remove(tmpFile.Name()) 495 if _, err := tmpFile.WriteString("foobarbaz"); err != nil { 496 t.Fatal(err) 497 } 498 c := newTestContext("testctrlr", "") 499 w := httptest.NewRecorder() 500 c.Response = &kocha.Response{ResponseWriter: w} 501 if err := c.SendFile(tmpFile.Name()); err != nil { 502 t.Fatal(err) 503 } 504 buf, err := ioutil.ReadAll(w.Body) 505 if err != nil { 506 t.Fatal(err) 507 } 508 actual := string(buf) 509 expected := "foobarbaz" 510 if !reflect.DeepEqual(actual, expected) { 511 t.Errorf("Expect %v, but %v", expected, actual) 512 } 513 }() 514 515 // test default static path 516 func() { 517 tmpDir := filepath.Join(os.TempDir(), kocha.StaticDir) 518 if err := os.Mkdir(tmpDir, 0755); err != nil { 519 t.Fatal(err) 520 } 521 tmpFile, err := ioutil.TempFile(tmpDir, "TestContextSendFile") 522 if err != nil { 523 panic(err) 524 } 525 defer tmpFile.Close() 526 defer os.RemoveAll(tmpDir) 527 c := newTestContext("testctrlr", "") 528 c.App.Config.AppPath = filepath.Dir(tmpDir) 529 if _, err := tmpFile.WriteString("foobarbaz"); err != nil { 530 t.Fatal(err) 531 } 532 w := httptest.NewRecorder() 533 c.Response = &kocha.Response{ResponseWriter: w} 534 if err := c.SendFile(filepath.Base(tmpFile.Name())); err != nil { 535 t.Fatal(err) 536 } 537 buf, err := ioutil.ReadAll(w.Body) 538 if err != nil { 539 t.Fatal(err) 540 } 541 actual := string(buf) 542 expected := "foobarbaz" 543 if !reflect.DeepEqual(actual, expected) { 544 t.Errorf("Expect %v, but %v", expected, actual) 545 } 546 }() 547 548 // test file not found 549 func() { 550 c := newTestContext("testctrlr", "") 551 w := httptest.NewRecorder() 552 c.Response = &kocha.Response{ResponseWriter: w} 553 if err := c.SendFile("unknown/path"); err != nil { 554 t.Fatal(err) 555 } 556 buf, err := ioutil.ReadAll(w.Body) 557 if err != nil { 558 t.Fatal(err) 559 } 560 actual := string(buf) 561 expect := "" 562 if !reflect.DeepEqual(actual, expect) { 563 t.Errorf(`kocha.SendFile(c, "unknown/path").Proc(res); body => %#v; want %#v`, actual, expect) 564 } 565 }() 566 567 // test detect content type by body 568 func() { 569 tmpFile, err := ioutil.TempFile("", "TestContextSendFile") 570 if err != nil { 571 t.Fatal(err) 572 } 573 defer tmpFile.Close() 574 defer os.Remove(tmpFile.Name()) 575 if _, err := tmpFile.WriteString("foobarbaz"); err != nil { 576 t.Fatal(err) 577 } 578 c := newTestContext("testctrlr", "") 579 if err := c.SendFile(tmpFile.Name()); err != nil { 580 t.Fatal(err) 581 } 582 actual := c.Response.ContentType 583 expected := "text/plain; charset=utf-8" 584 if !reflect.DeepEqual(actual, expected) { 585 t.Errorf("Expect %v, but %v", expected, actual) 586 } 587 588 c.Response.ContentType = "" 589 if _, err := tmpFile.Seek(0, os.SEEK_SET); err != nil { 590 t.Fatal(err) 591 } 592 if _, err := tmpFile.Write([]byte("\x89PNG\x0d\x0a\x1a\x0a")); err != nil { 593 t.Fatal(err) 594 } 595 if err := c.SendFile(tmpFile.Name()); err != nil { 596 t.Fatal(err) 597 } 598 actual = c.Response.ContentType 599 expected = "image/png" 600 if !reflect.DeepEqual(actual, expected) { 601 t.Errorf("Expect %v, but %v", expected, actual) 602 } 603 }() 604 605 // test detect content type by ext 606 func() { 607 currentPath, err := os.Getwd() 608 if err != nil { 609 t.Fatal(err) 610 } 611 tmpFile, err := os.Open(filepath.Join(currentPath, "testdata", "public", "test.js")) 612 if err != nil { 613 t.Fatal(err) 614 } 615 defer tmpFile.Close() 616 mime.AddExtensionType(".js", "application/javascript") // To avoid differences between environments. 617 c := newTestContext("testctrlr", "") 618 if err := c.SendFile(tmpFile.Name()); err != nil { 619 t.Fatal(err) 620 } 621 actual := c.Response.ContentType 622 expected := "application/javascript" 623 if !reflect.DeepEqual(actual, expected) { 624 t.Errorf("Expect %v, but %v", expected, actual) 625 } 626 }() 627 628 // test with included resources 629 func() { 630 c := newTestContext("testctrlr", "") 631 c.App.ResourceSet.Add("testrcname", "foobarbaz") 632 w := httptest.NewRecorder() 633 c.Response = &kocha.Response{ResponseWriter: w} 634 if err := c.SendFile("testrcname"); err != nil { 635 t.Fatal(err) 636 } 637 buf, err := ioutil.ReadAll(w.Body) 638 if err != nil { 639 t.Fatal(err) 640 } 641 actual := string(buf) 642 expected := "foobarbaz" 643 if !reflect.DeepEqual(actual, expected) { 644 t.Errorf("Expect %v, but %v", expected, actual) 645 } 646 }() 647 648 // test detect content type with included resources 649 func() { 650 c := newTestContext("testctrlr", "") 651 c.Response.ContentType = "" 652 c.App.ResourceSet.Add("testrcname", "\x89PNG\x0d\x0a\x1a\x0a") 653 if err := c.SendFile("testrcname"); err != nil { 654 t.Fatal(err) 655 } 656 actual := c.Response.ContentType 657 expected := "image/png" 658 if !reflect.DeepEqual(actual, expected) { 659 t.Errorf("Expect %v, but %v", expected, actual) 660 } 661 }() 662 } 663 664 func TestContext_Redirect(t *testing.T) { 665 c := newTestContext("testctrlr", "") 666 for _, v := range []struct { 667 redirectURL string 668 permanent bool 669 expected int 670 }{ 671 {"/path/to/redirect/permanently", true, 301}, 672 {"/path/to/redirect", false, 302}, 673 } { 674 w := httptest.NewRecorder() 675 c.Response = &kocha.Response{ResponseWriter: w} 676 if err := c.Redirect(v.redirectURL, v.permanent); err != nil { 677 t.Fatal(err) 678 } 679 actual := []interface{}{w.Code, w.HeaderMap.Get("Location")} 680 expected := []interface{}{v.expected, v.redirectURL} 681 if !reflect.DeepEqual(actual, expected) { 682 t.Errorf(`Controller.Redirect("%#v", %#v) => %#v; want %#v`, v.redirectURL, v.permanent, actual, expected) 683 } 684 } 685 }