-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandler_test.go
More file actions
250 lines (197 loc) · 6.21 KB
/
handler_test.go
File metadata and controls
250 lines (197 loc) · 6.21 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
package hx
import (
"context"
"encoding/json"
"encoding/xml"
"errors"
"net/http"
"net/http/httptest"
"testing"
"github.com/eatmoreapple/hx/httpx"
)
func TestWarp(t *testing.T) {
handler := Warp(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("ok"))
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
if err := handler(w, req); err != nil {
t.Errorf("expected no error, got %v", err)
}
if w.Code != http.StatusOK {
t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code)
}
if w.Body.String() != "ok" {
t.Errorf("expected body %s, got %s", "ok", w.Body.String())
}
}
func TestGeneric(t *testing.T) {
type Request struct {
Name string
}
type Response struct {
Message string
}
handler := Generic[Request, Response](func(ctx context.Context, req Request) (Response, error) {
return Response{Message: "Hello " + req.Name}, nil
})
// Since Generic returns a TypedHandlerFunc, we can't directly call it as http.HandlerFunc
// We need to verify it returns the correct function type
if handler == nil {
t.Error("expected handler to be not nil")
}
}
func TestRender(t *testing.T) {
type Request struct {
Name string `json:"name"`
}
handler := Render[Request](func(ctx context.Context, req Request) (httpx.ResponseRender, error) {
return httpx.JSONResponse{Data: map[string]string{"message": "Hello " + req.Name}}, nil
})
// Create a request with JSON body
req := httptest.NewRequest(http.MethodPost, "/", nil)
// Mock binding by manually setting the request context or just testing the handler logic if possible.
// However, Render uses internal requestHandler which uses ShouldBind.
// We need to provide a body for binding.
// For simplicity, let's assume query binding for GET or body for POST.
// Since we haven't implemented the full test suite for binding yet, we might face issues if binding fails.
// But Render creates a HandlerFunc that does binding.
// Let's try with a simple struct that doesn't require complex binding first, or just empty.
w := httptest.NewRecorder()
if err := handler(w, req); err != nil {
t.Errorf("expected no error, got %v", err)
}
}
func TestJSON(t *testing.T) {
type Request struct{}
type Response struct {
Message string `json:"message"`
}
handler := G(func(ctx context.Context, req Request) (Response, error) {
return Response{Message: "hello"}, nil
}).JSON()
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
if err := handler(w, req); err != nil {
t.Errorf("expected no error, got %v", err)
}
if w.Code != http.StatusOK {
t.Errorf("expected status code %d, got %d", http.StatusOK, w.Code)
}
var resp Response
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Errorf("failed to unmarshal response: %v", err)
}
if resp.Message != "hello" {
t.Errorf("expected message %s, got %s", "hello", resp.Message)
}
}
func TestString(t *testing.T) {
type Request struct{}
handler := G(func(ctx context.Context, req Request) (string, error) {
return "hello", nil
}).String()
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
if err := handler(w, req); err != nil {
t.Errorf("expected no error, got %v", err)
}
if w.Body.String() != "hello" {
t.Errorf("expected body %s, got %s", "hello", w.Body.String())
}
}
func TestStringPanic(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Error("expected panic but got nil")
}
}()
type Request struct{}
type Response struct{}
G(func(ctx context.Context, req Request) (Response, error) {
return Response{}, nil
}).String()
}
func TestXML(t *testing.T) {
type Request struct{}
type Response struct {
XMLName xml.Name `xml:"response"`
Message string `xml:"message"`
}
handler := G(func(ctx context.Context, req Request) (Response, error) {
return Response{Message: "hello"}, nil
}).XML()
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
if err := handler(w, req); err != nil {
t.Errorf("expected no error, got %v", err)
}
var resp Response
if err := xml.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Errorf("failed to unmarshal response: %v", err)
}
if resp.Message != "hello" {
t.Errorf("expected message %s, got %s", "hello", resp.Message)
}
}
func TestPipe(t *testing.T) {
type Request struct{}
type Response struct{}
var steps []string
middleware1 := func(ctx context.Context, req Request) error {
steps = append(steps, "m1")
return nil
}
middleware2 := func(ctx context.Context, req Request) error {
steps = append(steps, "m2")
return nil
}
handler := G(func(ctx context.Context, req Request) (Response, error) {
steps = append(steps, "handler")
return Response{}, nil
}).Pipe(middleware1, middleware2)
// Pipe returns TypedHandlerFunc, we need to convert it to HandlerFunc to execute or just call it directly if we could.
// But TypedHandlerFunc is a function type, so we can call it.
_, err := handler(context.Background(), Request{})
if err != nil {
t.Errorf("expected no error, got %v", err)
}
expected := []string{"m1", "m2", "handler"}
if len(steps) != len(expected) {
t.Errorf("expected %d steps, got %d", len(expected), len(steps))
}
for i, step := range steps {
if step != expected[i] {
t.Errorf("expected step %d to be %s, got %s", i, expected[i], step)
}
}
}
func TestPipeError(t *testing.T) {
type Request struct{}
type Response struct{}
expectedErr := errors.New("middleware error")
middleware := func(ctx context.Context, req Request) error {
return expectedErr
}
handler := G(func(ctx context.Context, req Request) (Response, error) {
return Response{}, nil
}).Pipe(middleware)
_, err := handler(context.Background(), Request{})
if err != expectedErr {
t.Errorf("expected error %v, got %v", expectedErr, err)
}
}
func TestE(t *testing.T) {
handler := E(func(ctx context.Context) (string, error) {
return "ok", nil
}).String()
req := httptest.NewRequest(http.MethodGet, "/", nil)
w := httptest.NewRecorder()
if err := handler(w, req); err != nil {
t.Errorf("expected no error, got %v", err)
}
if w.Body.String() != "ok" {
t.Errorf("expected body %s, got %s", "ok", w.Body.String())
}
}