blob: 2ec6016bdc06f2f40729815c7a127d1b2c0eaada [file] [log] [blame]
Kevin Burke84c3f712017-01-22 06:03:14 -08001// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package gerrit
6
7import (
Brad Fitzpatrickbce074b2017-04-18 03:12:13 +00008 "context"
Kevin Burkeafc6d122017-07-14 11:17:43 -06009 "io"
Kevin Burke84c3f712017-01-22 06:03:14 -080010 "net/http"
11 "net/http/httptest"
12 "net/url"
Kevin Burkeafc6d122017-07-14 11:17:43 -060013 "strings"
Kevin Burke84c3f712017-01-22 06:03:14 -080014 "testing"
15 "time"
Kevin Burke84c3f712017-01-22 06:03:14 -080016)
17
18// taken from https://go-review.googlesource.com/projects/go
19var exampleProjectResponse = []byte(`)]}'
20{
21 "id": "go",
22 "name": "go",
23 "parent": "All-Projects",
24 "description": "The Go Programming Language",
25 "state": "ACTIVE",
26 "web_links": [
27 {
28 "name": "gitiles",
29 "url": "https://go.googlesource.com/go/",
30 "target": "_blank"
31 }
32 ]
33}
34`)
35
36func TestGetProjectInfo(t *testing.T) {
37 hitServer := false
38 path := ""
39 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
40 hitServer = true
41 path = r.URL.Path
42 w.Header().Set("Content-Type", "application/json; charset=UTF-8")
43 w.WriteHeader(200)
44 w.Write(exampleProjectResponse)
45 }))
46 defer s.Close()
47 c := NewClient(s.URL, NoAuth)
48 info, err := c.GetProjectInfo(context.Background(), "go")
49 if err != nil {
50 t.Fatal(err)
51 }
52 if !hitServer {
53 t.Errorf("expected to hit test server, didn't")
54 }
55 if path != "/projects/go" {
56 t.Errorf("expected Path to be '/projects/go', got %s", path)
57 }
58 if info.Name != "go" {
59 t.Errorf("expected Name to be 'go', got %s", info.Name)
60 }
61}
62
63func TestProjectNotFound(t *testing.T) {
64 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
65 w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
66 w.WriteHeader(404)
67 w.Write([]byte("Not found: unknown"))
68 }))
69 defer s.Close()
70 c := NewClient(s.URL, NoAuth)
71 _, err := c.GetProjectInfo(context.Background(), "unknown")
72 if err != ErrProjectNotExist {
73 t.Errorf("expected to get ErrProjectNotExist, got %v", err)
74 }
75}
76
77func TestContextError(t *testing.T) {
78 c := NewClient("http://localhost", NoAuth)
79 yearsAgo, _ := time.Parse("2006", "2006")
80 ctx, cancel := context.WithDeadline(context.Background(), yearsAgo)
81 defer cancel()
82 _, err := c.GetProjectInfo(ctx, "unknown")
83 if err == nil {
84 t.Errorf("expected non-nil error, got nil")
85 }
86 uerr, ok := err.(*url.Error)
87 if !ok {
88 t.Errorf("expected url.Error, got %#v", err)
89 }
90 if uerr.Err != context.DeadlineExceeded {
91 t.Errorf("expected DeadlineExceeded error, got %v", uerr.Err)
92 }
93}
Kevin Burkeafc6d122017-07-14 11:17:43 -060094
95var getChangeResponse = []byte(`)]}'
96{
97 "id": "build~master~I92989e0231299ed305ddfbbe6034d293f1c87470",
98 "project": "build",
99 "branch": "master",
100 "hashtags": [],
101 "change_id": "I92989e0231299ed305ddfbbe6034d293f1c87470",
102 "subject": "devapp: fix tests",
103 "status": "ABANDONED",
104 "created": "2017-07-13 06:09:10.000000000",
105 "updated": "2017-07-14 16:31:32.000000000",
106 "insertions": 1,
107 "deletions": 1,
108 "unresolved_comment_count": 0,
109 "has_review_started": true,
110 "_number": 48330,
111 "owner": {
112 "_account_id": 13437
113 },
114 "messages": [
115 {
116 "id": "f9fcf0ff9eb58fc8edd989f8bbb3500ff73f9b11",
117 "author": {
118 "_account_id": 22285
119 },
120 "real_author": {
121 "_account_id": 22285
122 },
123 "date": "2017-07-13 06:14:48.000000000",
124 "message": "Patch Set 1:\n\nCheck out https://go-review.googlesource.com/c/48350/ :)",
125 "_revision_number": 1
126 }
127 ]
128}`)
129
130func TestGetChange(t *testing.T) {
131 hitServer := false
132 uri := ""
133 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
134 hitServer = true
135 uri = r.URL.RequestURI()
136 w.Header().Set("Content-Type", "application/json; charset=UTF-8")
137 w.WriteHeader(200)
138 w.Write(getChangeResponse)
139 }))
140 defer s.Close()
141 c := NewClient(s.URL, NoAuth)
Kevin Burkebf074722017-07-14 23:13:50 -0600142 info, err := c.GetChange(context.Background(), "48330", QueryChangesOpt{
Kevin Burkeafc6d122017-07-14 11:17:43 -0600143 Fields: []string{"MESSAGES"},
144 })
145 if err != nil {
146 t.Fatal(err)
147 }
148 if !hitServer {
149 t.Errorf("expected to hit test server, didn't")
150 }
151 if want := "/changes/48330?o=MESSAGES"; uri != want {
152 t.Errorf("expected RequestURI to be %q, got %q", want, uri)
153 }
154 if len(info.Messages) != 1 {
155 t.Errorf("expected message length to be 1, got %d", len(info.Messages))
156 }
157 msg := info.Messages[0].Message
158 if !strings.Contains(msg, "Check out") {
159 t.Errorf("expected to find string in Message, got %s", msg)
160 }
161}
162
163func TestGetChangeError(t *testing.T) {
164 hitServer := false
165 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
166 hitServer = true
167 w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
168 w.WriteHeader(404)
169 io.WriteString(w, "Not found: 99999")
170 }))
171 defer s.Close()
172 c := NewClient(s.URL, NoAuth)
Kevin Burkebf074722017-07-14 23:13:50 -0600173 _, err := c.GetChange(context.Background(), "99999", QueryChangesOpt{
Kevin Burkeafc6d122017-07-14 11:17:43 -0600174 Fields: []string{"MESSAGES"},
175 })
Kevin Burked13a0932017-11-28 13:50:06 -0800176 if !hitServer {
177 t.Errorf("expected to hit test server, didn't")
178 }
Kevin Burkeafc6d122017-07-14 11:17:43 -0600179 if err != ErrChangeNotExist {
180 t.Errorf("expected ErrChangeNotExist, got %v", err)
181 }
182}
Lann Martinbe55dc02017-08-01 11:23:33 -0600183
Jude Pereiraec36dd22017-09-06 23:40:03 +0530184var queryAccountsResponse = []byte(`)]}'
185[
186 {
187 "_account_id": 1,
188 "name": "John Doe",
189 "email": "john@doe.com"
190 },
191 {
192 "_account_id": 2,
193 "name": "Jane Doe",
194 "email": "jane@doe.com",
195 "_more_accounts": true
196 }
197]`)
198
199func TestQueryAccounts(t *testing.T) {
200 hitServer := false
201 uri := ""
202
203 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
204 hitServer = true
205 uri = r.URL.RequestURI()
206 w.Header().Set("Content-Type", "application/json; charset=UTF-8")
207 w.WriteHeader(200)
208 w.Write(queryAccountsResponse)
209 }))
210 defer s.Close()
211 c := NewClient(s.URL, NoAuth)
212 info, err := c.QueryAccounts(context.Background(), "is:active", QueryAccountsOpt{
213 Fields: []string{"DETAILS"},
214 N: 2,
215 })
216 if err != nil {
217 t.Fatal(err.Error())
218 }
219 if !hitServer {
220 t.Errorf("expected to hit test server, didn't")
221 }
222 if want := "/accounts/?n=2&o=DETAILS&q=is%3Aactive"; uri != want {
223 t.Errorf("expected RequestURI to be %q, got %q", want, uri)
224 }
225 if len(info) != 2 {
226 t.Errorf("expected accounts length to be 2, got %d", len(info))
227 }
228 if info[0].NumericID != 1 || info[0].Name != "John Doe" || info[0].Email != "john@doe.com" {
Tobias Klauserc9ba2772017-11-01 16:06:52 +0100229 t.Errorf("expected to match John Doe in account, got %v", info[0])
Jude Pereiraec36dd22017-09-06 23:40:03 +0530230 }
231 if info[1].NumericID != 2 || info[1].Name != "Jane Doe" || info[1].Email != "jane@doe.com" {
Tobias Klauserc9ba2772017-11-01 16:06:52 +0100232 t.Errorf("expected to match Jane Doe in account, got %v", info[1])
Jude Pereiraec36dd22017-09-06 23:40:03 +0530233 }
234 if info[0].MoreAccounts {
235 t.Errorf("expected to MoreAccounts to be false for John Doe")
236 }
237 if !info[1].MoreAccounts {
238 t.Errorf("expected to MoreAccounts to be true for Jane Doe")
239 }
240}
241
Lann Martinbe55dc02017-08-01 11:23:33 -0600242func TestTimeStampMarshalJson(t *testing.T) {
243 ts := TimeStamp(time.Date(1888, 6, 24, 6, 8, 30, 123456789, time.FixedZone("+1", 3600)))
244 b, err := ts.MarshalJSON()
245 if err != nil {
246 t.Errorf("unexpected err %v", err)
247 }
248 expected := `"1888-06-24 05:08:30.123456789"`
249 if string(b) != expected {
250 t.Errorf("expected %q, got %q", expected, b)
251 }
252}
253
254func TestTimeStampUnmarshalJson(t *testing.T) {
255 var ts TimeStamp
256 err := ts.UnmarshalJSON([]byte(`"1888-06-24 05:08:30.123456789"`))
257 if err != nil {
258 t.Errorf("unexpected err %v", err)
259 }
260 expected := time.Date(1888, 6, 24, 5, 8, 30, 123456789, time.UTC)
261 if !ts.Time().Equal(expected) {
262 t.Errorf("expected %v, got %v", expected, ts.Time())
263 }
264}
Giuseppe Valente453fa3c2018-10-23 20:46:33 +0000265
266// taken from https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#list-tags
267var exampleProjectTagsResponse = []byte(` )]}'
268 [
269 {
270 "ref": "refs/tags/v1.0",
271 "revision": "49ce77fdcfd3398dc0dedbe016d1a425fd52d666",
272 "object": "1624f5af8ae89148d1a3730df8c290413e3dcf30",
273 "message": "Annotated tag",
274 "tagger": {
275 "name": "David Pursehouse",
276 "email": "david.pursehouse@sonymobile.com",
277 "date": "2014-10-06 07:35:03.000000000",
278 "tz": 540
279 }
280 },
281 {
282 "ref": "refs/tags/v2.0",
283 "revision": "1624f5af8ae89148d1a3730df8c290413e3dcf30"
284 }
285 ]
286`)
287
288func TestGetProjectTags(t *testing.T) {
289 hitServer := false
290 path := ""
291 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
292 hitServer = true
293 path = r.URL.Path
294 w.Header().Set("Content-Type", "application/json; charset=UTF-8")
295 w.WriteHeader(200)
296 w.Write(exampleProjectTagsResponse)
297 }))
298 defer s.Close()
299 c := NewClient(s.URL, NoAuth)
300 tags, err := c.GetProjectTags(context.Background(), "go")
301 if err != nil {
302 t.Fatal(err)
303 }
304 if !hitServer {
305 t.Errorf("expected to hit test server, didn't")
306 }
307 if path != "/projects/go/tags/" {
308 t.Errorf("expected Path to be '/projects/go/tags/', got %s", path)
309 }
310 expectedTags := map[string]TagInfo{
311 "refs/tags/v1.0": TagInfo{
312 Ref: "refs/tags/v1.0",
313 Revision: "49ce77fdcfd3398dc0dedbe016d1a425fd52d666",
314 Object: "1624f5af8ae89148d1a3730df8c290413e3dcf30",
315 Message: "Annotated tag",
316 Tagger: &GitPersonInfo{
317 Name: "David Pursehouse",
318 Email: "david.pursehouse@sonymobile.com",
319 Date: TimeStamp(time.Date(2014, 10, 6, 7, 35, 3, 0, time.UTC)),
320 TZOffset: 540,
321 },
322 },
323 "refs/tags/v2.0": TagInfo{
324 Ref: "refs/tags/v2.0",
325 Revision: "1624f5af8ae89148d1a3730df8c290413e3dcf30",
326 },
327 }
328 if len(tags) != len(expectedTags) {
329 t.Errorf("expected %d tags, got %d", len(expectedTags), len(tags))
330 }
331 for ref, tag := range tags {
332 expectedTag, found := expectedTags[ref]
333 if !found {
334 t.Errorf("unexpected tag %q", ref)
335 }
336 if !tag.Equal(&expectedTag) {
337 t.Errorf("tags don't match (expected %#v and got %#v)", expectedTag, tag)
338 }
339 }
340}