diff --git a/server/web/namespace_test.go b/server/web/namespace_test.go index 05042c96..2bf2480e 100644 --- a/server/web/namespace_test.go +++ b/server/web/namespace_test.go @@ -23,6 +23,20 @@ import ( "github.com/beego/beego/v2/server/web/context" ) +const exampleBody = "hello world" + +type ExampleController struct { + Controller +} + +func (m ExampleController) Ping() { + m.Ctx.Output.Body([]byte(exampleBody)) +} + +func (m ExampleController) ping() { + m.Ctx.Output.Body([]byte(exampleBody)) +} + func TestNamespaceGet(t *testing.T) { r, _ := http.NewRequest("GET", "/v1/user", nil) w := httptest.NewRecorder() @@ -166,3 +180,215 @@ func TestNamespaceInside(t *testing.T) { t.Errorf("TestNamespaceInside can't run, get the response is " + w.Body.String()) } } + +func TestNamespaceRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterGet("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterGet can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterPost("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPost can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterDelete("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterDelete can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterPut("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPut can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterHead("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterHead can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterOptions(t *testing.T) { + r, _ := http.NewRequest(http.MethodOptions, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterOptions("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterOptions can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + ns.RouterPatch("/user", ExampleController.Ping) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPatch can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceRouterAny(t *testing.T) { + ns := NewNamespace("/v1") + ns.RouterAny("/user", ExampleController.Ping) + AddNamespace(ns) + + for method, _ := range HTTPMETHOD { + w := httptest.NewRecorder() + r, _ := http.NewRequest(method, "/v1/user", nil) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) + } + } +} + +func TestNamespaceNSRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterGet("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterGet can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterPost("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPost can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterDelete("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterDelete can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterPut("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPut can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterHead("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterHead can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterOptions(t *testing.T) { + r, _ := http.NewRequest(http.MethodOptions, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterOptions("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterOptions can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/v1/user", nil) + w := httptest.NewRecorder() + + ns := NewNamespace("/v1") + NSRouterPatch("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterPatch can't run, get the response is " + w.Body.String()) + } +} + +func TestNamespaceNSRouterAny(t *testing.T) { + ns := NewNamespace("/v1") + NSRouterAny("/user", ExampleController.Ping)(ns) + AddNamespace(ns) + + for method, _ := range HTTPMETHOD { + w := httptest.NewRecorder() + r, _ := http.NewRequest(method, "/v1/user", nil) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestNamespaceRouterAny can't run, get the response is " + w.Body.String()) + } + } +} diff --git a/server/web/router.go b/server/web/router.go index af143d1a..0eb93d5a 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -361,7 +361,7 @@ func (p *ControllerRegister) RouterPost(pattern string, f interface{}) { p.AddRouterMethod(http.MethodPost, pattern, f) } -// RouterHead add post method +// RouterHead add head method // usage: // type MyController struct { // web.Controller @@ -375,7 +375,7 @@ func (p *ControllerRegister) RouterHead(pattern string, f interface{}) { p.AddRouterMethod(http.MethodHead, pattern, f) } -// RouterPut add post method +// RouterPut add put method // usage: // type MyController struct { // web.Controller @@ -389,7 +389,7 @@ func (p *ControllerRegister) RouterPut(pattern string, f interface{}) { p.AddRouterMethod(http.MethodPut, pattern, f) } -// RouterPatch add post method +// RouterPatch add patch method // usage: // type MyController struct { // web.Controller @@ -403,7 +403,7 @@ func (p *ControllerRegister) RouterPatch(pattern string, f interface{}) { p.AddRouterMethod(http.MethodPatch, pattern, f) } -// RouterDelete add post method +// RouterDelete add delete method // usage: // type MyController struct { // web.Controller @@ -417,7 +417,7 @@ func (p *ControllerRegister) RouterDelete(pattern string, f interface{}) { p.AddRouterMethod(http.MethodDelete, pattern, f) } -// RouterOptions add post method +// RouterOptions add options method // usage: // type MyController struct { // web.Controller @@ -431,7 +431,7 @@ func (p *ControllerRegister) RouterOptions(pattern string, f interface{}) { p.AddRouterMethod(http.MethodOptions, pattern, f) } -// RouterAny add post method +// RouterAny add all method // usage: // type MyController struct { // web.Controller @@ -467,8 +467,20 @@ func (p *ControllerRegister) AddRouterMethod(method, pattern string, f interface route.routerType = routerTypeBeego route.sessionOn = p.cfg.WebConfig.Session.SessionOn route.controllerType = ct - route.methods = map[string]string{method: methodName} - p.addToRouter(method, pattern, route) + + methods := make(map[string]string) + if method == "*" { + for val := range HTTPMETHOD { + methods[val] = methodName + } + } else { + methods[method] = methodName + } + route.methods = methods + + for method, _ := range methods { + p.addToRouter(method, pattern, route) + } } // get reflect controller type and method by controller method expression diff --git a/server/web/router_test.go b/server/web/router_test.go index 474405e8..9e5ee79d 100644 --- a/server/web/router_test.go +++ b/server/web/router_test.go @@ -16,6 +16,7 @@ package web import ( "bytes" + "fmt" "net/http" "net/http/httptest" "strings" @@ -34,6 +35,12 @@ func (ptc *PrefixTestController) PrefixList() { ptc.Ctx.Output.Body([]byte("i am list in prefix test")) } +type TestControllerWithInterface struct { +} + +func (m TestControllerWithInterface) Ping() { +} + type TestController struct { Controller } @@ -95,7 +102,7 @@ func (jc *JSONController) Get() { jc.Ctx.Output.Body([]byte("ok")) } -func TestPrefixUrlFor(t *testing.T){ +func TestPrefixUrlFor(t *testing.T) { handler := NewControllerRegister() handler.Add("/my/prefix/list", &PrefixTestController{}, WithRouterMethods(&PrefixTestController{}, "get:PrefixList")) @@ -828,3 +835,161 @@ func TestRouterSessionSet(t *testing.T) { } } + +func TestRouterRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterGet("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterGet can't run") + } +} + +func TestRouterRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterPost("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterPost can't run") + } +} + +func TestRouterRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterHead("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterHead can't run") + } +} + +func TestRouterRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterPut("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterPut can't run") + } +} + +func TestRouterRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterPatch("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterPatch can't run") + } +} + +func TestRouterRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/user", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.RouterDelete("/user", ExampleController.Ping) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterDelete can't run") + } +} + +func TestRouterRouterAny(t *testing.T) { + handler := NewControllerRegister() + handler.RouterAny("/user", ExampleController.Ping) + + for method, _ := range HTTPMETHOD { + w := httptest.NewRecorder() + r, _ := http.NewRequest(method, "/user", nil) + handler.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestRouterRouterAny can't run, get the response is " + w.Body.String()) + } + } +} + +func TestRouterAddRouterMethodPanicInvalidMethod(t *testing.T) { + method := "some random method" + message := "not support http method: " + strings.ToUpper(method) + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", ExampleController.Ping) +} + +func TestRouterAddRouterMethodPanicNotAMethod(t *testing.T) { + method := http.MethodGet + message := "not a method" + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", ExampleController{}) +} + +func TestRouterAddRouterMethodPanicNotPublicMethod(t *testing.T) { + method := http.MethodGet + message := "not a public method" + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidMethod failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", ExampleController.ping) +} + +func TestRouterAddRouterMethodPanicNotImplementInterface(t *testing.T) { + method := http.MethodGet + message := "web.TestControllerWithInterface is not implemented ControllerInterface" + defer func() { + err := recover() + if err != nil { //产生了panic异常 + errStr, ok := err.(string) + if ok && errStr == message { + return + } + } + t.Errorf(fmt.Sprintf("TestRouterAddRouterMethodPanicInvalidNumberParamIn failed: %v", err)) + }() + + handler := NewControllerRegister() + handler.AddRouterMethod(method, "/user", TestControllerWithInterface.Ping) +} diff --git a/server/web/server.go b/server/web/server.go index b61b85de..be8ec228 100644 --- a/server/web/server.go +++ b/server/web/server.go @@ -503,7 +503,7 @@ func (app *HttpServer) RouterPost(rootpath string, f interface{}) *HttpServer { // RouterHead see HttpServer.RouterHead func RouterHead(rootpath string, f interface{}) { - BeeApp.RouterPost(rootpath, f) + BeeApp.RouterHead(rootpath, f) } // RouterHead used to register router for RouterHead method @@ -523,7 +523,7 @@ func (app *HttpServer) RouterHead(rootpath string, f interface{}) *HttpServer { // RouterPut see HttpServer.RouterPut func RouterPut(rootpath string, f interface{}) { - BeeApp.RouterPost(rootpath, f) + BeeApp.RouterPut(rootpath, f) } // RouterPut used to register router for RouterPut method @@ -603,7 +603,7 @@ func (app *HttpServer) RouterOptions(rootpath string, f interface{}) *HttpServer // RouterAny see HttpServer.RouterAny func RouterAny(rootpath string, f interface{}) { - BeeApp.RouterOptions(rootpath, f) + BeeApp.RouterAny(rootpath, f) } // RouterAny used to register router for RouterAny method diff --git a/server/web/server_test.go b/server/web/server_test.go index 0b0c601c..bdc5b008 100644 --- a/server/web/server_test.go +++ b/server/web/server_test.go @@ -15,6 +15,8 @@ package web import ( + "net/http" + "net/http/httptest" "testing" "github.com/stretchr/testify/assert" @@ -28,3 +30,82 @@ func TestNewHttpServerWithCfg(t *testing.T) { assert.Equal(t, "hello", BConfig.AppName) } + +func TestServerRouterGet(t *testing.T) { + r, _ := http.NewRequest(http.MethodGet, "/user", nil) + w := httptest.NewRecorder() + + RouterGet("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterGet can't run") + } +} + +func TestServerRouterPost(t *testing.T) { + r, _ := http.NewRequest(http.MethodPost, "/user", nil) + w := httptest.NewRecorder() + + RouterPost("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterPost can't run") + } +} + +func TestServerRouterHead(t *testing.T) { + r, _ := http.NewRequest(http.MethodHead, "/user", nil) + w := httptest.NewRecorder() + + RouterHead("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterHead can't run") + } +} + +func TestServerRouterPut(t *testing.T) { + r, _ := http.NewRequest(http.MethodPut, "/user", nil) + w := httptest.NewRecorder() + + RouterPut("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterPut can't run") + } +} + +func TestServerRouterPatch(t *testing.T) { + r, _ := http.NewRequest(http.MethodPatch, "/user", nil) + w := httptest.NewRecorder() + + RouterPatch("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterPatch can't run") + } +} + +func TestServerRouterDelete(t *testing.T) { + r, _ := http.NewRequest(http.MethodDelete, "/user", nil) + w := httptest.NewRecorder() + + RouterDelete("/user", ExampleController.Ping) + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterDelete can't run") + } +} + +func TestServerRouterAny(t *testing.T) { + RouterAny("/user", ExampleController.Ping) + + for method, _ := range HTTPMETHOD { + r, _ := http.NewRequest(method, "/user", nil) + w := httptest.NewRecorder() + BeeApp.Handlers.ServeHTTP(w, r) + if w.Body.String() != exampleBody { + t.Errorf("TestServerRouterAny can't run") + } + } +}