forked from dimfeld/httptreemux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
group_test.go
182 lines (160 loc) · 4.91 KB
/
group_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
package httptreemux
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestEmptyGroupAndMapping(t *testing.T) {
defer func() {
if err := recover(); err != nil {
//everything is good, it paniced
} else {
t.Error(`Expected NewGroup("")`)
}
}()
New().GET("", func(w http.ResponseWriter, _ *http.Request, _ map[string]string) {})
}
func TestSubGroupSlashMapping(t *testing.T) {
r := New()
r.NewGroup("/foo").GET("/", func(w http.ResponseWriter, _ *http.Request, _ map[string]string) {
w.WriteHeader(200)
})
var req *http.Request
var recorder *httptest.ResponseRecorder
req, _ = http.NewRequest("GET", "/foo", nil)
recorder = httptest.NewRecorder()
r.ServeHTTP(recorder, req)
if recorder.Code != 301 { //should get redirected
t.Error(`/foo on NewGroup("/foo").GET("/") should result in 301 response, got:`, recorder.Code)
}
req, _ = http.NewRequest("GET", "/foo/", nil)
recorder = httptest.NewRecorder()
r.ServeHTTP(recorder, req)
if recorder.Code != 200 {
t.Error(`/foo/ on NewGroup("/foo").GET("/"") should result in 200 response, got:`, recorder.Code)
}
}
func TestSubGroupEmptyMapping(t *testing.T) {
r := New()
r.NewGroup("/foo").GET("", func(w http.ResponseWriter, _ *http.Request, _ map[string]string) {
w.WriteHeader(200)
})
req, _ := http.NewRequest("GET", "/foo", nil)
recorder := httptest.NewRecorder()
r.ServeHTTP(recorder, req)
if recorder.Code != 200 {
t.Error(`/foo on NewGroup("/foo").GET("") should result in 200 response, got:`, recorder.Code)
}
}
func TestGroupCaseInsensitiveRouting(t *testing.T) {
r := New()
r.CaseInsensitive = true
r.NewGroup("/MY-path").GET("", func(w http.ResponseWriter, _ *http.Request, _ map[string]string) {
w.WriteHeader(200)
})
req, _ := http.NewRequest("GET", "/MY-PATH", nil)
recorder := httptest.NewRecorder()
r.ServeHTTP(recorder, req)
if recorder.Code != http.StatusOK {
t.Errorf("expected 200 response for case-insensitive request. Received: %d", recorder.Code)
}
}
func TestGroupMethods(t *testing.T) {
for _, scenario := range scenarios {
t.Log(scenario.description)
testGroupMethods(t, scenario.RequestCreator, false)
testGroupMethods(t, scenario.RequestCreator, true)
}
}
func TestInvalidHandle(t *testing.T) {
defer func() {
if err := recover(); err == nil {
t.Error("Bad handle path should have caused a panic")
}
}()
New().NewGroup("/foo").GET("bar", nil)
}
func TestInvalidSubPath(t *testing.T) {
defer func() {
if err := recover(); err == nil {
t.Error("Bad sub-path should have caused a panic")
}
}()
New().NewGroup("/foo").NewGroup("bar")
}
func TestInvalidPath(t *testing.T) {
defer func() {
if err := recover(); err == nil {
t.Error("Bad path should have caused a panic")
}
}()
New().NewGroup("foo")
}
//Liberally borrowed from router_test
func testGroupMethods(t *testing.T, reqGen RequestCreator, headCanUseGet bool) {
var result string
makeHandler := func(method string) HandlerFunc {
return func(w http.ResponseWriter, r *http.Request, params map[string]string) {
result = method
}
}
router := New()
router.HeadCanUseGet = headCanUseGet
// Testing with a sub-group of a group as that will test everything at once
g := router.NewGroup("/base").NewGroup("/user")
g.GET("/:param", makeHandler("GET"))
g.POST("/:param", makeHandler("POST"))
g.PATCH("/:param", makeHandler("PATCH"))
g.PUT("/:param", makeHandler("PUT"))
g.DELETE("/:param", makeHandler("DELETE"))
testMethod := func(method, expect string) {
result = ""
w := httptest.NewRecorder()
r, _ := reqGen(method, "/base/user/"+method, nil)
router.ServeHTTP(w, r)
if expect == "" && w.Code != http.StatusMethodNotAllowed {
t.Errorf("Method %s not expected to match but saw code %d", method, w.Code)
}
if result != expect {
t.Errorf("Method %s got result %s", method, result)
}
}
testMethod("GET", "GET")
testMethod("POST", "POST")
testMethod("PATCH", "PATCH")
testMethod("PUT", "PUT")
testMethod("DELETE", "DELETE")
if headCanUseGet {
t.Log("Test implicit HEAD with HeadCanUseGet = true")
testMethod("HEAD", "GET")
} else {
t.Log("Test implicit HEAD with HeadCanUseGet = false")
testMethod("HEAD", "")
}
router.HEAD("/base/user/:param", makeHandler("HEAD"))
testMethod("HEAD", "HEAD")
}
// Ensure that setting a GET handler doesn't overwrite an explciit HEAD handler.
func TestSetGetAfterHead(t *testing.T) {
var result string
makeHandler := func(method string) HandlerFunc {
return func(w http.ResponseWriter, r *http.Request, params map[string]string) {
result = method
}
}
router := New()
router.HeadCanUseGet = true
router.HEAD("/abc", makeHandler("HEAD"))
router.GET("/abc", makeHandler("GET"))
testMethod := func(method, expect string) {
result = ""
w := httptest.NewRecorder()
r, _ := http.NewRequest(method, "/abc", nil)
router.ServeHTTP(w, r)
if result != expect {
t.Errorf("Method %s got result %s", method, result)
}
}
testMethod("HEAD", "HEAD")
testMethod("GET", "GET")
}