github.com/google/go-github/v70@v70.0.0/github/issue_import_test.go (about) 1 // Copyright 2020 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 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 t.Parallel() 21 client, mux, _ := setup(t) 22 23 createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC) 24 input := &IssueImportRequest{ 25 IssueImport: IssueImport{ 26 Assignee: Ptr("developer"), 27 Body: "Dummy description", 28 CreatedAt: &Timestamp{createdAt}, 29 Labels: []string{"l1", "l2"}, 30 Milestone: Ptr(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 assertNilError(t, 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 assertWrite(t, w, 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_deferred(t *testing.T) { 78 t.Parallel() 79 client, mux, _ := setup(t) 80 81 createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC) 82 input := &IssueImportRequest{ 83 IssueImport: IssueImport{ 84 Assignee: Ptr("developer"), 85 Body: "Dummy description", 86 CreatedAt: &Timestamp{createdAt}, 87 Labels: []string{"l1", "l2"}, 88 Milestone: Ptr(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 assertNilError(t, 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 assertWrite(t, w, 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 t.Parallel() 125 client, mux, _ := setup(t) 126 127 createdAt := time.Date(2020, time.August, 11, 15, 30, 0, 0, time.UTC) 128 input := &IssueImportRequest{ 129 IssueImport: IssueImport{ 130 Assignee: Ptr("developer"), 131 Body: "Dummy description", 132 CreatedAt: &Timestamp{createdAt}, 133 Labels: []string{"l1", "l2"}, 134 Milestone: Ptr(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 assertNilError(t, 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 assertWrite(t, w, []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 t.Parallel() 166 client, _, _ := setup(t) 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 t.Parallel() 175 client, mux, _ := setup(t) 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 assertWrite(t, w, 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 t.Parallel() 212 client, _, _ := setup(t) 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 t.Parallel() 221 client, mux, _ := setup(t) 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 assertWrite(t, w, []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 t.Parallel() 258 client, mux, _ := setup(t) 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 assertWrite(t, w, []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 t.Parallel() 275 client, _, _ := setup(t) 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: Ptr(3), 292 Status: Ptr("pending"), 293 URL: Ptr("https://api.github.com/repos/o/r/import/issues/3"), 294 ImportIssuesURL: Ptr("https://api.github.com/repos/o/r/import/issues"), 295 RepositoryURL: Ptr("https://api.github.com/repos/o/r"), 296 } 297 298 func TestIssueImportError_Marshal(t *testing.T) { 299 t.Parallel() 300 testJSONMarshal(t, &IssueImportError{}, "{}") 301 302 u := &IssueImportError{ 303 Location: Ptr("loc"), 304 Resource: Ptr("res"), 305 Field: Ptr("field"), 306 Value: Ptr("value"), 307 Code: Ptr("code"), 308 } 309 310 want := `{ 311 "location": "loc", 312 "resource": "res", 313 "field": "field", 314 "value": "value", 315 "code": "code" 316 }` 317 318 testJSONMarshal(t, u, want) 319 } 320 321 func TestIssueImportResponse_Marshal(t *testing.T) { 322 t.Parallel() 323 testJSONMarshal(t, &IssueImportResponse{}, "{}") 324 325 u := &IssueImportResponse{ 326 ID: Ptr(1), 327 Status: Ptr("status"), 328 URL: Ptr("url"), 329 ImportIssuesURL: Ptr("iiu"), 330 RepositoryURL: Ptr("ru"), 331 CreatedAt: &Timestamp{referenceTime}, 332 UpdatedAt: &Timestamp{referenceTime}, 333 Message: Ptr("msg"), 334 DocumentationURL: Ptr("durl"), 335 Errors: []*IssueImportError{ 336 { 337 Location: Ptr("loc"), 338 Resource: Ptr("res"), 339 Field: Ptr("field"), 340 Value: Ptr("value"), 341 Code: Ptr("code"), 342 }, 343 }, 344 } 345 346 want := `{ 347 "id": 1, 348 "status": "status", 349 "url": "url", 350 "import_issues_url": "iiu", 351 "repository_url": "ru", 352 "created_at": ` + referenceTimeStr + `, 353 "updated_at": ` + referenceTimeStr + `, 354 "message": "msg", 355 "documentation_url": "durl", 356 "errors": [ 357 { 358 "location": "loc", 359 "resource": "res", 360 "field": "field", 361 "value": "value", 362 "code": "code" 363 } 364 ] 365 }` 366 367 testJSONMarshal(t, u, want) 368 } 369 370 func TestComment_Marshal(t *testing.T) { 371 t.Parallel() 372 testJSONMarshal(t, &Comment{}, "{}") 373 374 u := &Comment{ 375 CreatedAt: &Timestamp{referenceTime}, 376 Body: "body", 377 } 378 379 want := `{ 380 "created_at": ` + referenceTimeStr + `, 381 "body": "body" 382 }` 383 384 testJSONMarshal(t, u, want) 385 } 386 387 func TestIssueImport_Marshal(t *testing.T) { 388 t.Parallel() 389 testJSONMarshal(t, &IssueImport{}, "{}") 390 391 u := &IssueImport{ 392 Title: "title", 393 Body: "body", 394 CreatedAt: &Timestamp{referenceTime}, 395 ClosedAt: &Timestamp{referenceTime}, 396 UpdatedAt: &Timestamp{referenceTime}, 397 Assignee: Ptr("a"), 398 Milestone: Ptr(1), 399 Closed: Ptr(false), 400 Labels: []string{"l"}, 401 } 402 403 want := `{ 404 "title": "title", 405 "body": "body", 406 "created_at": ` + referenceTimeStr + `, 407 "closed_at": ` + referenceTimeStr + `, 408 "updated_at": ` + referenceTimeStr + `, 409 "assignee": "a", 410 "milestone": 1, 411 "closed": false, 412 "labels": [ 413 "l" 414 ] 415 }` 416 417 testJSONMarshal(t, u, want) 418 } 419 420 func TestIssueImportRequest_Marshal(t *testing.T) { 421 t.Parallel() 422 testJSONMarshal(t, &IssueImportRequest{}, "{}") 423 424 u := &IssueImportRequest{ 425 IssueImport: IssueImport{ 426 Title: "title", 427 Body: "body", 428 CreatedAt: &Timestamp{referenceTime}, 429 ClosedAt: &Timestamp{referenceTime}, 430 UpdatedAt: &Timestamp{referenceTime}, 431 Assignee: Ptr("a"), 432 Milestone: Ptr(1), 433 Closed: Ptr(false), 434 Labels: []string{"l"}, 435 }, 436 Comments: []*Comment{ 437 { 438 CreatedAt: &Timestamp{referenceTime}, 439 Body: "body", 440 }, 441 }, 442 } 443 444 want := `{ 445 "issue": { 446 "title": "title", 447 "body": "body", 448 "created_at": ` + referenceTimeStr + `, 449 "closed_at": ` + referenceTimeStr + `, 450 "updated_at": ` + referenceTimeStr + `, 451 "assignee": "a", 452 "milestone": 1, 453 "closed": false, 454 "labels": [ 455 "l" 456 ] 457 }, 458 "comments": [ 459 { 460 "created_at": ` + referenceTimeStr + `, 461 "body": "body" 462 } 463 ] 464 }` 465 466 testJSONMarshal(t, u, want) 467 }