github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/gin_test.go (about) 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 5 package gin 6 7 import ( 8 "fmt" 9 "github.com/hellobchain/newcryptosm/http" 10 "github.com/hellobchain/newcryptosm/http/httptest" 11 "github.com/hellobchain/newcryptosm/tls" 12 "html/template" 13 "io/ioutil" 14 "net" 15 "reflect" 16 "strconv" 17 "sync/atomic" 18 "testing" 19 "time" 20 21 "github.com/stretchr/testify/assert" 22 ) 23 24 func formatAsDate(t time.Time) string { 25 year, month, day := t.Date() 26 return fmt.Sprintf("%d/%02d/%02d", year, month, day) 27 } 28 29 func setupHTMLFiles(t *testing.T, mode string, tls bool, loadMethod func(*Engine)) *httptest.Server { 30 SetMode(mode) 31 defer SetMode(TestMode) 32 33 var router *Engine 34 captureOutput(t, func() { 35 router = New() 36 router.Delims("{[{", "}]}") 37 router.SetFuncMap(template.FuncMap{ 38 "formatAsDate": formatAsDate, 39 }) 40 loadMethod(router) 41 router.GET("/test", func(c *Context) { 42 c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"}) 43 }) 44 router.GET("/raw", func(c *Context) { 45 c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{ 46 "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC), 47 }) 48 }) 49 }) 50 51 var ts *httptest.Server 52 53 if tls { 54 ts = httptest.NewTLSServer(router) 55 } else { 56 ts = httptest.NewServer(router) 57 } 58 59 return ts 60 } 61 62 func TestLoadHTMLGlobDebugMode(t *testing.T) { 63 ts := setupHTMLFiles( 64 t, 65 DebugMode, 66 false, 67 func(router *Engine) { 68 router.LoadHTMLGlob("./testdata/template/*") 69 }, 70 ) 71 defer ts.Close() 72 73 res, err := http.Get(fmt.Sprintf("%s/test", ts.URL)) 74 if err != nil { 75 fmt.Println(err) 76 } 77 78 resp, _ := ioutil.ReadAll(res.Body) 79 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 80 } 81 82 func TestLoadHTMLGlobTestMode(t *testing.T) { 83 ts := setupHTMLFiles( 84 t, 85 TestMode, 86 false, 87 func(router *Engine) { 88 router.LoadHTMLGlob("./testdata/template/*") 89 }, 90 ) 91 defer ts.Close() 92 93 res, err := http.Get(fmt.Sprintf("%s/test", ts.URL)) 94 if err != nil { 95 fmt.Println(err) 96 } 97 98 resp, _ := ioutil.ReadAll(res.Body) 99 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 100 } 101 102 func TestLoadHTMLGlobReleaseMode(t *testing.T) { 103 ts := setupHTMLFiles( 104 t, 105 ReleaseMode, 106 false, 107 func(router *Engine) { 108 router.LoadHTMLGlob("./testdata/template/*") 109 }, 110 ) 111 defer ts.Close() 112 113 res, err := http.Get(fmt.Sprintf("%s/test", ts.URL)) 114 if err != nil { 115 fmt.Println(err) 116 } 117 118 resp, _ := ioutil.ReadAll(res.Body) 119 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 120 } 121 122 func TestLoadHTMLGlobUsingTLS(t *testing.T) { 123 ts := setupHTMLFiles( 124 t, 125 DebugMode, 126 true, 127 func(router *Engine) { 128 router.LoadHTMLGlob("./testdata/template/*") 129 }, 130 ) 131 defer ts.Close() 132 133 // Use InsecureSkipVerify for avoiding `x509: certificate signed by unknown authority` error 134 tr := &http.Transport{ 135 TLSClientConfig: &tls.Config{ 136 InsecureSkipVerify: true, 137 }, 138 } 139 client := &http.Client{Transport: tr} 140 res, err := client.Get(fmt.Sprintf("%s/test", ts.URL)) 141 if err != nil { 142 fmt.Println(err) 143 } 144 145 resp, _ := ioutil.ReadAll(res.Body) 146 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 147 } 148 149 func TestLoadHTMLGlobFromFuncMap(t *testing.T) { 150 ts := setupHTMLFiles( 151 t, 152 DebugMode, 153 false, 154 func(router *Engine) { 155 router.LoadHTMLGlob("./testdata/template/*") 156 }, 157 ) 158 defer ts.Close() 159 160 res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL)) 161 if err != nil { 162 fmt.Println(err) 163 } 164 165 resp, _ := ioutil.ReadAll(res.Body) 166 assert.Equal(t, "Date: 2017/07/01\n", string(resp)) 167 } 168 169 func init() { 170 SetMode(TestMode) 171 } 172 173 func TestCreateEngine(t *testing.T) { 174 router := New() 175 assert.Equal(t, "/", router.basePath) 176 assert.Equal(t, router.engine, router) 177 assert.Empty(t, router.Handlers) 178 } 179 180 func TestLoadHTMLFilesTestMode(t *testing.T) { 181 ts := setupHTMLFiles( 182 t, 183 TestMode, 184 false, 185 func(router *Engine) { 186 router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl") 187 }, 188 ) 189 defer ts.Close() 190 191 res, err := http.Get(fmt.Sprintf("%s/test", ts.URL)) 192 if err != nil { 193 fmt.Println(err) 194 } 195 196 resp, _ := ioutil.ReadAll(res.Body) 197 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 198 } 199 200 func TestLoadHTMLFilesDebugMode(t *testing.T) { 201 ts := setupHTMLFiles( 202 t, 203 DebugMode, 204 false, 205 func(router *Engine) { 206 router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl") 207 }, 208 ) 209 defer ts.Close() 210 211 res, err := http.Get(fmt.Sprintf("%s/test", ts.URL)) 212 if err != nil { 213 fmt.Println(err) 214 } 215 216 resp, _ := ioutil.ReadAll(res.Body) 217 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 218 } 219 220 func TestLoadHTMLFilesReleaseMode(t *testing.T) { 221 ts := setupHTMLFiles( 222 t, 223 ReleaseMode, 224 false, 225 func(router *Engine) { 226 router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl") 227 }, 228 ) 229 defer ts.Close() 230 231 res, err := http.Get(fmt.Sprintf("%s/test", ts.URL)) 232 if err != nil { 233 fmt.Println(err) 234 } 235 236 resp, _ := ioutil.ReadAll(res.Body) 237 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 238 } 239 240 func TestLoadHTMLFilesUsingTLS(t *testing.T) { 241 ts := setupHTMLFiles( 242 t, 243 TestMode, 244 true, 245 func(router *Engine) { 246 router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl") 247 }, 248 ) 249 defer ts.Close() 250 251 // Use InsecureSkipVerify for avoiding `x509: certificate signed by unknown authority` error 252 tr := &http.Transport{ 253 TLSClientConfig: &tls.Config{ 254 InsecureSkipVerify: true, 255 }, 256 } 257 client := &http.Client{Transport: tr} 258 res, err := client.Get(fmt.Sprintf("%s/test", ts.URL)) 259 if err != nil { 260 fmt.Println(err) 261 } 262 263 resp, _ := ioutil.ReadAll(res.Body) 264 assert.Equal(t, "<h1>Hello world</h1>", string(resp)) 265 } 266 267 func TestLoadHTMLFilesFuncMap(t *testing.T) { 268 ts := setupHTMLFiles( 269 t, 270 TestMode, 271 false, 272 func(router *Engine) { 273 router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl") 274 }, 275 ) 276 defer ts.Close() 277 278 res, err := http.Get(fmt.Sprintf("%s/raw", ts.URL)) 279 if err != nil { 280 fmt.Println(err) 281 } 282 283 resp, _ := ioutil.ReadAll(res.Body) 284 assert.Equal(t, "Date: 2017/07/01\n", string(resp)) 285 } 286 287 func TestAddRoute(t *testing.T) { 288 router := New() 289 router.addRoute("GET", "/", HandlersChain{func(_ *Context) {}}) 290 291 assert.Len(t, router.trees, 1) 292 assert.NotNil(t, router.trees.get("GET")) 293 assert.Nil(t, router.trees.get("POST")) 294 295 router.addRoute("POST", "/", HandlersChain{func(_ *Context) {}}) 296 297 assert.Len(t, router.trees, 2) 298 assert.NotNil(t, router.trees.get("GET")) 299 assert.NotNil(t, router.trees.get("POST")) 300 301 router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}}) 302 assert.Len(t, router.trees, 2) 303 } 304 305 func TestAddRouteFails(t *testing.T) { 306 router := New() 307 assert.Panics(t, func() { router.addRoute("", "/", HandlersChain{func(_ *Context) {}}) }) 308 assert.Panics(t, func() { router.addRoute("GET", "a", HandlersChain{func(_ *Context) {}}) }) 309 assert.Panics(t, func() { router.addRoute("GET", "/", HandlersChain{}) }) 310 311 router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}}) 312 assert.Panics(t, func() { 313 router.addRoute("POST", "/post", HandlersChain{func(_ *Context) {}}) 314 }) 315 } 316 317 func TestCreateDefaultRouter(t *testing.T) { 318 router := Default() 319 assert.Len(t, router.Handlers, 2) 320 } 321 322 func TestNoRouteWithoutGlobalHandlers(t *testing.T) { 323 var middleware0 HandlerFunc = func(c *Context) {} 324 var middleware1 HandlerFunc = func(c *Context) {} 325 326 router := New() 327 328 router.NoRoute(middleware0) 329 assert.Nil(t, router.Handlers) 330 assert.Len(t, router.noRoute, 1) 331 assert.Len(t, router.allNoRoute, 1) 332 compareFunc(t, router.noRoute[0], middleware0) 333 compareFunc(t, router.allNoRoute[0], middleware0) 334 335 router.NoRoute(middleware1, middleware0) 336 assert.Len(t, router.noRoute, 2) 337 assert.Len(t, router.allNoRoute, 2) 338 compareFunc(t, router.noRoute[0], middleware1) 339 compareFunc(t, router.allNoRoute[0], middleware1) 340 compareFunc(t, router.noRoute[1], middleware0) 341 compareFunc(t, router.allNoRoute[1], middleware0) 342 } 343 344 func TestNoRouteWithGlobalHandlers(t *testing.T) { 345 var middleware0 HandlerFunc = func(c *Context) {} 346 var middleware1 HandlerFunc = func(c *Context) {} 347 var middleware2 HandlerFunc = func(c *Context) {} 348 349 router := New() 350 router.Use(middleware2) 351 352 router.NoRoute(middleware0) 353 assert.Len(t, router.allNoRoute, 2) 354 assert.Len(t, router.Handlers, 1) 355 assert.Len(t, router.noRoute, 1) 356 357 compareFunc(t, router.Handlers[0], middleware2) 358 compareFunc(t, router.noRoute[0], middleware0) 359 compareFunc(t, router.allNoRoute[0], middleware2) 360 compareFunc(t, router.allNoRoute[1], middleware0) 361 362 router.Use(middleware1) 363 assert.Len(t, router.allNoRoute, 3) 364 assert.Len(t, router.Handlers, 2) 365 assert.Len(t, router.noRoute, 1) 366 367 compareFunc(t, router.Handlers[0], middleware2) 368 compareFunc(t, router.Handlers[1], middleware1) 369 compareFunc(t, router.noRoute[0], middleware0) 370 compareFunc(t, router.allNoRoute[0], middleware2) 371 compareFunc(t, router.allNoRoute[1], middleware1) 372 compareFunc(t, router.allNoRoute[2], middleware0) 373 } 374 375 func TestNoMethodWithoutGlobalHandlers(t *testing.T) { 376 var middleware0 HandlerFunc = func(c *Context) {} 377 var middleware1 HandlerFunc = func(c *Context) {} 378 379 router := New() 380 381 router.NoMethod(middleware0) 382 assert.Empty(t, router.Handlers) 383 assert.Len(t, router.noMethod, 1) 384 assert.Len(t, router.allNoMethod, 1) 385 compareFunc(t, router.noMethod[0], middleware0) 386 compareFunc(t, router.allNoMethod[0], middleware0) 387 388 router.NoMethod(middleware1, middleware0) 389 assert.Len(t, router.noMethod, 2) 390 assert.Len(t, router.allNoMethod, 2) 391 compareFunc(t, router.noMethod[0], middleware1) 392 compareFunc(t, router.allNoMethod[0], middleware1) 393 compareFunc(t, router.noMethod[1], middleware0) 394 compareFunc(t, router.allNoMethod[1], middleware0) 395 } 396 397 func TestRebuild404Handlers(t *testing.T) { 398 399 } 400 401 func TestNoMethodWithGlobalHandlers(t *testing.T) { 402 var middleware0 HandlerFunc = func(c *Context) {} 403 var middleware1 HandlerFunc = func(c *Context) {} 404 var middleware2 HandlerFunc = func(c *Context) {} 405 406 router := New() 407 router.Use(middleware2) 408 409 router.NoMethod(middleware0) 410 assert.Len(t, router.allNoMethod, 2) 411 assert.Len(t, router.Handlers, 1) 412 assert.Len(t, router.noMethod, 1) 413 414 compareFunc(t, router.Handlers[0], middleware2) 415 compareFunc(t, router.noMethod[0], middleware0) 416 compareFunc(t, router.allNoMethod[0], middleware2) 417 compareFunc(t, router.allNoMethod[1], middleware0) 418 419 router.Use(middleware1) 420 assert.Len(t, router.allNoMethod, 3) 421 assert.Len(t, router.Handlers, 2) 422 assert.Len(t, router.noMethod, 1) 423 424 compareFunc(t, router.Handlers[0], middleware2) 425 compareFunc(t, router.Handlers[1], middleware1) 426 compareFunc(t, router.noMethod[0], middleware0) 427 compareFunc(t, router.allNoMethod[0], middleware2) 428 compareFunc(t, router.allNoMethod[1], middleware1) 429 compareFunc(t, router.allNoMethod[2], middleware0) 430 } 431 432 func compareFunc(t *testing.T, a, b interface{}) { 433 sf1 := reflect.ValueOf(a) 434 sf2 := reflect.ValueOf(b) 435 if sf1.Pointer() != sf2.Pointer() { 436 t.Error("different functions") 437 } 438 } 439 440 func TestListOfRoutes(t *testing.T) { 441 router := New() 442 router.GET("/favicon.ico", handlerTest1) 443 router.GET("/", handlerTest1) 444 group := router.Group("/users") 445 { 446 group.GET("/", handlerTest2) 447 group.GET("/:id", handlerTest1) 448 group.POST("/:id", handlerTest2) 449 } 450 router.Static("/static", ".") 451 452 list := router.Routes() 453 454 assert.Len(t, list, 7) 455 assertRoutePresent(t, list, RouteInfo{ 456 Method: "GET", 457 Path: "/favicon.ico", 458 Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", 459 }) 460 assertRoutePresent(t, list, RouteInfo{ 461 Method: "GET", 462 Path: "/", 463 Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", 464 }) 465 assertRoutePresent(t, list, RouteInfo{ 466 Method: "GET", 467 Path: "/users/", 468 Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$", 469 }) 470 assertRoutePresent(t, list, RouteInfo{ 471 Method: "GET", 472 Path: "/users/:id", 473 Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest1$", 474 }) 475 assertRoutePresent(t, list, RouteInfo{ 476 Method: "POST", 477 Path: "/users/:id", 478 Handler: "^(.*/vendor/)?github.com/gin-gonic/gin.handlerTest2$", 479 }) 480 } 481 482 func TestEngineHandleContext(t *testing.T) { 483 r := New() 484 r.GET("/", func(c *Context) { 485 c.Request.URL.Path = "/v2" 486 r.HandleContext(c) 487 }) 488 v2 := r.Group("/v2") 489 { 490 v2.GET("/", func(c *Context) {}) 491 } 492 493 assert.NotPanics(t, func() { 494 w := performRequest(r, "GET", "/") 495 assert.Equal(t, 301, w.Code) 496 }) 497 } 498 499 func TestEngineHandleContextManyReEntries(t *testing.T) { 500 expectValue := 10000 501 502 var handlerCounter, middlewareCounter int64 503 504 r := New() 505 r.Use(func(c *Context) { 506 atomic.AddInt64(&middlewareCounter, 1) 507 }) 508 r.GET("/:count", func(c *Context) { 509 countStr := c.Param("count") 510 count, err := strconv.Atoi(countStr) 511 assert.NoError(t, err) 512 513 n, err := c.Writer.Write([]byte(".")) 514 assert.NoError(t, err) 515 assert.Equal(t, 1, n) 516 517 switch { 518 case count > 0: 519 c.Request.URL.Path = "/" + strconv.Itoa(count-1) 520 r.HandleContext(c) 521 } 522 }, func(c *Context) { 523 atomic.AddInt64(&handlerCounter, 1) 524 }) 525 526 assert.NotPanics(t, func() { 527 w := performRequest(r, "GET", "/"+strconv.Itoa(expectValue-1)) // include 0 value 528 assert.Equal(t, 200, w.Code) 529 assert.Equal(t, expectValue, w.Body.Len()) 530 }) 531 532 assert.Equal(t, int64(expectValue), handlerCounter) 533 assert.Equal(t, int64(expectValue), middlewareCounter) 534 } 535 536 func TestPrepareTrustedCIRDsWith(t *testing.T) { 537 r := New() 538 539 // valid ipv4 cidr 540 { 541 expectedTrustedCIDRs := []*net.IPNet{parseCIDR("0.0.0.0/0")} 542 r.TrustedProxies = []string{"0.0.0.0/0"} 543 544 trustedCIDRs, err := r.prepareTrustedCIDRs() 545 546 assert.NoError(t, err) 547 assert.Equal(t, expectedTrustedCIDRs, trustedCIDRs) 548 } 549 550 // invalid ipv4 cidr 551 { 552 r.TrustedProxies = []string{"192.168.1.33/33"} 553 554 _, err := r.prepareTrustedCIDRs() 555 556 assert.Error(t, err) 557 } 558 559 // valid ipv4 address 560 { 561 expectedTrustedCIDRs := []*net.IPNet{parseCIDR("192.168.1.33/32")} 562 r.TrustedProxies = []string{"192.168.1.33"} 563 564 trustedCIDRs, err := r.prepareTrustedCIDRs() 565 566 assert.NoError(t, err) 567 assert.Equal(t, expectedTrustedCIDRs, trustedCIDRs) 568 } 569 570 // invalid ipv4 address 571 { 572 r.TrustedProxies = []string{"192.168.1.256"} 573 574 _, err := r.prepareTrustedCIDRs() 575 576 assert.Error(t, err) 577 } 578 579 // valid ipv6 address 580 { 581 expectedTrustedCIDRs := []*net.IPNet{parseCIDR("2002:0000:0000:1234:abcd:ffff:c0a8:0101/128")} 582 r.TrustedProxies = []string{"2002:0000:0000:1234:abcd:ffff:c0a8:0101"} 583 584 trustedCIDRs, err := r.prepareTrustedCIDRs() 585 586 assert.NoError(t, err) 587 assert.Equal(t, expectedTrustedCIDRs, trustedCIDRs) 588 } 589 590 // invalid ipv6 address 591 { 592 r.TrustedProxies = []string{"gggg:0000:0000:1234:abcd:ffff:c0a8:0101"} 593 594 _, err := r.prepareTrustedCIDRs() 595 596 assert.Error(t, err) 597 } 598 599 // valid ipv6 cidr 600 { 601 expectedTrustedCIDRs := []*net.IPNet{parseCIDR("::/0")} 602 r.TrustedProxies = []string{"::/0"} 603 604 trustedCIDRs, err := r.prepareTrustedCIDRs() 605 606 assert.NoError(t, err) 607 assert.Equal(t, expectedTrustedCIDRs, trustedCIDRs) 608 } 609 610 // invalid ipv6 cidr 611 { 612 r.TrustedProxies = []string{"gggg:0000:0000:1234:abcd:ffff:c0a8:0101/129"} 613 614 _, err := r.prepareTrustedCIDRs() 615 616 assert.Error(t, err) 617 } 618 619 // valid combination 620 { 621 expectedTrustedCIDRs := []*net.IPNet{ 622 parseCIDR("::/0"), 623 parseCIDR("192.168.0.0/16"), 624 parseCIDR("172.16.0.1/32"), 625 } 626 r.TrustedProxies = []string{ 627 "::/0", 628 "192.168.0.0/16", 629 "172.16.0.1", 630 } 631 632 trustedCIDRs, err := r.prepareTrustedCIDRs() 633 634 assert.NoError(t, err) 635 assert.Equal(t, expectedTrustedCIDRs, trustedCIDRs) 636 } 637 638 // invalid combination 639 { 640 r.TrustedProxies = []string{ 641 "::/0", 642 "192.168.0.0/16", 643 "172.16.0.256", 644 } 645 _, err := r.prepareTrustedCIDRs() 646 647 assert.Error(t, err) 648 } 649 650 // nil value 651 { 652 r.TrustedProxies = nil 653 trustedCIDRs, err := r.prepareTrustedCIDRs() 654 655 assert.Nil(t, trustedCIDRs) 656 assert.Nil(t, err) 657 } 658 659 } 660 661 func parseCIDR(cidr string) *net.IPNet { 662 _, parsedCIDR, err := net.ParseCIDR(cidr) 663 if err != nil { 664 fmt.Println(err) 665 } 666 return parsedCIDR 667 } 668 669 func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo) { 670 for _, gotRoute := range gotRoutes { 671 if gotRoute.Path == wantRoute.Path && gotRoute.Method == wantRoute.Method { 672 assert.Regexp(t, wantRoute.Handler, gotRoute.Handler) 673 return 674 } 675 } 676 t.Errorf("route not found: %v", wantRoute) 677 } 678 679 func handlerTest1(c *Context) {} 680 func handlerTest2(c *Context) {}