~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/terms-client/api/api_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2016 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package api_test
 
5
 
 
6
import (
 
7
        "bytes"
 
8
        "encoding/json"
 
9
        "io"
 
10
        "io/ioutil"
 
11
        "net/http"
 
12
        stdtesting "testing"
 
13
        "time"
 
14
 
 
15
        "github.com/juju/testing"
 
16
        jc "github.com/juju/testing/checkers"
 
17
        gc "gopkg.in/check.v1"
 
18
 
 
19
        "github.com/juju/terms-client/api"
 
20
        "github.com/juju/terms-client/api/wireformat"
 
21
)
 
22
 
 
23
type apiSuite struct {
 
24
        client     api.Client
 
25
        httpClient *mockHttpClient
 
26
}
 
27
 
 
28
func Test(t *stdtesting.T) {
 
29
        gc.TestingT(t)
 
30
}
 
31
 
 
32
var _ = gc.Suite(&apiSuite{})
 
33
 
 
34
func (s *apiSuite) SetUpTest(c *gc.C) {
 
35
        s.newClient(c)
 
36
}
 
37
 
 
38
func (s *apiSuite) newClient(c *gc.C) {
 
39
        s.httpClient = &mockHttpClient{}
 
40
        var err error
 
41
        s.client, err = api.NewClient(api.HTTPClient(s.httpClient))
 
42
        c.Assert(err, jc.ErrorIsNil)
 
43
}
 
44
 
 
45
func (s *apiSuite) TestPublish(c *gc.C) {
 
46
        termID := struct {
 
47
                TermID string `json:"term-id"`
 
48
        }{
 
49
                TermID: "test-owner/test-term/17",
 
50
        }
 
51
        s.httpClient.status = http.StatusOK
 
52
        s.httpClient.SetBody(c, termID)
 
53
 
 
54
        id, err := s.client.Publish("test-owner", "test-term", 17)
 
55
        c.Assert(err, jc.ErrorIsNil)
 
56
        c.Assert(id, gc.Equals, termID.TermID)
 
57
        s.httpClient.CheckCall(c, 0, "DoWithBody", "https://api.jujucharms.com/terms/v1/terms/test-owner/test-term/17/publish")
 
58
}
 
59
 
 
60
func (s *apiSuite) TestSaveOwnedTerm(c *gc.C) {
 
61
        term := wireformat.TermIDResponse{
 
62
                TermID: "test-term/1",
 
63
        }
 
64
        s.httpClient.status = http.StatusOK
 
65
        s.httpClient.SetBody(c, term)
 
66
        savedTerm, err := s.client.SaveTerm("owner", "test-term", "You hereby agree to run this test.")
 
67
        c.Assert(err, jc.ErrorIsNil)
 
68
        c.Assert(savedTerm, jc.DeepEquals, term.TermID)
 
69
        s.httpClient.CheckCall(c, 0, "DoWithBody", "https://api.jujucharms.com/terms/v1/terms/owner/test-term")
 
70
}
 
71
 
 
72
func (s *apiSuite) TestSaveOwnerlessTerm(c *gc.C) {
 
73
        term := wireformat.TermIDResponse{
 
74
                TermID: "test-term/1",
 
75
        }
 
76
        s.httpClient.status = http.StatusOK
 
77
        s.httpClient.SetBody(c, term)
 
78
        savedTerm, err := s.client.SaveTerm("", "test-term", "You hereby agree to run this test.")
 
79
        c.Assert(err, jc.ErrorIsNil)
 
80
        c.Assert(savedTerm, jc.DeepEquals, term.TermID)
 
81
        s.httpClient.CheckCall(c, 0, "DoWithBody", "https://api.jujucharms.com/terms/v1/terms/test-term")
 
82
}
 
83
 
 
84
func (s *apiSuite) TestSaveTermError(c *gc.C) {
 
85
        s.httpClient.status = http.StatusInternalServerError
 
86
        s.httpClient.SetBody(c, struct {
 
87
                Error string `json:"error"`
 
88
        }{"silly internal error"})
 
89
        _, err := s.client.SaveTerm("", "test-term", "You hereby agree to run this test.")
 
90
        c.Assert(err, gc.ErrorMatches, "silly internal error")
 
91
}
 
