-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathfiber_v3_test.go
More file actions
282 lines (245 loc) · 7 KB
/
fiber_v3_test.go
File metadata and controls
282 lines (245 loc) · 7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
package evo
import (
"io"
"net/http/httptest"
"strings"
"testing"
"github.com/gofiber/fiber/v3"
fstatic "github.com/gofiber/fiber/v3/middleware/static"
)
// newTestApp creates a bare Fiber v3 app and sets the package-level app variable
// so evo routing helpers (Get, Post, Redirect, etc.) can be called in tests.
func newTestApp() *fiber.App {
a := fiber.New(fiber.Config{})
app = a
return a
}
// TestFiberCtxIsInterface verifies that fiber.Ctx is now an interface and that
// our Upgrade() wrapper correctly wraps it into a *Request.
func TestFiberCtxIsInterface(t *testing.T) {
a := newTestApp()
a.Get("/hello", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
if r == nil {
t.Error("Upgrade returned nil")
}
if r.Context == nil {
t.Error("Request.Context is nil")
}
return ctx.SendString("ok")
})
req := httptest.NewRequest("GET", "/hello", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Errorf("expected 200, got %d", resp.StatusCode)
}
}
// TestRouteParams verifies that the AllParams replacement (Route().Params + Params(key))
// correctly returns all route parameters.
func TestRouteParams(t *testing.T) {
a := newTestApp()
a.Get("/user/:id/order/:orderId", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
params := r.Params()
if params["id"] != "42" {
t.Errorf("expected id=42, got %q", params["id"])
}
if params["orderId"] != "99" {
t.Errorf("expected orderId=99, got %q", params["orderId"])
}
return ctx.SendString("ok")
})
req := httptest.NewRequest("GET", "/user/42/order/99", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Errorf("expected 200, got %d", resp.StatusCode)
}
}
// TestRouteParamsEmpty verifies that Params() returns an empty map when there are no route params.
func TestRouteParamsEmpty(t *testing.T) {
a := newTestApp()
a.Get("/no-params", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
params := r.Params()
if len(params) != 0 {
t.Errorf("expected empty params map, got %v", params)
}
return ctx.SendString("ok")
})
req := httptest.NewRequest("GET", "/no-params", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Errorf("expected 200, got %d", resp.StatusCode)
}
}
// TestRedirectWithStatus verifies ctx.Redirect().Status(code).To(url) behavior.
func TestRedirectWithStatus(t *testing.T) {
a := newTestApp()
a.Get("/old", func(ctx fiber.Ctx) error {
return ctx.Redirect().Status(301).To("/new")
})
req := httptest.NewRequest("GET", "/old", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 301 {
t.Errorf("expected 301, got %d", resp.StatusCode)
}
if loc := resp.Header.Get("Location"); loc != "/new" {
t.Errorf("expected Location=/new, got %q", loc)
}
}
// TestRedirectDefault verifies redirect without explicit status uses 303 (Fiber v3 default).
func TestRedirectDefault(t *testing.T) {
a := newTestApp()
a.Get("/move", func(ctx fiber.Ctx) error {
return ctx.Redirect().To("/dest")
})
req := httptest.NewRequest("GET", "/move", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
// Fiber v3 changed the default redirect code from 302 to 303 See Other.
if resp.StatusCode != 303 {
t.Errorf("expected 303 (fiber v3 default), got %d", resp.StatusCode)
}
}
// TestRequestRedirect verifies the Request.Redirect wrapper.
func TestRequestRedirect(t *testing.T) {
a := newTestApp()
a.Get("/r1", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
return r.Redirect("/target", 303)
})
a.Get("/r2", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
return r.Redirect("/target2")
})
for _, tc := range []struct {
path string
code int
loc string
}{
{"/r1", 303, "/target"},
{"/r2", 303, "/target2"}, // Fiber v3 default is 303
} {
req := httptest.NewRequest("GET", tc.path, nil)
resp, err := a.Test(req)
if err != nil {
t.Fatalf("%s: %v", tc.path, err)
}
if resp.StatusCode != tc.code {
t.Errorf("%s: expected %d, got %d", tc.path, tc.code, resp.StatusCode)
}
if loc := resp.Header.Get("Location"); loc != tc.loc {
t.Errorf("%s: expected Location=%q, got %q", tc.path, tc.loc, loc)
}
}
}
// TestLocals verifies Locals() still works with fiber.Ctx as interface.
func TestLocals(t *testing.T) {
a := newTestApp()
a.Use(func(ctx fiber.Ctx) error {
ctx.Locals("user", "alice")
return ctx.Next()
})
a.Get("/locals", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
v := r.Var("user")
return ctx.SendString(v.String())
})
req := httptest.NewRequest("GET", "/locals", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
if string(body) != "alice" {
t.Errorf("expected 'alice', got %q", string(body))
}
}
// TestHandleHelpers verifies the package-level evo routing helpers wrap fiber.Ctx correctly.
func TestHandleHelpers(t *testing.T) {
a := newTestApp()
Get("/ping", func(req *Request) any {
return "pong"
})
req := httptest.NewRequest("GET", "/ping", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
// The handler returns "pong" → WriteResponse encodes it as JSON {"success":true,"data":"pong"}
if !strings.Contains(string(body), "pong") {
t.Errorf("expected body to contain 'pong', got %q", string(body))
}
}
// TestSendStatus verifies SendStatus still works after removing *fiber.Ctx.
func TestSendStatus(t *testing.T) {
a := newTestApp()
a.Get("/teapot", func(ctx fiber.Ctx) error {
return ctx.SendStatus(418)
})
req := httptest.NewRequest("GET", "/teapot", nil)
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 418 {
t.Errorf("expected 418, got %d", resp.StatusCode)
}
}
// TestStaticMiddleware verifies static.New() is used correctly (no panic, correct middleware chain).
func TestStaticMiddleware(t *testing.T) {
a := newTestApp()
// Just verify it registers without panic; actual file serving needs real files.
_ = a.Use("/static", fstatic.New(".", fstatic.Config{}))
}
// TestRequestHeaders verifies header access via the Request wrapper.
func TestRequestHeaders(t *testing.T) {
a := newTestApp()
a.Get("/hdr", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
v := r.Header("X-Custom")
return ctx.SendString(v)
})
req := httptest.NewRequest("GET", "/hdr", nil)
req.Header.Set("X-Custom", "hello")
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
if string(body) != "hello" {
t.Errorf("expected 'hello', got %q", string(body))
}
}
// TestRequestBody verifies Body() reads the request body correctly.
func TestRequestBody(t *testing.T) {
a := newTestApp()
a.Post("/body", func(ctx fiber.Ctx) error {
r := Upgrade(ctx)
return ctx.SendString(r.Body())
})
req := httptest.NewRequest("POST", "/body", strings.NewReader("hello body"))
resp, err := a.Test(req)
if err != nil {
t.Fatal(err)
}
body, _ := io.ReadAll(resp.Body)
if string(body) != "hello body" {
t.Errorf("expected 'hello body', got %q", string(body))
}
}