-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware_test.go
209 lines (179 loc) · 6.54 KB
/
middleware_test.go
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
package requests
import (
"bytes"
"context"
"net/http"
"net/http/httptest"
"testing"
)
// TestMiddleware ensures that the Middleware correctly applies
// middleware to outgoing requests.
func TestMiddleware(t *testing.T) {
// Set up a mock server to inspect incoming requests
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Check for the custom header added by our middleware
if r.Header.Get("X-Custom-Header") != "true" {
t.Errorf("Expected custom header 'X-Custom-Header' to be 'true', got '%s'", r.Header.Get("X-Custom-Header"))
w.WriteHeader(http.StatusBadRequest) // Indicate a bad request if header is missing
return
}
w.WriteHeader(http.StatusOK) // All good if the header is present
}))
defer mockServer.Close()
// Define the middleware that adds a custom header
customHeaderMiddleware := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
// Add the custom header
req.Header.Set("X-Custom-Header", "true")
// Proceed with the next middleware or the actual request
return next(req)
}
}
// Initialize the client with our custom middleware
client := Create(&Config{
BaseURL: mockServer.URL, // Use our mock server as the base URL
Transport: http.DefaultTransport, // Use the default transport
Middlewares: []Middleware{customHeaderMiddleware}, // Apply our custom header middleware
})
// Create an HTTP request object
resp, err := client.Get("/").Send(context.Background())
if err != nil {
t.Fatalf("Failed to send request: %v", err)
}
defer resp.Close() //nolint: errcheck
// Check if the server responded with a 200 OK, indicating the middleware applied the header successfully
if resp.StatusCode() != http.StatusOK {
t.Errorf("Expected status code 200, got %d", resp.StatusCode())
}
}
func TestNestedMiddleware(t *testing.T) {
var buf bytes.Buffer
mid0 := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
buf.WriteString("0>>")
resp, err := next(req)
buf.WriteString(">>0")
return resp, err
}
}
mid1 := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
buf.WriteString("1>>")
resp, err := next(req)
buf.WriteString(">>1")
return resp, err
}
}
mid2 := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
buf.WriteString("2>>")
resp, err := next(req)
buf.WriteString(">>2")
return resp, err
}
}
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
buf.WriteString("(served)")
w.WriteHeader(http.StatusOK)
}))
defer mockServer.Close()
client := Create(&Config{
BaseURL: mockServer.URL,
Middlewares: []Middleware{mid0, mid1, mid2},
})
// Create an HTTP request object
resp, err := client.Get("/").Send(context.Background())
if err != nil {
t.Fatalf("Failed to send request: %v", err)
}
defer resp.Close() //nolint: errcheck
expected := "0>>1>>2>>(served)>>2>>1>>0"
if buf.String() != expected {
t.Errorf("Expected sequence %s, got %s", expected, buf.String())
}
}
// TestDynamicMiddlewareAddition tests the dynamic addition of middleware to the client
func TestDynamicMiddlewareAddition(t *testing.T) {
// Buffer to track middleware execution order
var executionOrder bytes.Buffer
// Define middleware functions
loggingMiddleware := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
executionOrder.WriteString("Logging>")
return next(req)
}
}
authenticationMiddleware := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
executionOrder.WriteString("Auth>")
return next(req)
}
}
// Set up a mock server
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
executionOrder.WriteString("Handler")
w.WriteHeader(http.StatusOK)
}))
defer mockServer.Close()
// Create a new client
client := Create(&Config{
BaseURL: mockServer.URL,
})
// Dynamically add middleware
client.AddMiddleware(loggingMiddleware)
client.AddMiddleware(authenticationMiddleware)
// Make a request to the mock server
_, err := client.Get("/").Send(context.Background())
if err != nil {
t.Fatalf("Failed to send request: %v", err)
}
// Check the order of middleware execution
expectedOrder := "Logging>Auth>Handler"
if executionOrder.String() != expectedOrder {
t.Errorf("Middleware executed in incorrect order. Expected %s, got %s", expectedOrder, executionOrder.String())
}
}
// TestRequestMiddlewareAddition tests the addition of middleware at the request level,
// and ensures that both client and request level middlewares are executed in the correct order.
func TestRequestMiddlewareAddition(t *testing.T) {
// Buffer to track middleware execution order
var executionOrder bytes.Buffer
// Define client-level middleware
clientLoggingMiddleware := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
executionOrder.WriteString("ClientLogging>")
return next(req)
}
}
// Define request-level middleware
requestAuthMiddleware := func(next MiddlewareHandlerFunc) MiddlewareHandlerFunc {
return func(req *http.Request) (*http.Response, error) {
executionOrder.WriteString("RequestAuth>")
return next(req)
}
}
// Set up a mock server
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
executionOrder.WriteString("Handler")
w.WriteHeader(http.StatusOK)
}))
defer mockServer.Close()
// Create a new client with client-level middleware
client := Create(&Config{
BaseURL: mockServer.URL,
Middlewares: []Middleware{clientLoggingMiddleware}, // Apply client-level middleware
})
// Create a request and dynamically add request-level middleware
reqBuilder := client.Get("/")
reqBuilder.AddMiddleware(requestAuthMiddleware) // Apply request-level middleware
// Make a request to the mock server
_, err := reqBuilder.Send(context.Background())
if err != nil {
t.Fatalf("Failed to send request: %v", err)
}
// Check the order of middleware execution
expectedOrder := "ClientLogging>RequestAuth>Handler"
if executionOrder.String() != expectedOrder {
t.Errorf("Middleware executed in incorrect order. Expected %s, got %s", expectedOrder, executionOrder.String())
}
}