92
 
 
93
func (s *apiSuite) TestGetOwnedTermWithRevision(c *gc.C) {
 
94
        t := time.Now().Round(time.Second).UTC()
 
95
        term := []wireformat.Term{{
 
96
                Owner:     "owner",
 
97
                Name:      "test-term",
 
98
                Revision:  17,
 
99
                CreatedOn: wireformat.TimeRFC3339(t),
 
100
                Content:   "You hereby agree to run this test.",
 
101
        }}
 
102
        s.httpClient.status = http.StatusOK
 
103
        s.httpClient.SetBody(c, term)
 
104
        savedTerm, err := s.client.GetTerm("owner", "test-term", 17)
 
105
        c.Assert(err, jc.ErrorIsNil)
 
106
        c.Assert(savedTerm, jc.DeepEquals, &term[0])
 
107
        s.httpClient.CheckCall(c, 0, "Do", "https://api.jujucharms.com/terms/v1/terms/owner/test-term?revision=17")
 
108
}
 
109
 
 
110
func (s *apiSuite) TestGetOwnedTermWithoutRevision(c *gc.C) {
 
111
        t := time.Now().Round(time.Second).UTC()
 
112
        term := []wireformat.Term{{
 
113
                Owner:     "owner",
 
114
                Name:      "test-term",
 
115
                Revision:  17,
 
116
                CreatedOn: wireformat.TimeRFC3339(t),
 
117
                Content:   "You hereby agree to run this test.",
 
118
        }}
 
119
        s.httpClient.status = http.StatusOK
 
120
        s.httpClient.SetBody(c, term)
 
121
        savedTerm, err := s.client.GetTerm("owner", "test-term", 0)
 
122
        c.Assert(err, jc.ErrorIsNil)
 
123
        c.Assert(savedTerm, jc.DeepEquals, &term[0])
 
124
        s.httpClient.CheckCall(c, 0, "Do", "https://api.jujucharms.com/terms/v1/terms/owner/test-term")
 
125
}
 
126
 
 
127
func (s *apiSuite) TestGetOwnerlessTermWithRevision(c *gc.C) {
 
128
        t := time.Now().Round(time.Second).UTC()
 
129
        term := []wireformat.Term{{
 
130
                Name:      "test-term",
 
131
                Revision:  17,
 
132
                CreatedOn: wireformat.TimeRFC3339(t),
 
133
                Content:   "You hereby agree to run this test.",
 
134
        }}
 
135
        s.httpClient.status = http.StatusOK
 
136
        s.httpClient.SetBody(c, term)
 
137
        savedTerm, err := s.client.GetTerm("", "test-term", 17)
 
138
        c.Assert(err, jc.ErrorIsNil)
 
139
        c.Assert(savedTerm, jc.DeepEquals, &term[0])
 
140
        s.httpClient.CheckCall(c, 0, "Do", "https://api.jujucharms.com/terms/v1/terms/test-term?revision=17")
 
141
}
 
142
 
 
143
func (s *apiSuite) TestGetOwnerlessTermWithoutRevision(c *gc.C) {
 
144
        t := time.Now().Round(time.Second).UTC()
 
145
        term := []wireformat.Term{{
 
146
                Name:      "test-term",
 
147
                Revision:  17,
 
148
                CreatedOn: wireformat.TimeRFC3339(t),
 
149
                Content:   "You hereby agree to run this test.",
 
150
        }}
 
151
        s.httpClient.status = http.StatusOK
 
152
        s.httpClient.SetBody(c, term)
 
153
        savedTerm, err := s.client.GetTerm("", "test-term", 0)
 
154
        c.Assert(err, jc.ErrorIsNil)
 
155
        c.Assert(savedTerm, jc.DeepEquals, &term[0])
 
156
        s.httpClient.CheckCall(c, 0, "Do", "https://api.jujucharms.com/terms/v1/terms/test-term")
 
157
}
 
158
 
 
159
func (s *apiSuite) TestGetTermError(c *gc.C) {
 
160
        s.httpClient.status = http.StatusInternalServerError
 
161
        s.httpClient.SetBody(c, struct {
 
162
                Error string `json:"error"`
 
163
        }{"silly internal error"})
 
164
        _, err := s.client.GetTerm("", "test-term", 17)
 
165
        c.Assert(err, gc.ErrorMatches, "silly internal error")
 
166
}
 
167
 
 
168
func (s *apiSuite) TestSignedAgreements(c *gc.C) {
 
169
        t := time.Now().Round(time.Second).UTC()
 
170
        s.httpClient.status = http.StatusOK
 
171
        s.httpClient.SetBody(c, []wireformat.Agreement{{
 
172
                User:      "test-user",
 
173
                Term:      "hello-world-terms",
 
174
                Revision:  1,
 
175
                CreatedOn: wireformat.TimeRFC3339(t),
 
176
        }, {
 
177
                User:      "test-user",
 
178
                Term:      "hello-universe-terms",
 
179
                Revision:  42,
 
180
                CreatedOn: wireformat.TimeRFC3339(t),
 
181
        },
 
182
        })
 
183
        signedAgreements, err := s.client.GetUsersAgreements()
 
184
        c.Assert(err, jc.ErrorIsNil)
 
185
        c.Assert(signedAgreements, gc.HasLen, 2)
 
186
        c.Assert(signedAgreements[0].User, gc.Equals, "test-user")
 
187
        c.Assert(signedAgreements[0].Term, gc.Equals, "hello-world-terms")
 
188
        c.Assert(signedAgreements[0].Revision, gc.Equals, 1)
 
189
        c.Assert(signedAgreements[0].CreatedOn, gc.DeepEquals, t)
 
190
        c.Assert(signedAgreements[1].User, gc.Equals, "test-user")
 
191
        c.Assert(signedAgreements[1].Term, gc.Equals, "hello-universe-terms")
 
192
        c.Assert(signedAgreements[1].Revision, gc.Equals, 42)
 
193
        c.Assert(signedAgreements[1].CreatedOn, gc.DeepEquals, t)
 
194
}
 
