1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
13
"github.com/juju/errors"
14
"github.com/juju/names"
15
"github.com/juju/testing"
16
jc "github.com/juju/testing/checkers"
17
gc "gopkg.in/check.v1"
19
"github.com/juju/juju/apiserver/params"
20
"github.com/juju/juju/resource/api"
21
"github.com/juju/juju/resource/api/server"
24
type LegacyHTTPHandlerSuite struct {
30
resp *stubHTTPResponseWriter
31
result *api.UploadResult
34
var _ = gc.Suite(&LegacyHTTPHandlerSuite{})
36
func (s *LegacyHTTPHandlerSuite) SetUpTest(c *gc.C) {
37
s.BaseSuite.SetUpTest(c)
41
body := strings.NewReader("...")
42
req, err := http.NewRequest(method, urlStr, body)
43
c.Assert(err, jc.ErrorIsNil)
46
s.header = make(http.Header)
47
s.resp = &stubHTTPResponseWriter{
49
returnHeader: s.header,
51
s.result = &api.UploadResult{}
54
func (s *LegacyHTTPHandlerSuite) connect(req *http.Request) (server.DataStore, names.Tag, error) {
55
s.stub.AddCall("Connect", req)
56
if err := s.stub.NextErr(); err != nil {
57
return nil, nil, errors.Trace(err)
60
tag := names.NewUserTag(s.username)
61
return s.data, tag, nil
64
func (s *LegacyHTTPHandlerSuite) handleUpload(username string, st server.DataStore, req *http.Request) (*api.UploadResult, error) {
65
s.stub.AddCall("HandleUpload", username, st, req)
66
if err := s.stub.NextErr(); err != nil {
67
return nil, errors.Trace(err)
73
func (s *LegacyHTTPHandlerSuite) TestServeHTTPConnectFailure(c *gc.C) {
74
s.username = "youknowwho"
75
handler := server.LegacyHTTPHandler{
77
HandleUpload: s.handleUpload,
81
failure, expected := apiFailure(c, "<failure>", "")
82
s.stub.SetErrors(failure)
84
handler.ServeHTTP(s.resp, req)
86
s.stub.CheckCallNames(c,
93
s.stub.CheckCall(c, 0, "Connect", req)
94
s.stub.CheckCall(c, 3, "WriteHeader", http.StatusInternalServerError)
95
s.stub.CheckCall(c, 4, "Write", expected)
96
c.Check(req, jc.DeepEquals, s.req) // did not change
97
c.Check(s.header, jc.DeepEquals, http.Header{
98
"Content-Type": []string{"application/json"},
99
"Content-Length": []string{strconv.Itoa(len(expected))},
103
func (s *LegacyHTTPHandlerSuite) TestServeHTTPUnsupportedMethod(c *gc.C) {
104
s.username = "youknowwho"
105
handler := server.LegacyHTTPHandler{
107
HandleUpload: s.handleUpload,
109
s.req.Method = "POST"
112
_, expected := apiFailure(c, `unsupported method: "POST"`, params.CodeMethodNotAllowed)
114
handler.ServeHTTP(s.resp, req)
116
s.stub.CheckCallNames(c,
123
s.stub.CheckCall(c, 0, "Connect", req)
124
s.stub.CheckCall(c, 3, "WriteHeader", http.StatusMethodNotAllowed)
125
s.stub.CheckCall(c, 4, "Write", expected)
126
c.Check(req, jc.DeepEquals, s.req) // did not change
127
c.Check(s.header, jc.DeepEquals, http.Header{
128
"Content-Type": []string{"application/json"},
129
"Content-Length": []string{strconv.Itoa(len(expected))},
133
func (s *LegacyHTTPHandlerSuite) TestServeHTTPPutSuccess(c *gc.C) {
134
s.result.Resource.Name = "spam"
135
expected, err := json.Marshal(s.result)
136
c.Assert(err, jc.ErrorIsNil)
137
s.username = "youknowwho"
138
handler := server.LegacyHTTPHandler{
140
HandleUpload: s.handleUpload,
146
handler.ServeHTTP(s.resp, req)
148
s.stub.CheckCallNames(c,
156
s.stub.CheckCall(c, 0, "Connect", req)
157
s.stub.CheckCall(c, 1, "HandleUpload", "youknowwho", s.data, req)
158
s.stub.CheckCall(c, 4, "WriteHeader", http.StatusOK)
159
s.stub.CheckCall(c, 5, "Write", string(expected))
160
c.Check(req, jc.DeepEquals, s.req) // did not change
161
c.Check(s.header, jc.DeepEquals, http.Header{
162
"Content-Type": []string{"application/json"},
163
"Content-Length": []string{fmt.Sprint(len(expected))},
167
func (s *LegacyHTTPHandlerSuite) TestServeHTTPPutHandleUploadFailure(c *gc.C) {
168
s.username = "youknowwho"
169
handler := server.LegacyHTTPHandler{
171
HandleUpload: s.handleUpload,
176
failure, expected := apiFailure(c, "<failure>", "")
177
s.stub.SetErrors(nil, failure)
179
handler.ServeHTTP(s.resp, req)
181
s.stub.CheckCallNames(c,
189
s.stub.CheckCall(c, 0, "Connect", req)
190
s.stub.CheckCall(c, 1, "HandleUpload", "youknowwho", s.data, req)
191
s.stub.CheckCall(c, 4, "WriteHeader", http.StatusInternalServerError)
192
s.stub.CheckCall(c, 5, "Write", expected)
193
c.Check(req, jc.DeepEquals, s.req) // did not change
194
c.Check(s.header, jc.DeepEquals, http.Header{
195
"Content-Type": []string{"application/json"},
196
"Content-Length": []string{strconv.Itoa(len(expected))},
200
func apiFailure(c *gc.C, msg, code string) (error, string) {
201
failure := errors.New(msg)
203
data, err := json.Marshal(params.ErrorResult{
204
Error: ¶ms.Error{
209
c.Assert(err, jc.ErrorIsNil)
211
return failure, string(data)
214
type stubHTTPResponseWriter struct {
217
returnHeader http.Header
220
func (s *stubHTTPResponseWriter) Header() http.Header {
221
s.stub.AddCall("Header")
222
s.stub.NextErr() // Pop one off.
224
return s.returnHeader
227
func (s *stubHTTPResponseWriter) Write(data []byte) (int, error) {
228
s.stub.AddCall("Write", string(data))
229
if err := s.stub.NextErr(); err != nil {
230
return 0, errors.Trace(err)
233
return len(data), nil
236
func (s *stubHTTPResponseWriter) WriteHeader(code int) {
237
s.stub.AddCall("WriteHeader", code)
238
s.stub.NextErr() // Pop one off.