1
2
3
4
5
6 package github
7
8 import (
9 "context"
10 "encoding/json"
11 "fmt"
12 "net/http"
13 "testing"
14 "time"
15
16 "github.com/google/go-cmp/cmp"
17 )
18
19 func TestIssueImportService_Create(t *testing.T) {
20 client, mux, _, teardown := setup()
21 defer teardown()
22
23 createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC)
24 input := &IssueImportRequest{
25 IssueImport: IssueImport{
26 Assignee: String("developer"),
27 Body: "Dummy description",
28 CreatedAt: &Timestamp{createdAt},
29 Labels: []string{"l1", "l2"},
30 Milestone: Int(1),
31 Title: "Dummy Issue",
32 },
33 Comments: []*Comment{{
34 CreatedAt: &Timestamp{createdAt},
35 Body: "Comment body",
36 }},
37 }
38
39 mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) {
40 v := new(IssueImportRequest)
41 json.NewDecoder(r.Body).Decode(v)
42 testMethod(t, r, "POST")
43 testHeader(t, r, "Accept", mediaTypeIssueImportAPI)
44 if !cmp.Equal(v, input) {
45 t.Errorf("Request body = %+v, want %+v", v, input)
46 }
47
48 w.Write(issueImportResponseJSON)
49 })
50
51 ctx := context.Background()
52 got, _, err := client.IssueImport.Create(ctx, "o", "r", input)
53 if err != nil {
54 t.Errorf("Create returned error: %v", err)
55 }
56
57 want := wantIssueImportResponse
58 if !cmp.Equal(got, want) {
59 t.Errorf("Create = %+v, want %+v", got, want)
60 }
61
62 const methodName = "Create"
63 testBadOptions(t, methodName, func() (err error) {
64 _, _, err = client.IssueImport.Create(ctx, "\n", "\n", input)
65 return err
66 })
67
68 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
69 got, resp, err := client.IssueImport.Create(ctx, "o", "r", input)
70 if got != nil {
71 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
72 }
73 return resp, err
74 })
75 }
76
77 func TestIssueImportService_Create_defered(t *testing.T) {
78 client, mux, _, teardown := setup()
79 defer teardown()
80
81 createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC)
82 input := &IssueImportRequest{
83 IssueImport: IssueImport{
84 Assignee: String("developer"),
85 Body: "Dummy description",
86 CreatedAt: &Timestamp{createdAt},
87 Labels: []string{"l1", "l2"},
88 Milestone: Int(1),
89 Title: "Dummy Issue",
90 },
91 Comments: []*Comment{{
92 CreatedAt: &Timestamp{createdAt},
93 Body: "Comment body",
94 }},
95 }
96
97 mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) {
98 v := new(IssueImportRequest)
99 json.NewDecoder(r.Body).Decode(v)
100 testMethod(t, r, "POST")
101 testHeader(t, r, "Accept", mediaTypeIssueImportAPI)
102 if !cmp.Equal(v, input) {
103 t.Errorf("Request body = %+v, want %+v", v, input)
104 }
105
106 w.WriteHeader(http.StatusAccepted)
107 w.Write(issueImportResponseJSON)
108 })
109
110 ctx := context.Background()
111 got, _, err := client.IssueImport.Create(ctx, "o", "r", input)
112
113 if _, ok := err.(*AcceptedError); !ok {
114 t.Errorf("Create returned error: %v (want AcceptedError)", err)
115 }
116
117 want := wantIssueImportResponse
118 if !cmp.Equal(got, want) {
119 t.Errorf("Create = %+v, want %+v", got, want)
120 }
121 }
122
123 func TestIssueImportService_Create_badResponse(t *testing.T) {
124 client, mux, _, teardown := setup()
125 defer teardown()
126
127 createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC)
128 input := &IssueImportRequest{
129 IssueImport: IssueImport{
130 Assignee: String("developer"),
131 Body: "Dummy description",
132 CreatedAt: &Timestamp{createdAt},
133 Labels: []string{"l1", "l2"},
134 Milestone: Int(1),
135 Title: "Dummy Issue",
136 },
137 Comments: []*Comment{{
138 CreatedAt: &Timestamp{createdAt},
139 Body: "Comment body",
140 }},
141 }
142
143 mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) {
144 v := new(IssueImportRequest)
145 json.NewDecoder(r.Body).Decode(v)
146 testMethod(t, r, "POST")
147 testHeader(t, r, "Accept", mediaTypeIssueImportAPI)
148 if !cmp.Equal(v, input) {
149 t.Errorf("Request body = %+v, want %+v", v, input)
150 }
151
152 w.WriteHeader(http.StatusAccepted)
153 w.Write([]byte("{[}"))
154 })
155
156 ctx := context.Background()
157 _, _, err := client.IssueImport.Create(ctx, "o", "r", input)
158
159 if err == nil || err.Error() != "invalid character '[' looking for beginning of object key string" {
160 t.Errorf("unexpected error: %v", err)
161 }
162 }
163
164 func TestIssueImportService_Create_invalidOwner(t *testing.T) {
165 client, _, _, teardown := setup()
166 defer teardown()
167
168 ctx := context.Background()
169 _, _, err := client.IssueImport.Create(ctx, "%", "r", nil)
170 testURLParseError(t, err)
171 }
172
173 func TestIssueImportService_CheckStatus(t *testing.T) {
174 client, mux, _, teardown := setup()
175 defer teardown()
176
177 mux.HandleFunc("/repos/o/r/import/issues/3", func(w http.ResponseWriter, r *http.Request) {
178 testMethod(t, r, "GET")
179 testHeader(t, r, "Accept", mediaTypeIssueImportAPI)
180 w.WriteHeader(http.StatusOK)
181 w.Write(issueImportResponseJSON)
182 })
183
184 ctx := context.Background()
185 got, _, err := client.IssueImport.CheckStatus(ctx, "o", "r", 3)
186 if err != nil {
187 t.Errorf("CheckStatus returned error: %v", err)
188 }
189
190 want := wantIssueImportResponse
191 if !cmp.Equal(got, want) {
192 t.Errorf("CheckStatus = %+v, want %+v", got, want)
193 }
194
195 const methodName = "CheckStatus"
196 testBadOptions(t, methodName, func() (err error) {
197 _, _, err = client.IssueImport.CheckStatus(ctx, "\n", "\n", -3)
198 return err
199 })
200
201 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
202 got, resp, err := client.IssueImport.CheckStatus(ctx, "o", "r", 3)
203 if got != nil {
204 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
205 }
206 return resp, err
207 })
208 }
209
210 func TestIssueImportService_CheckStatus_invalidOwner(t *testing.T) {
211 client, _, _, teardown := setup()
212 defer teardown()
213
214 ctx := context.Background()
215 _, _, err := client.IssueImport.CheckStatus(ctx, "%", "r", 1)
216 testURLParseError(t, err)
217 }
218
219 func TestIssueImportService_CheckStatusSince(t *testing.T) {
220 client, mux, _, teardown := setup()
221 defer teardown()
222
223 mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) {
224 testMethod(t, r, "GET")
225 testHeader(t, r, "Accept", mediaTypeIssueImportAPI)
226 w.WriteHeader(http.StatusOK)
227 w.Write([]byte(fmt.Sprintf("[%s]", issueImportResponseJSON)))
228 })
229
230 ctx := context.Background()
231 got, _, err := client.IssueImport.CheckStatusSince(ctx, "o", "r", Timestamp{time.Now()})
232 if err != nil {
233 t.Errorf("CheckStatusSince returned error: %v", err)
234 }
235
236 want := []*IssueImportResponse{wantIssueImportResponse}
237 if !cmp.Equal(want, got) {
238 t.Errorf("CheckStatusSince = %v, want = %v", got, want)
239 }
240
241 const methodName = "CheckStatusSince"
242 testBadOptions(t, methodName, func() (err error) {
243 _, _, err = client.IssueImport.CheckStatusSince(ctx, "\n", "\n", Timestamp{time.Now()})
244 return err
245 })
246
247 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
248 got, resp, err := client.IssueImport.CheckStatusSince(ctx, "o", "r", Timestamp{time.Now()})
249 if got != nil {
250 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
251 }
252 return resp, err
253 })
254 }
255
256 func TestIssueImportService_CheckStatusSince_badResponse(t *testing.T) {
257 client, mux, _, teardown := setup()
258 defer teardown()
259
260 mux.HandleFunc("/repos/o/r/import/issues", func(w http.ResponseWriter, r *http.Request) {
261 testMethod(t, r, "GET")
262 testHeader(t, r, "Accept", mediaTypeIssueImportAPI)
263 w.WriteHeader(http.StatusOK)
264 w.Write([]byte("{badly-formed JSON"))
265 })
266
267 ctx := context.Background()
268 if _, _, err := client.IssueImport.CheckStatusSince(ctx, "o", "r", Timestamp{time.Now()}); err == nil {
269 t.Errorf("CheckStatusSince returned no error, want JSON err")
270 }
271 }
272
273 func TestIssueImportService_CheckStatusSince_invalidOwner(t *testing.T) {
274 client, _, _, teardown := setup()
275 defer teardown()
276
277 ctx := context.Background()
278 _, _, err := client.IssueImport.CheckStatusSince(ctx, "%", "r", Timestamp{time.Now()})
279 testURLParseError(t, err)
280 }
281
282 var issueImportResponseJSON = []byte(`{
283 "id": 3,
284 "status": "pending",
285 "url": "https://api.github.com/repos/o/r/import/issues/3",
286 "import_issues_url": "https://api.github.com/repos/o/r/import/issues",
287 "repository_url": "https://api.github.com/repos/o/r"
288 }`)
289
290 var wantIssueImportResponse = &IssueImportResponse{
291 ID: Int(3),
292 Status: String("pending"),
293 URL: String("https://api.github.com/repos/o/r/import/issues/3"),
294 ImportIssuesURL: String("https://api.github.com/repos/o/r/import/issues"),
295 RepositoryURL: String("https://api.github.com/repos/o/r"),
296 }
297
298 func TestIssueImportError_Marshal(t *testing.T) {
299 testJSONMarshal(t, &IssueImportError{}, "{}")
300
301 u := &IssueImportError{
302 Location: String("loc"),
303 Resource: String("res"),
304 Field: String("field"),
305 Value: String("value"),
306 Code: String("code"),
307 }
308
309 want := `{
310 "location": "loc",
311 "resource": "res",
312 "field": "field",
313 "value": "value",
314 "code": "code"
315 }`
316
317 testJSONMarshal(t, u, want)
318 }
319
320 func TestIssueImportResponse_Marshal(t *testing.T) {
321 testJSONMarshal(t, &IssueImportResponse{}, "{}")
322
323 u := &IssueImportResponse{
324 ID: Int(1),
325 Status: String("status"),
326 URL: String("url"),
327 ImportIssuesURL: String("iiu"),
328 RepositoryURL: String("ru"),
329 CreatedAt: &Timestamp{referenceTime},
330 UpdatedAt: &Timestamp{referenceTime},
331 Message: String("msg"),
332 DocumentationURL: String("durl"),
333 Errors: []*IssueImportError{
334 {
335 Location: String("loc"),
336 Resource: String("res"),
337 Field: String("field"),
338 Value: String("value"),
339 Code: String("code"),
340 },
341 },
342 }
343
344 want := `{
345 "id": 1,
346 "status": "status",
347 "url": "url",
348 "import_issues_url": "iiu",
349 "repository_url": "ru",
350 "created_at": ` + referenceTimeStr + `,
351 "updated_at": ` + referenceTimeStr + `,
352 "message": "msg",
353 "documentation_url": "durl",
354 "errors": [
355 {
356 "location": "loc",
357 "resource": "res",
358 "field": "field",
359 "value": "value",
360 "code": "code"
361 }
362 ]
363 }`
364
365 testJSONMarshal(t, u, want)
366 }
367
368 func TestComment_Marshal(t *testing.T) {
369 testJSONMarshal(t, &Comment{}, "{}")
370
371 u := &Comment{
372 CreatedAt: &Timestamp{referenceTime},
373 Body: "body",
374 }
375
376 want := `{
377 "created_at": ` + referenceTimeStr + `,
378 "body": "body"
379 }`
380
381 testJSONMarshal(t, u, want)
382 }
383
384 func TestIssueImport_Marshal(t *testing.T) {
385 testJSONMarshal(t, &IssueImport{}, "{}")
386
387 u := &IssueImport{
388 Title: "title",
389 Body: "body",
390 CreatedAt: &Timestamp{referenceTime},
391 ClosedAt: &Timestamp{referenceTime},
392 UpdatedAt: &Timestamp{referenceTime},
393 Assignee: String("a"),
394 Milestone: Int(1),
395 Closed: Bool(false),
396 Labels: []string{"l"},
397 }
398
399 want := `{
400 "title": "title",
401 "body": "body",
402 "created_at": ` + referenceTimeStr + `,
403 "closed_at": ` + referenceTimeStr + `,
404 "updated_at": ` + referenceTimeStr + `,
405 "assignee": "a",
406 "milestone": 1,
407 "closed": false,
408 "labels": [
409 "l"
410 ]
411 }`
412
413 testJSONMarshal(t, u, want)
414 }
415
416 func TestIssueImportRequest_Marshal(t *testing.T) {
417 testJSONMarshal(t, &IssueImportRequest{}, "{}")
418
419 u := &IssueImportRequest{
420 IssueImport: IssueImport{
421 Title: "title",
422 Body: "body",
423 CreatedAt: &Timestamp{referenceTime},
424 ClosedAt: &Timestamp{referenceTime},
425 UpdatedAt: &Timestamp{referenceTime},
426 Assignee: String("a"),
427 Milestone: Int(1),
428 Closed: Bool(false),
429 Labels: []string{"l"},
430 },
431 Comments: []*Comment{
432 {
433 CreatedAt: &Timestamp{referenceTime},
434 Body: "body",
435 },
436 },
437 }
438
439 want := `{
440 "issue": {
441 "title": "title",
442 "body": "body",
443 "created_at": ` + referenceTimeStr + `,
444 "closed_at": ` + referenceTimeStr + `,
445 "updated_at": ` + referenceTimeStr + `,
446 "assignee": "a",
447 "milestone": 1,
448 "closed": false,
449 "labels": [
450 "l"
451 ]
452 },
453 "comments": [
454 {
455 "created_at": ` + referenceTimeStr + `,
456 "body": "body"
457 }
458 ]
459 }`
460
461 testJSONMarshal(t, u, want)
462 }
463
View as plain text