195
 
 
196
func (s *apiSuite) TestUnsignedTerms(c *gc.C) {
 
197
        s.httpClient.status = http.StatusOK
 
198
        s.httpClient.SetBody(c, []wireformat.Term{{
 
199
                Name:     "hello-world-terms",
 
200
                Revision: 1,
 
201
                Content:  "terms doc content",
 
202
        }, {
 
203
                Name:     "hello-universe-terms",
 
204
                Revision: 1,
 
205
                Content:  "universal terms doc content",
 
206
        },
 
207
        })
 
208
        missingAgreements, err := s.client.GetUnsignedTerms(&wireformat.CheckAgreementsRequest{
 
209
                Terms: []string{
 
210
                        "hello-world-terms/1",
 
211
                        "hello-universe-terms/1",
 
212
                },
 
213
        })
 
214
        c.Assert(err, jc.ErrorIsNil)
 
215
        c.Assert(missingAgreements, gc.HasLen, 2)
 
216
        c.Assert(missingAgreements[0].Name, gc.Equals, "hello-world-terms")
 
217
        c.Assert(missingAgreements[0].Revision, gc.Equals, 1)
 
218
        c.Assert(missingAgreements[0].Content, gc.Equals, "terms doc content")
 
219
        c.Assert(missingAgreements[1].Name, gc.Equals, "hello-universe-terms")
 
220
        c.Assert(missingAgreements[1].Revision, gc.Equals, 1)
 
221
        c.Assert(missingAgreements[1].Content, gc.Equals, "universal terms doc content")
 
222
        s.httpClient.SetBody(c, wireformat.SaveAgreementResponses{
 
223
                Agreements: []wireformat.AgreementResponse{{
 
224
                        User:     "test-user",
 
225
                        Term:     "hello-world-terms",
 
226
                        Revision: 1,
 
227
                }}},
 
228
        )
 
229
 
 
230
        p1 := wireformat.SaveAgreements{
 
231
                Agreements: []wireformat.SaveAgreement{{
 
232
                        TermName:     "hello-world-terms",
 
233
                        TermRevision: 1,
 
234
                }},
 
235
        }
 
236
        response, err := s.client.SaveAgreement(&p1)
 
237
        c.Assert(err, jc.ErrorIsNil)
 
238
        c.Assert(response.Agreements, gc.HasLen, 1)
 
239
        c.Assert(response.Agreements[0].User, gc.Equals, "test-user")
 
240
        c.Assert(response.Agreements[0].Term, gc.Equals, "hello-world-terms")
 
241
        c.Assert(response.Agreements[0].Revision, gc.Equals, 1)
 
242
}
 
243
 
 
244
func (s *apiSuite) TestNotFoundError(c *gc.C) {
 
245
        s.httpClient.status = http.StatusNotFound
 
246
        s.httpClient.body = []byte("something failed")
 
247
        _, err := s.client.GetUnsignedTerms(&wireformat.CheckAgreementsRequest{
 
248
                Terms: []string{
 
249
                        "hello-world-terms/1",
 
250
                        "hello-universe-terms/1",
 
251
                },
 
252
        })
 
253
        c.Assert(err, gc.ErrorMatches, "failed to get unsigned terms: Not Found: something failed")
 
254
}
 
255
 
 
256
func (s *apiSuite) TestSignedAgreementsEnvTermsURL(c *gc.C) {
 
257
        cleanup := testing.PatchEnvironment("JUJU_TERMS", "http://example.com")
 
258
        defer cleanup()
 
259
        s.newClient(c)
 
260
 
 
261
        t := time.Now().UTC()
 
262
        s.httpClient.status = http.StatusOK
 
263
        s.httpClient.SetBody(c, []wireformat.AgreementResponse{
 
264
                {
 
265
                        User:      "test-user",
 
266
                        Term:      "hello-world-terms",
 
267
                        Revision:  1,
 
268
                        CreatedOn: t,
 
269
                },
 
270
                {
 
271
                        User:      "test-user",
 
272
                        Term:      "hello-universe-terms",
 
273
                        Revision:  42,
 
274
                        CreatedOn: t,
 
275
                },
 
276
        })
 
277
        _, err := s.client.GetUsersAgreements()
 
278
        c.Assert(err, jc.ErrorIsNil)
 
279
        c.Assert(s.httpClient.Calls(), gc.HasLen, 1)
 
280
        s.httpClient.CheckCall(c, 0, "Do", "http://example.com/v1/agreements")
 
281
}
 
