-
Notifications
You must be signed in to change notification settings - Fork 298
/
fake.go
88 lines (73 loc) · 2.25 KB
/
fake.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
package httputil
import (
"bytes"
"io/ioutil"
"net/http"
)
// FakeTransport represents a fake http.Transport that returns prerecorded responses.
type FakeTransport struct {
responses map[string]*responseCollection
}
// NewFakeTransport creates a new FakeTransport instance without any responses.
func NewFakeTransport() *FakeTransport {
return &FakeTransport{
responses: make(map[string]*responseCollection),
}
}
func (ft *FakeTransport) responseCollection(url string) *responseCollection {
if _, ok := ft.responses[url]; !ok {
ft.responses[url] = &responseCollection{}
}
return ft.responses[url]
}
// AddResponse stores a fake HTTP response for the given URL.
func (ft *FakeTransport) AddResponse(url string, status int, body string, headers map[string]string) {
ft.responseCollection(url).Add(createResponse(status, body, headers), nil)
}
// AddResponse stores a error for the given URL.
func (ft *FakeTransport) AddError(url string, err error) {
ft.responseCollection(url).Add(nil, err)
}
// RoundTrip returns a prerecorded response to the given request, if one exists. Otherwise its response indicates 404 - not found.
func (ft *FakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if responses, ok := ft.responses[req.URL.String()]; ok {
return responses.Next()
}
return notFound(), nil
}
type responseCollection struct {
all []responseError
next int
}
func (rc *responseCollection) Add(resp *http.Response, err error) {
rc.all = append(rc.all, responseError{resp: resp, err: err})
}
func (rc *responseCollection) Next() (*http.Response, error) {
if rc.next >= len(rc.all) {
return notFound(), nil
}
rc.next++
next := rc.all[rc.next-1]
return next.resp, next.err
}
func createResponse(status int, body string, headers map[string]string) *http.Response {
return &http.Response{
StatusCode: status,
Body: ioutil.NopCloser(bytes.NewBufferString(body)),
Header: transformHeaders(headers),
}
}
func transformHeaders(original map[string]string) http.Header {
result := make(map[string][]string)
for k, v := range original {
result[k] = []string{v}
}
return result
}
func notFound() *http.Response {
return createResponse(http.StatusNotFound, "", nil)
}
type responseError struct {
resp *http.Response
err error
}