forked from ivpusic/httpcheck
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathchecker.go
158 lines (135 loc) · 3.78 KB
/
checker.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
package httpcheck
import (
"net/http"
"net/http/cookiejar"
"net/http/httptest"
"strings"
"time"
"github.com/stretchr/testify/require"
)
const (
// DefaultClientTimeout is the default timeout for requests made by checker.
DefaultClientTimeout = 5 * time.Second
)
// Option represents the option for the checker.
type Option func(*Checker)
// ClientTimeout sets the client timeout.
func ClientTimeout(d time.Duration) Option {
return func(c *Checker) {
c.client.Timeout = d
}
}
// CheckRedirect sets the policy of redirection to the HTTP client.
func CheckRedirect(policy func(req *http.Request, via []*http.Request) error) Option {
return func(c *Checker) {
c.client.CheckRedirect = policy
}
}
func Debug() Option {
return func(c *Checker) {
c.debug = true
}
}
// NoRedirect is the alias of the following:
//
// CheckRedirect(func(req *http.Request, via []*http.Request) error {
// return http.ErrUseLastResponse
// })
//
// Client returns ErrUseLastResponse, the next request is not sent and the most recent
// response is returned with its body unclosed.
func NoRedirect() Option {
return CheckRedirect(func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
})
}
// Checker represents the HTTP checker without TestingT.
type Checker struct {
client *http.Client
request *http.Request
response *http.Response
pcookies map[string]bool
// Set external to true if testing an external server.
// In this case, handler and server are undefined.
external bool
url string
server *httptest.Server
handler http.Handler
// debug mode
debug bool
}
// New creates an HTTP Checker for testing with the given handler.
func New(h http.Handler, options ...Option) *Checker {
jar, _ := cookiejar.New(nil)
ret := &Checker{
client: &http.Client{
Timeout: DefaultClientTimeout,
Jar: jar,
},
pcookies: map[string]bool{},
server: createServer(h),
handler: h,
}
for _, v := range options {
v(ret)
}
return ret
}
// NewExternal creates an HTTP Checker for testing an external server specified by url.
func NewExternal(url string, options ...Option) *Checker {
jar, _ := cookiejar.New(nil)
ret := &Checker{
client: &http.Client{
Timeout: DefaultClientTimeout,
Jar: jar,
},
pcookies: map[string]bool{},
external: true,
url: url,
}
for _, v := range options {
v(ret)
}
return ret
}
func createServer(handler http.Handler) *httptest.Server {
return httptest.NewUnstartedServer(handler)
}
// PersistCookie - enables a cookie to be preserved between requests
func (c *Checker) PersistCookie(cookie string) {
c.pcookies[cookie] = true
}
// UnpersistCookie - the specified cookie will not be preserved during requests anymore
func (c *Checker) UnpersistCookie(cookie string) {
delete(c.pcookies, cookie)
}
// make request /////////////////////////////////////////////////
// TestRequest - If you want to provide you custom http.Request instance, you can do it using this method
// In this case internal http.Request instance won't be created, and passed instance will be used
// for making request
func (c *Checker) TestRequest(t TestingT, request *http.Request) *Tester {
require.NotNil(t, request, "request is nil")
c.request = request
return &Tester{
t: t,
Checker: c,
}
}
// Test - Prepare for testing some part of code which lives on provided path and method.
func (c *Checker) Test(t TestingT, method, path string) *Tester {
method = strings.ToUpper(method)
request, err := http.NewRequest(method, c.GetURL()+path, nil)
require.NoError(t, err, "failed to make new request")
c.request = request
return &Tester{
t: t,
Checker: c,
}
}
// GetURL returns the server URL.
func (c *Checker) GetURL() string {
if c.external {
return c.url
}
return "http://" + c.server.Listener.Addr().String()
}