282
 
 
283
func (s *apiSuite) TestUnsignedTermsEnvTermsURL(c *gc.C) {
 
284
        cleanup := testing.PatchEnvironment("JUJU_TERMS", "http://example.com")
 
285
        defer cleanup()
 
286
        s.newClient(c)
 
287
 
 
288
        s.httpClient.status = http.StatusOK
 
289
        s.httpClient.SetBody(c, []wireformat.GetTermsResponse{
 
290
                {
 
291
                        Name:     "hello-world-terms",
 
292
                        Revision: 1,
 
293
                        Content:  "terms doc content",
 
294
                },
 
295
                {
 
296
                        Name:     "hello-universe-terms",
 
297
                        Revision: 1,
 
298
                        Content:  "universal terms doc content",
 
299
                },
 
300
        })
 
301
        _, err := s.client.GetUnsignedTerms(&wireformat.CheckAgreementsRequest{
 
302
                Terms: []string{
 
303
                        "hello-world-terms/1",
 
304
                        "hello-universe-terms/1",
 
305
                },
 
306
        })
 
307
        c.Assert(err, jc.ErrorIsNil)
 
308
        c.Assert(s.httpClient.Calls(), gc.HasLen, 1)
 
309
        s.httpClient.CheckCall(c, 0, "Do", "http://example.com/v1/agreement?Terms=hello-world-terms%2F1&Terms=hello-universe-terms%2F1")
 
310
        s.httpClient.ResetCalls()
 
311
}
 
312
 
 
313
func (s *apiSuite) TestSaveAgreementEnvTermsURL(c *gc.C) {
 
314
        cleanup := testing.PatchEnvironment("JUJU_TERMS", "http://example.com")
 
315
        defer cleanup()
 
316
        s.newClient(c)
 
317
 
 
318
        s.httpClient.status = http.StatusOK
 
319
        s.httpClient.SetBody(c, wireformat.SaveAgreementResponses{})
 
320
        p1 := wireformat.SaveAgreements{
 
321
                Agreements: []wireformat.SaveAgreement{{
 
322
                        TermName:     "hello-world-terms",
 
323
                        TermRevision: 1,
 
324
                }},
 
325
        }
 
326
        _, err := s.client.SaveAgreement(&p1)
 
327
        c.Assert(err, jc.ErrorIsNil)
 
328
        c.Assert(s.httpClient.Calls(), gc.HasLen, 1)
 
329
        s.httpClient.CheckCall(c, 0, "DoWithBody", "http://example.com/v1/agreement")
 
330
}
 
331
 
 
332
type mockHttpClient struct {
 
333
        testing.Stub
 
334
        status int
 
335
        body   []byte
 
336
}
 
337
 
 
338
func (m *mockHttpClient) Do(req *http.Request) (*http.Response, error) {
 
339
        m.AddCall("Do", req.URL.String())
 
340
        return &http.Response{
 
341
                Status:     http.StatusText(m.status),
 
342
                StatusCode: m.status,
 
343
                Proto:      "HTTP/1.0",
 
344
                ProtoMajor: 1,
 
345
                ProtoMinor: 1,
 
346
                Body:       ioutil.NopCloser(bytes.NewReader(m.body)),
 
347
        }, nil
 
348
}
 
349
 
 
350
func (m *mockHttpClient) DoWithBody(req *http.Request, body io.ReadSeeker) (*http.Response, error) {
 
351
        m.AddCall("DoWithBody", req.URL.String())
 
352
        return &http.Response{
 
353
                Status:     http.StatusText(m.status),
 
354
                StatusCode: m.status,
 
355
                Proto:      "HTTP/1.0",
 
356
                ProtoMajor: 1,
 
357
                ProtoMinor: 1,
 
358
                Body:       ioutil.NopCloser(bytes.NewReader(m.body)),
 
359
        }, nil
 
360
}
 
361
 
 
362
func (m *mockHttpClient) SetBody(c *gc.C, v interface{}) {
 
363
        b, err := json.Marshal(&v)
 
364
        c.Assert(err, jc.ErrorIsNil)
 
365
        m.body = b
 
366
}