10
gc "gopkg.in/check.v1"
12
"gopkg.in/goose.v1/testing/httpsuite"
15
func Test(t *testing.T) {
19
type LoopingHTTPSuite struct {
23
func (s *LoopingHTTPSuite) setupLoopbackRequest() (*http.Header, chan string, *Client) {
24
var headers http.Header
25
bodyChan := make(chan string, 1)
26
handler := func(resp http.ResponseWriter, req *http.Request) {
28
bodyBytes, _ := ioutil.ReadAll(req.Body)
30
bodyChan <- string(bodyBytes)
31
resp.Header().Add("Content-Length", "0")
32
resp.Header().Add("Testing", "true")
33
resp.WriteHeader(http.StatusNoContent)
36
s.Mux.HandleFunc("/", handler)
38
return &headers, bodyChan, client
41
type HTTPClientTestSuite struct {
45
type HTTPSClientTestSuite struct {
49
var _ = gc.Suite(&HTTPClientTestSuite{})
50
var _ = gc.Suite(&HTTPSClientTestSuite{LoopingHTTPSuite{httpsuite.HTTPSuite{UseTLS: true}}})
52
func (s *HTTPClientTestSuite) assertHeaderValues(c *gc.C, token string) {
53
emptyHeaders := http.Header{}
54
headers := createHeaders(emptyHeaders, "content-type", token)
55
contentTypes := []string{"content-type"}
56
headerData := map[string][]string{
57
"Content-Type": contentTypes, "Accept": contentTypes, "User-Agent": {gooseAgent()}}
59
headerData["X-Auth-Token"] = []string{token}
61
expectedHeaders := http.Header(headerData)
62
c.Assert(headers, gc.DeepEquals, expectedHeaders)
63
c.Assert(emptyHeaders, gc.DeepEquals, http.Header{})
66
func (s *HTTPClientTestSuite) TestCreateHeadersNoToken(c *gc.C) {
67
s.assertHeaderValues(c, "")
70
func (s *HTTPClientTestSuite) TestCreateHeadersWithToken(c *gc.C) {
71
s.assertHeaderValues(c, "token")
74
func (s *HTTPClientTestSuite) TestCreateHeadersCopiesSupplied(c *gc.C) {
75
initialHeaders := make(http.Header)
76
initialHeaders["Foo"] = []string{"Bar"}
77
contentType := contentTypeJSON
78
contentTypes := []string{contentType}
79
headers := createHeaders(initialHeaders, contentType, "")
80
// it should not change the headers passed in
81
c.Assert(initialHeaders, gc.DeepEquals, http.Header{"Foo": []string{"Bar"}})
82
// The initial headers should be in the output
83
c.Assert(headers, gc.DeepEquals,
84
http.Header{"Foo": []string{"Bar"}, "Content-Type": contentTypes, "Accept": contentTypes, "User-Agent": []string{gooseAgent()}})
87
func (s *HTTPClientTestSuite) TestBinaryRequestSetsUserAgent(c *gc.C) {
88
headers, _, client := s.setupLoopbackRequest()
89
req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
90
err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)
91
c.Assert(err, gc.IsNil)
92
agent := headers.Get("User-Agent")
93
c.Check(agent, gc.Not(gc.Equals), "")
94
c.Check(agent, gc.Equals, gooseAgent())
95
c.Check(req.RespHeaders.Get("Testing"), gc.Equals, "true")
98
func (s *HTTPClientTestSuite) TestJSONRequestSetsUserAgent(c *gc.C) {
99
headers, _, client := s.setupLoopbackRequest()
100
req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
101
err := client.JsonRequest("POST", s.Server.URL, "", req, nil)
102
c.Assert(err, gc.IsNil)
103
agent := headers.Get("User-Agent")
104
c.Check(agent, gc.Not(gc.Equals), "")
105
c.Check(agent, gc.Equals, gooseAgent())
106
c.Check(req.RespHeaders.Get("Testing"), gc.Equals, "true")
109
func (s *HTTPClientTestSuite) TestBinaryRequestSetsContentLength(c *gc.C) {
110
headers, bodyChan, client := s.setupLoopbackRequest()
111
content := "binary\ncontent\n"
113
ExpectedStatus: []int{http.StatusNoContent},
114
ReqReader: bytes.NewBufferString(content),
115
ReqLength: len(content),
117
err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)
118
c.Assert(err, gc.IsNil)
119
encoding := headers.Get("Transfer-Encoding")
120
c.Check(encoding, gc.Equals, "")
121
length := headers.Get("Content-Length")
122
c.Check(length, gc.Equals, fmt.Sprintf("%d", len(content)))
123
body, ok := <-bodyChan
124
c.Assert(ok, gc.Equals, true)
125
c.Check(body, gc.Equals, content)
128
func (s *HTTPClientTestSuite) TestJSONRequestSetsContentLength(c *gc.C) {
129
headers, bodyChan, client := s.setupLoopbackRequest()
130
reqMap := map[string]string{"key": "value"}
132
ExpectedStatus: []int{http.StatusNoContent},
135
err := client.JsonRequest("POST", s.Server.URL, "", req, nil)
136
c.Assert(err, gc.IsNil)
137
encoding := headers.Get("Transfer-Encoding")
138
c.Check(encoding, gc.Equals, "")
139
length := headers.Get("Content-Length")
140
body, ok := <-bodyChan
141
c.Assert(ok, gc.Equals, true)
142
c.Check(body, gc.Not(gc.Equals), "")
143
c.Check(length, gc.Equals, fmt.Sprintf("%d", len(body)))
146
func (s *HTTPClientTestSuite) TestBinaryRequestSetsToken(c *gc.C) {
147
headers, _, client := s.setupLoopbackRequest()
148
req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
149
err := client.BinaryRequest("POST", s.Server.URL, "token", req, nil)
150
c.Assert(err, gc.IsNil)
151
agent := headers.Get("X-Auth-Token")
152
c.Check(agent, gc.Equals, "token")
155
func (s *HTTPClientTestSuite) TestJSONRequestSetsToken(c *gc.C) {
156
headers, _, client := s.setupLoopbackRequest()
157
req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
158
err := client.JsonRequest("POST", s.Server.URL, "token", req, nil)
159
c.Assert(err, gc.IsNil)
160
agent := headers.Get("X-Auth-Token")
161
c.Check(agent, gc.Equals, "token")
164
func (s *HTTPClientTestSuite) TestHttpTransport(c *gc.C) {
165
transport := http.DefaultTransport.(*http.Transport)
166
c.Assert(transport.DisableKeepAlives, gc.Equals, true)
169
func (s *HTTPSClientTestSuite) TestDefaultClientRejectSelfSigned(c *gc.C) {
170
_, _, client := s.setupLoopbackRequest()
171
req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
172
err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)
173
c.Assert(err, gc.NotNil)
174
c.Check(err, gc.ErrorMatches, "(.|\\n)*x509: certificate signed by unknown authority")
177
func (s *HTTPSClientTestSuite) TestInsecureClientAllowsSelfSigned(c *gc.C) {
178
headers, _, _ := s.setupLoopbackRequest()
179
client := NewNonSSLValidating()
180
req := &RequestData{ExpectedStatus: []int{http.StatusNoContent}}
181
err := client.BinaryRequest("POST", s.Server.URL, "", req, nil)
182
c.Assert(err, gc.IsNil)
183
agent := headers.Get("User-Agent")
184
c.Check(agent, gc.Not(gc.Equals), "")
185
c.Check(agent, gc.Equals, gooseAgent())
188
func (s *HTTPSClientTestSuite) TestProperlyFormattedJsonUnmarshalling(c *gc.C) {
189
validJSON := `{"itemNotFound": {"message": "A Meaningful error", "code": 404}}`
190
unmarshalled, err := unmarshallError([]byte(validJSON))
191
c.Assert(err, gc.IsNil)
192
c.Check(unmarshalled.Code, gc.Equals, 404)
193
c.Check(unmarshalled.Title, gc.Equals, "itemNotFound")
194
c.Check(unmarshalled.Message, gc.Equals, "A Meaningful error")
197
func (s *HTTPSClientTestSuite) TestImproperlyFormattedJSONUnmarshalling(c *gc.C) {
198
invalidJSON := `This string is not a valid JSON`
199
unmarshalled, err := unmarshallError([]byte(invalidJSON))
200
c.Assert(err, gc.NotNil)
201
c.Assert(unmarshalled, gc.IsNil)
202
c.Check(err, gc.ErrorMatches, "invalid character 'T' looking for beginning of value")
205
func (s *HTTPSClientTestSuite) TestJSONMissingCodeUnmarshalling(c *gc.C) {
206
missingCodeJSON := `{"itemNotFound": {"message": "A Meaningful error"}}`
207
unmarshalled, err := unmarshallError([]byte(missingCodeJSON))
208
c.Assert(err, gc.NotNil)
209
c.Assert(unmarshalled, gc.IsNil)
210
c.Check(err, gc.ErrorMatches, `Unparsable json error body: "{\\"itemNotFound\\": {\\"message\\": \\"A Meaningful error\\"}}"`)
213
func (s *HTTPSClientTestSuite) TestJSONMissingMessageUnmarshalling(c *gc.C) {
214
missingMessageJSON := `{"itemNotFound": {"code": 404}}`
215
unmarshalled, err := unmarshallError([]byte(missingMessageJSON))
216
c.Assert(err, gc.NotNil)
217
c.Assert(unmarshalled, gc.IsNil)
218
c.Check(err, gc.ErrorMatches, `Unparsable json error body: "{\\"itemNotFound\\": {\\"code\\": 404}}"`)
221
func (s *HTTPSClientTestSuite) TestBrokenBodyJSONUnmarshalling(c *gc.C) {
222
invalidBodyJSON := `{"itemNotFound": {}}`
223
unmarshalled, err := unmarshallError([]byte(invalidBodyJSON))
224
c.Assert(err, gc.NotNil)
225
c.Assert(unmarshalled, gc.IsNil)
226
c.Check(err, gc.ErrorMatches, `Unparsable json error body: \"{\\\"itemNotFound\\\": {}}\"`)