iris/core/router/route_register_rule_test.go
2023-08-04 17:59:00 +03:00

121 lines
3.7 KiB
Go

package router_test
import (
"bytes"
"reflect"
"testing"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/core/router"
"github.com/kataras/iris/v12/httptest"
)
func TestRegisterRule(t *testing.T) {
app := iris.New()
app.Configure(iris.WithDynamicHandler)
// collect the error on RouteError rule.
buf := new(bytes.Buffer)
app.Logger().SetTimeFormat("").DisableNewLine().SetOutput(buf)
v1 := app.Party("/v1")
v1.SetRegisterRule(iris.RouteSkip)
getHandler := func(ctx iris.Context) {
ctx.Writef("[get] %s", ctx.Method())
}
anyHandler := func(ctx iris.Context) {
ctx.Writef("[any] %s", ctx.Method())
}
getRoute := v1.Get("/", getHandler)
v1.Any("/", anyHandler)
if route := v1.Get("/", getHandler); !reflect.DeepEqual(route, getRoute) {
t.Fatalf("expected route to be equal with the original get route")
}
// test RouteSkip.
e := httptest.New(t, app, httptest.LogLevel("error"))
testRegisterRule(e, "[get] GET")
// test RouteOverride (default behavior).
v1.SetRegisterRule(iris.RouteOverride)
v1.Any("/", anyHandler)
app.RefreshRouter()
testRegisterRule(e, "[any] GET")
// test RouteError.
v1.SetRegisterRule(iris.RouteError)
if route := v1.Get("/", getHandler); route != nil {
t.Fatalf("expected duplicated route, with RouteError rule, to be nil but got: %#+v", route)
}
if expected, got := "[ERRO] new route: GET /v1 conflicts with an already registered one: GET /v1 route", buf.String(); expected != got {
t.Fatalf("expected api builder's error to be:\n'%s'\nbut got:\n'%s'", expected, got)
}
}
func testRegisterRule(e *httptest.Expect, expectedGetBody string) {
for _, method := range router.AllMethods {
tt := e.Request(method, "/v1").Expect().Status(httptest.StatusOK).Body()
if method == iris.MethodGet {
tt.IsEqual(expectedGetBody)
} else {
tt.IsEqual("[any] " + method)
}
}
}
func TestRegisterRuleOverlap(t *testing.T) {
app := iris.New()
// TODO(@kataras) the overlapping does not work per-party yet,
// it just checks compares from the total app's routes (which is the best possible action to do
// because MVC applications can be separated into different parties too?).
usersRouter := app.Party("/users")
usersRouter.SetRegisterRule(iris.RouteOverlap)
// second handler will be executed, status will be reset-ed as well,
// stop without data written.
usersRouter.Get("/", func(ctx iris.Context) {
ctx.StopWithStatus(iris.StatusUnauthorized)
})
usersRouter.Get("/", func(ctx iris.Context) {
ctx.StatusCode(iris.StatusOK)
ctx.WriteString("data")
})
// first handler will be executed, no stop called.
usersRouter.Get("/p1", func(ctx iris.Context) {
ctx.StatusCode(iris.StatusUnauthorized)
})
usersRouter.Get("/p1", func(ctx iris.Context) {
ctx.WriteString("not written")
})
// first handler will be executed, stop but with data sent on default writer
// (body sent cannot be reset-ed here).
usersRouter.Get("/p2", func(ctx iris.Context) {
ctx.StopWithText(iris.StatusUnauthorized, "no access")
})
usersRouter.Get("/p2", func(ctx iris.Context) {
ctx.WriteString("not written")
})
// second will be executed, response can be reset-ed on recording.
usersRouter.Get("/p3", func(ctx iris.Context) {
ctx.Record()
ctx.StopWithText(iris.StatusUnauthorized, "no access")
})
usersRouter.Get("/p3", func(ctx iris.Context) {
ctx.StatusCode(iris.StatusOK)
ctx.WriteString("p3 data")
})
e := httptest.New(t, app)
e.GET("/users").Expect().Status(httptest.StatusOK).Body().IsEqual("data")
e.GET("/users/p1").Expect().Status(httptest.StatusUnauthorized).Body().IsEqual("Unauthorized")
e.GET("/users/p2").Expect().Status(httptest.StatusUnauthorized).Body().IsEqual("no access")
e.GET("/users/p3").Expect().Status(httptest.StatusOK).Body().IsEqual("p3 data")
}