// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️ // 🤖 Github Repository: https://github.com/gofiber/fiber // 📌 API Documentation: https://docs.gofiber.io //nolint:bodyclose // Much easier to just ignore memory leaks in tests package fiber import ( "errors" "io" "net/http/httptest" "testing" "github.com/stretchr/testify/require" ) // go test -run Test_App_Mount func Test_App_Mount(t *testing.T) { t.Parallel() micro := New() micro.Get("/doe", func(c Ctx) error { return c.SendStatus(StatusOK) }) app := New() app.Use("/john", micro) resp, err := app.Test(httptest.NewRequest(MethodGet, "/john/doe", nil)) require.Equal(t, nil, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, uint32(1), app.handlersCount) } func Test_App_Mount_RootPath_Nested(t *testing.T) { t.Parallel() app := New() dynamic := New() apiserver := New() apiroutes := apiserver.Group("/v1") apiroutes.Get("/home", func(c Ctx) error { return c.SendString("home") }) dynamic.Use("/api", apiserver) app.Use("/", dynamic) resp, err := app.Test(httptest.NewRequest(MethodGet, "/api/v1/home", nil)) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, uint32(1), app.handlersCount) } // go test -run Test_App_Mount_Nested func Test_App_Mount_Nested(t *testing.T) { t.Parallel() app := New() one := New() two := New() three := New() two.Use("/three", three) app.Use("/one", one) one.Use("/two", two) one.Get("/doe", func(c Ctx) error { return c.SendStatus(StatusOK) }) two.Get("/nested", func(c Ctx) error { return c.SendStatus(StatusOK) }) three.Get("/test", func(c Ctx) error { return c.SendStatus(StatusOK) }) resp, err := app.Test(httptest.NewRequest(MethodGet, "/one/doe", nil)) require.Equal(t, nil, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") resp, err = app.Test(httptest.NewRequest(MethodGet, "/one/two/nested", nil)) require.Equal(t, nil, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") resp, err = app.Test(httptest.NewRequest(MethodGet, "/one/two/three/test", nil)) require.Equal(t, nil, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, uint32(3), app.handlersCount) } // go test -run Test_App_MountPath func Test_App_MountPath(t *testing.T) { t.Parallel() app := New() one := New() two := New() three := New() two.Use("/three", three) one.Use("/two", two) app.Use("/one", one) require.Equal(t, "/one", one.MountPath()) require.Equal(t, "/one/two", two.MountPath()) require.Equal(t, "/one/two/three", three.MountPath()) require.Equal(t, "", app.MountPath()) } func Test_App_ErrorHandler_GroupMount(t *testing.T) { t.Parallel() micro := New(Config{ ErrorHandler: func(c Ctx, err error) error { require.Equal(t, "0: GET error", err.Error()) return c.Status(500).SendString("1: custom error") }, }) micro.Get("/doe", func(c Ctx) error { return errors.New("0: GET error") }) app := New() v1 := app.Group("/v1") v1.Use("/john", micro) resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil)) testErrorResponse(t, err, resp, "1: custom error") } func Test_App_ErrorHandler_GroupMountRootLevel(t *testing.T) { t.Parallel() micro := New(Config{ ErrorHandler: func(c Ctx, err error) error { require.Equal(t, "0: GET error", err.Error()) return c.Status(500).SendString("1: custom error") }, }) micro.Get("/john/doe", func(c Ctx) error { return errors.New("0: GET error") }) app := New() v1 := app.Group("/v1") v1.Use("/", micro) resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil)) testErrorResponse(t, err, resp, "1: custom error") } // go test -run Test_App_Group_Mount func Test_App_Group_Mount(t *testing.T) { t.Parallel() micro := New() micro.Get("/doe", func(c Ctx) error { return c.SendStatus(StatusOK) }) app := New() v1 := app.Group("/v1") v1.Use("/john", micro) resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil)) require.Equal(t, nil, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, uint32(1), app.handlersCount) } func Test_App_UseParentErrorHandler(t *testing.T) { t.Parallel() app := New(Config{ ErrorHandler: func(ctx Ctx, err error) error { return ctx.Status(500).SendString("hi, i'm a custom error") }, }) fiber := New() fiber.Get("/", func(c Ctx) error { return errors.New("something happened") }) app.Use("/api", fiber) resp, err := app.Test(httptest.NewRequest(MethodGet, "/api", nil)) testErrorResponse(t, err, resp, "hi, i'm a custom error") } func Test_App_UseMountedErrorHandler(t *testing.T) { t.Parallel() app := New() fiber := New(Config{ ErrorHandler: func(c Ctx, err error) error { return c.Status(500).SendString("hi, i'm a custom error") }, }) fiber.Get("/", func(c Ctx) error { return errors.New("something happened") }) app.Use("/api", fiber) resp, err := app.Test(httptest.NewRequest(MethodGet, "/api", nil)) testErrorResponse(t, err, resp, "hi, i'm a custom error") } func Test_App_UseMountedErrorHandlerRootLevel(t *testing.T) { t.Parallel() app := New() fiber := New(Config{ ErrorHandler: func(c Ctx, err error) error { return c.Status(500).SendString("hi, i'm a custom error") }, }) fiber.Get("/api", func(c Ctx) error { return errors.New("something happened") }) app.Use("/", fiber) resp, err := app.Test(httptest.NewRequest(MethodGet, "/api", nil)) testErrorResponse(t, err, resp, "hi, i'm a custom error") } func Test_App_UseMountedErrorHandlerForBestPrefixMatch(t *testing.T) { t.Parallel() app := New() tsf := func(c Ctx, err error) error { return c.Status(200).SendString("hi, i'm a custom sub sub fiber error") } tripleSubFiber := New(Config{ ErrorHandler: tsf, }) tripleSubFiber.Get("/", func(c Ctx) error { return errors.New("something happened") }) sf := func(c Ctx, err error) error { return c.Status(200).SendString("hi, i'm a custom sub fiber error") } subfiber := New(Config{ ErrorHandler: sf, }) subfiber.Get("/", func(c Ctx) error { return errors.New("something happened") }) subfiber.Use("/third", tripleSubFiber) f := func(c Ctx, err error) error { return c.Status(200).SendString("hi, i'm a custom error") } fiber := New(Config{ ErrorHandler: f, }) fiber.Get("/", func(c Ctx) error { return errors.New("something happened") }) fiber.Use("/sub", subfiber) app.Use("/api", fiber) resp, err := app.Test(httptest.NewRequest(MethodGet, "/api/sub", nil)) require.Equal(t, nil, err, "/api/sub req") require.Equal(t, 200, resp.StatusCode, "Status code") b, err := io.ReadAll(resp.Body) require.Equal(t, nil, err, "iotuil.ReadAll()") require.Equal(t, "hi, i'm a custom sub fiber error", string(b), "Response body") resp2, err := app.Test(httptest.NewRequest(MethodGet, "/api/sub/third", nil)) require.Equal(t, nil, err, "/api/sub/third req") require.Equal(t, 200, resp.StatusCode, "Status code") b, err = io.ReadAll(resp2.Body) require.Equal(t, nil, err, "iotuil.ReadAll()") require.Equal(t, "hi, i'm a custom sub sub fiber error", string(b), "Third fiber Response body") } // go test -run Test_Ctx_Render_Mount func Test_Ctx_Render_Mount(t *testing.T) { t.Parallel() engine := &testTemplateEngine{} err := engine.Load() require.NoError(t, err) sub := New(Config{ Views: engine, }) sub.Get("/:name", func(c Ctx) error { return c.Render("hello_world.tmpl", Map{ "Name": c.Params("name"), }) }) app := New() app.Use("/hello", sub) resp, err := app.Test(httptest.NewRequest(MethodGet, "/hello/a", nil)) require.Equal(t, StatusOK, resp.StatusCode, "Status code") require.Equal(t, nil, err, "app.Test(req)") body, err := io.ReadAll(resp.Body) require.Equal(t, nil, err) require.Equal(t, "