-
Notifications
You must be signed in to change notification settings - Fork 1
/
http_context.go
137 lines (114 loc) · 4.06 KB
/
http_context.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
package mt
import (
"errors"
"fmt"
"log"
"net/http"
"net/url"
"strings"
)
// An HTTPTestContext is used to create HTTP test cases that target either
// a specific base URL or a Go HTTP handler.
type HTTPTestContext struct {
BaseURL string
Client *http.Client
Handler http.Handler
}
// DefaultContext returns an HTTPTestContext using the default HTTP client.
func DefaultContext() *HTTPTestContext {
return &HTTPTestContext{}
}
// NewURLContext creates a new HTTPTestContext for creating tests that target
// the specified base URL.
func NewURLContext(baseURL string) *HTTPTestContext {
return &HTTPTestContext{
BaseURL: baseURL,
}
}
// NewHandlerContext creates a new HTTPTestContext for creating tests that target
// the specified HTTP handler.
func NewHandlerContext(handler http.Handler) *HTTPTestContext {
return &HTTPTestContext{
Handler: handler,
}
}
// WithHTTPClient sets the HTTP client used for HTTP requests and returns the
// context.
func (c *HTTPTestContext) WithHTTPClient(client *http.Client) *HTTPTestContext {
c.Client = client
return c
}
// DELETE is a shortcut for NewTestCase(http.MethodDelete, path).
func (c *HTTPTestContext) DELETE(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodDelete, path, description...)
}
// HEAD is a shortcut for NewTestCase(http.MethodHead, path, description...).
func (c *HTTPTestContext) HEAD(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodHead, path, description...)
}
// GET is a shortcut for NewTestCase(http.MethodGet, path, description...).
func (c *HTTPTestContext) GET(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodGet, path, description...)
}
// OPTIONS is a shortcut for NewTestCase(http.MethodOptions, path, description...).
func (c *HTTPTestContext) OPTIONS(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodOptions, path, description...)
}
// PATCH is a shortcut for NewTestCase(http.MethodPatch, path, description...).
func (c *HTTPTestContext) PATCH(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodPatch, path, description...)
}
// POST is a shortcut for NewTestCase(http.MethodPost, path, description...).
func (c *HTTPTestContext) POST(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodPost, path, description...)
}
// PUT is a shortcut for NewTestCase(http.MethodPut, path, description...).
func (c *HTTPTestContext) PUT(path string, description ...string) *HTTPTestCase {
return c.newHTTPTestCase(http.MethodPut, path, description...)
}
// DO creates a test case from a custom HTTP request.
func (c *HTTPTestContext) DO(request *http.Request, description ...string) *HTTPTestCase {
tc := c.newHTTPTestCase(request.Method, request.URL.Path, description...)
tc.request = request
return tc
}
func (c *HTTPTestContext) createURL(path string) (*url.URL, error) {
if path == "" {
return nil, errors.New("not enough URL information")
}
// when using the default context, the path must be a complete URL.
if c.BaseURL == "" {
u, err := url.ParseRequestURI(path)
if err != nil {
return nil, fmt.Errorf("invalid URL %q: %s", path, err)
}
return u, nil
}
base, err := url.ParseRequestURI(c.BaseURL)
if err != nil {
return nil, fmt.Errorf("invalid base URL %q: %s", c.BaseURL, err)
}
endpoint, err := url.ParseRequestURI(path)
if err != nil {
return nil, fmt.Errorf("invalid path %q: %s", path, err)
}
return base.ResolveReference(endpoint), nil
}
func (c *HTTPTestContext) newHTTPTestCase(method, path string, description ...string) *HTTPTestCase {
u, err := c.createURL(path)
if err != nil {
log.Fatalf("failed to create URL for path %q: %v", path, err)
}
req, cancel, err := createRequest(method, u.String())
if err != nil {
log.Fatalf("failed to create request %v", err)
}
return &HTTPTestCase{
Desc: strings.Join(description, " "),
tctx: c,
pathParams: parameters{},
queryParams: parameters{},
request: req,
cancel: cancel,
}
}