github.com/google/go-github/v49@v49.1.0/github/repos_test.go (about) 1 // Copyright 2013 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 "errors" 12 "fmt" 13 "net/http" 14 "net/url" 15 "strings" 16 "testing" 17 18 "github.com/google/go-cmp/cmp" 19 ) 20 21 func TestRepositoriesService_List_authenticatedUser(t *testing.T) { 22 client, mux, _, teardown := setup() 23 defer teardown() 24 25 wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 26 mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { 27 testMethod(t, r, "GET") 28 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 29 fmt.Fprint(w, `[{"id":1},{"id":2}]`) 30 }) 31 32 ctx := context.Background() 33 got, _, err := client.Repositories.List(ctx, "", nil) 34 if err != nil { 35 t.Errorf("Repositories.List returned error: %v", err) 36 } 37 38 want := []*Repository{{ID: Int64(1)}, {ID: Int64(2)}} 39 if !cmp.Equal(got, want) { 40 t.Errorf("Repositories.List returned %+v, want %+v", got, want) 41 } 42 43 const methodName = "List" 44 testBadOptions(t, methodName, func() (err error) { 45 _, _, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{}) 46 return err 47 }) 48 49 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 50 got, resp, err := client.Repositories.List(ctx, "", nil) 51 if got != nil { 52 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 53 } 54 return resp, err 55 }) 56 } 57 58 func TestRepositoriesService_List_specifiedUser(t *testing.T) { 59 client, mux, _, teardown := setup() 60 defer teardown() 61 62 wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 63 mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) { 64 testMethod(t, r, "GET") 65 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 66 testFormValues(t, r, values{ 67 "visibility": "public", 68 "affiliation": "owner,collaborator", 69 "sort": "created", 70 "direction": "asc", 71 "page": "2", 72 }) 73 fmt.Fprint(w, `[{"id":1}]`) 74 }) 75 76 opt := &RepositoryListOptions{ 77 Visibility: "public", 78 Affiliation: "owner,collaborator", 79 Sort: "created", 80 Direction: "asc", 81 ListOptions: ListOptions{Page: 2}, 82 } 83 ctx := context.Background() 84 repos, _, err := client.Repositories.List(ctx, "u", opt) 85 if err != nil { 86 t.Errorf("Repositories.List returned error: %v", err) 87 } 88 89 want := []*Repository{{ID: Int64(1)}} 90 if !cmp.Equal(repos, want) { 91 t.Errorf("Repositories.List returned %+v, want %+v", repos, want) 92 } 93 } 94 95 func TestRepositoriesService_List_specifiedUser_type(t *testing.T) { 96 client, mux, _, teardown := setup() 97 defer teardown() 98 99 wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 100 mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) { 101 testMethod(t, r, "GET") 102 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 103 testFormValues(t, r, values{ 104 "type": "owner", 105 }) 106 fmt.Fprint(w, `[{"id":1}]`) 107 }) 108 109 opt := &RepositoryListOptions{ 110 Type: "owner", 111 } 112 ctx := context.Background() 113 repos, _, err := client.Repositories.List(ctx, "u", opt) 114 if err != nil { 115 t.Errorf("Repositories.List returned error: %v", err) 116 } 117 118 want := []*Repository{{ID: Int64(1)}} 119 if !cmp.Equal(repos, want) { 120 t.Errorf("Repositories.List returned %+v, want %+v", repos, want) 121 } 122 } 123 124 func TestRepositoriesService_List_invalidUser(t *testing.T) { 125 client, _, _, teardown := setup() 126 defer teardown() 127 128 ctx := context.Background() 129 _, _, err := client.Repositories.List(ctx, "%", nil) 130 testURLParseError(t, err) 131 } 132 133 func TestRepositoriesService_ListByOrg(t *testing.T) { 134 client, mux, _, teardown := setup() 135 defer teardown() 136 137 wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeRepositoryVisibilityPreview} 138 mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) { 139 testMethod(t, r, "GET") 140 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 141 testFormValues(t, r, values{ 142 "type": "forks", 143 "page": "2", 144 }) 145 fmt.Fprint(w, `[{"id":1}]`) 146 }) 147 148 ctx := context.Background() 149 opt := &RepositoryListByOrgOptions{ 150 Type: "forks", 151 ListOptions: ListOptions{Page: 2}, 152 } 153 got, _, err := client.Repositories.ListByOrg(ctx, "o", opt) 154 if err != nil { 155 t.Errorf("Repositories.ListByOrg returned error: %v", err) 156 } 157 158 want := []*Repository{{ID: Int64(1)}} 159 if !cmp.Equal(got, want) { 160 t.Errorf("Repositories.ListByOrg returned %+v, want %+v", got, want) 161 } 162 163 const methodName = "ListByOrg" 164 testBadOptions(t, methodName, func() (err error) { 165 _, _, err = client.Repositories.ListByOrg(ctx, "\n", opt) 166 return err 167 }) 168 169 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 170 got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt) 171 if got != nil { 172 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 173 } 174 return resp, err 175 }) 176 } 177 178 func TestRepositoriesService_ListByOrg_invalidOrg(t *testing.T) { 179 client, _, _, teardown := setup() 180 defer teardown() 181 182 ctx := context.Background() 183 _, _, err := client.Repositories.ListByOrg(ctx, "%", nil) 184 testURLParseError(t, err) 185 } 186 187 func TestRepositoriesService_ListAll(t *testing.T) { 188 client, mux, _, teardown := setup() 189 defer teardown() 190 191 mux.HandleFunc("/repositories", func(w http.ResponseWriter, r *http.Request) { 192 testMethod(t, r, "GET") 193 testFormValues(t, r, values{ 194 "since": "1", 195 }) 196 fmt.Fprint(w, `[{"id":1}]`) 197 }) 198 199 ctx := context.Background() 200 opt := &RepositoryListAllOptions{1} 201 got, _, err := client.Repositories.ListAll(ctx, opt) 202 if err != nil { 203 t.Errorf("Repositories.ListAll returned error: %v", err) 204 } 205 206 want := []*Repository{{ID: Int64(1)}} 207 if !cmp.Equal(got, want) { 208 t.Errorf("Repositories.ListAll returned %+v, want %+v", got, want) 209 } 210 211 const methodName = "ListAll" 212 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 213 got, resp, err := client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) 214 if got != nil { 215 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 216 } 217 return resp, err 218 }) 219 } 220 221 func TestRepositoriesService_Create_user(t *testing.T) { 222 client, mux, _, teardown := setup() 223 defer teardown() 224 225 input := &Repository{ 226 Name: String("n"), 227 Archived: Bool(true), // not passed along. 228 } 229 230 wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 231 mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { 232 v := new(createRepoRequest) 233 json.NewDecoder(r.Body).Decode(v) 234 235 testMethod(t, r, "POST") 236 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 237 want := &createRepoRequest{Name: String("n")} 238 if !cmp.Equal(v, want) { 239 t.Errorf("Request body = %+v, want %+v", v, want) 240 } 241 242 fmt.Fprint(w, `{"id":1}`) 243 }) 244 245 ctx := context.Background() 246 got, _, err := client.Repositories.Create(ctx, "", input) 247 if err != nil { 248 t.Errorf("Repositories.Create returned error: %v", err) 249 } 250 251 want := &Repository{ID: Int64(1)} 252 if !cmp.Equal(got, want) { 253 t.Errorf("Repositories.Create returned %+v, want %+v", got, want) 254 } 255 256 const methodName = "Create" 257 testBadOptions(t, methodName, func() (err error) { 258 _, _, err = client.Repositories.Create(ctx, "\n", input) 259 return err 260 }) 261 262 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 263 got, resp, err := client.Repositories.Create(ctx, "", input) 264 if got != nil { 265 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 266 } 267 return resp, err 268 }) 269 } 270 271 func TestRepositoriesService_Create_org(t *testing.T) { 272 client, mux, _, teardown := setup() 273 defer teardown() 274 275 input := &Repository{ 276 Name: String("n"), 277 Archived: Bool(true), // not passed along. 278 } 279 280 wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 281 mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) { 282 v := new(createRepoRequest) 283 json.NewDecoder(r.Body).Decode(v) 284 285 testMethod(t, r, "POST") 286 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 287 want := &createRepoRequest{Name: String("n")} 288 if !cmp.Equal(v, want) { 289 t.Errorf("Request body = %+v, want %+v", v, want) 290 } 291 292 fmt.Fprint(w, `{"id":1}`) 293 }) 294 295 ctx := context.Background() 296 repo, _, err := client.Repositories.Create(ctx, "o", input) 297 if err != nil { 298 t.Errorf("Repositories.Create returned error: %v", err) 299 } 300 301 want := &Repository{ID: Int64(1)} 302 if !cmp.Equal(repo, want) { 303 t.Errorf("Repositories.Create returned %+v, want %+v", repo, want) 304 } 305 } 306 307 func TestRepositoriesService_CreateFromTemplate(t *testing.T) { 308 client, mux, _, teardown := setup() 309 defer teardown() 310 311 templateRepoReq := &TemplateRepoRequest{ 312 Name: String("n"), 313 } 314 315 mux.HandleFunc("/repos/to/tr/generate", func(w http.ResponseWriter, r *http.Request) { 316 v := new(TemplateRepoRequest) 317 json.NewDecoder(r.Body).Decode(v) 318 319 testMethod(t, r, "POST") 320 testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) 321 want := &TemplateRepoRequest{Name: String("n")} 322 if !cmp.Equal(v, want) { 323 t.Errorf("Request body = %+v, want %+v", v, want) 324 } 325 326 fmt.Fprint(w, `{"id":1,"name":"n"}`) 327 }) 328 329 ctx := context.Background() 330 got, _, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) 331 if err != nil { 332 t.Errorf("Repositories.CreateFromTemplate returned error: %v", err) 333 } 334 335 want := &Repository{ID: Int64(1), Name: String("n")} 336 if !cmp.Equal(got, want) { 337 t.Errorf("Repositories.CreateFromTemplate returned %+v, want %+v", got, want) 338 } 339 340 const methodName = "CreateFromTemplate" 341 testBadOptions(t, methodName, func() (err error) { 342 _, _, err = client.Repositories.CreateFromTemplate(ctx, "\n", "\n", templateRepoReq) 343 return err 344 }) 345 346 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 347 got, resp, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) 348 if got != nil { 349 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 350 } 351 return resp, err 352 }) 353 } 354 355 func TestRepositoriesService_Get(t *testing.T) { 356 client, mux, _, teardown := setup() 357 defer teardown() 358 359 wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 360 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 361 testMethod(t, r, "GET") 362 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 363 fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"}}}`) 364 }) 365 366 ctx := context.Background() 367 got, _, err := client.Repositories.Get(ctx, "o", "r") 368 if err != nil { 369 t.Errorf("Repositories.Get returned error: %v", err) 370 } 371 372 want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{String("enabled")}}} 373 if !cmp.Equal(got, want) { 374 t.Errorf("Repositories.Get returned %+v, want %+v", got, want) 375 } 376 377 const methodName = "Get" 378 testBadOptions(t, methodName, func() (err error) { 379 _, _, err = client.Repositories.Get(ctx, "\n", "\n") 380 return err 381 }) 382 383 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 384 got, resp, err := client.Repositories.Get(ctx, "o", "r") 385 if got != nil { 386 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 387 } 388 return resp, err 389 }) 390 } 391 392 func TestRepositoriesService_GetCodeOfConduct(t *testing.T) { 393 client, mux, _, teardown := setup() 394 defer teardown() 395 396 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 397 testMethod(t, r, "GET") 398 testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview) 399 fmt.Fprint(w, `{ 400 "code_of_conduct": { 401 "key": "key", 402 "name": "name", 403 "url": "url", 404 "body": "body" 405 }}`, 406 ) 407 }) 408 409 ctx := context.Background() 410 got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") 411 if err != nil { 412 t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err) 413 } 414 415 want := &CodeOfConduct{ 416 Key: String("key"), 417 Name: String("name"), 418 URL: String("url"), 419 Body: String("body"), 420 } 421 422 if !cmp.Equal(got, want) { 423 t.Errorf("Repositories.GetCodeOfConduct returned %+v, want %+v", got, want) 424 } 425 426 const methodName = "GetCodeOfConduct" 427 testBadOptions(t, methodName, func() (err error) { 428 _, _, err = client.Repositories.GetCodeOfConduct(ctx, "\n", "\n") 429 return err 430 }) 431 432 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 433 got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") 434 if got != nil { 435 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 436 } 437 return resp, err 438 }) 439 } 440 441 func TestRepositoriesService_GetByID(t *testing.T) { 442 client, mux, _, teardown := setup() 443 defer teardown() 444 445 mux.HandleFunc("/repositories/1", func(w http.ResponseWriter, r *http.Request) { 446 testMethod(t, r, "GET") 447 fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`) 448 }) 449 450 ctx := context.Background() 451 got, _, err := client.Repositories.GetByID(ctx, 1) 452 if err != nil { 453 t.Fatalf("Repositories.GetByID returned error: %v", err) 454 } 455 456 want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}} 457 if !cmp.Equal(got, want) { 458 t.Errorf("Repositories.GetByID returned %+v, want %+v", got, want) 459 } 460 461 const methodName = "GetByID" 462 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 463 got, resp, err := client.Repositories.GetByID(ctx, 1) 464 if got != nil { 465 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 466 } 467 return resp, err 468 }) 469 } 470 471 func TestRepositoriesService_Edit(t *testing.T) { 472 client, mux, _, teardown := setup() 473 defer teardown() 474 475 i := true 476 input := &Repository{HasIssues: &i} 477 478 wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 479 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 480 v := new(Repository) 481 json.NewDecoder(r.Body).Decode(v) 482 483 testMethod(t, r, "PATCH") 484 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 485 if !cmp.Equal(v, input) { 486 t.Errorf("Request body = %+v, want %+v", v, input) 487 } 488 fmt.Fprint(w, `{"id":1}`) 489 }) 490 491 ctx := context.Background() 492 got, _, err := client.Repositories.Edit(ctx, "o", "r", input) 493 if err != nil { 494 t.Errorf("Repositories.Edit returned error: %v", err) 495 } 496 497 want := &Repository{ID: Int64(1)} 498 if !cmp.Equal(got, want) { 499 t.Errorf("Repositories.Edit returned %+v, want %+v", got, want) 500 } 501 502 const methodName = "Edit" 503 testBadOptions(t, methodName, func() (err error) { 504 _, _, err = client.Repositories.Edit(ctx, "\n", "\n", input) 505 return err 506 }) 507 508 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 509 got, resp, err := client.Repositories.Edit(ctx, "o", "r", input) 510 if got != nil { 511 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 512 } 513 return resp, err 514 }) 515 } 516 517 func TestRepositoriesService_Delete(t *testing.T) { 518 client, mux, _, teardown := setup() 519 defer teardown() 520 521 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 522 testMethod(t, r, "DELETE") 523 }) 524 525 ctx := context.Background() 526 _, err := client.Repositories.Delete(ctx, "o", "r") 527 if err != nil { 528 t.Errorf("Repositories.Delete returned error: %v", err) 529 } 530 531 const methodName = "Delete" 532 testBadOptions(t, methodName, func() (err error) { 533 _, err = client.Repositories.Delete(ctx, "\n", "\n") 534 return err 535 }) 536 537 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 538 return client.Repositories.Delete(ctx, "o", "r") 539 }) 540 } 541 542 func TestRepositoriesService_Get_invalidOwner(t *testing.T) { 543 client, _, _, teardown := setup() 544 defer teardown() 545 546 ctx := context.Background() 547 _, _, err := client.Repositories.Get(ctx, "%", "r") 548 testURLParseError(t, err) 549 } 550 551 func TestRepositoriesService_Edit_invalidOwner(t *testing.T) { 552 client, _, _, teardown := setup() 553 defer teardown() 554 555 ctx := context.Background() 556 _, _, err := client.Repositories.Edit(ctx, "%", "r", nil) 557 testURLParseError(t, err) 558 } 559 560 func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) { 561 client, mux, _, teardown := setup() 562 defer teardown() 563 564 mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { 565 testMethod(t, r, "GET") 566 testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 567 568 w.WriteHeader(http.StatusNoContent) 569 }) 570 571 ctx := context.Background() 572 vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r") 573 if err != nil { 574 t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err) 575 } 576 577 if want := true; vulnerabilityAlertsEnabled != want { 578 t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want) 579 } 580 581 const methodName = "GetVulnerabilityAlerts" 582 testBadOptions(t, methodName, func() (err error) { 583 _, _, err = client.Repositories.GetVulnerabilityAlerts(ctx, "\n", "\n") 584 return err 585 }) 586 587 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 588 got, resp, err := client.Repositories.GetVulnerabilityAlerts(ctx, "o", "r") 589 if got { 590 t.Errorf("testNewRequestAndDoFailure %v = %#v, want false", methodName, got) 591 } 592 return resp, err 593 }) 594 } 595 596 func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) { 597 client, mux, _, teardown := setup() 598 defer teardown() 599 600 mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { 601 testMethod(t, r, "PUT") 602 testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 603 604 w.WriteHeader(http.StatusNoContent) 605 }) 606 607 ctx := context.Background() 608 if _, err := client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r"); err != nil { 609 t.Errorf("Repositories.EnableVulnerabilityAlerts returned error: %v", err) 610 } 611 612 const methodName = "EnableVulnerabilityAlerts" 613 testBadOptions(t, methodName, func() (err error) { 614 _, err = client.Repositories.EnableVulnerabilityAlerts(ctx, "\n", "\n") 615 return err 616 }) 617 618 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 619 return client.Repositories.EnableVulnerabilityAlerts(ctx, "o", "r") 620 }) 621 } 622 623 func TestRepositoriesService_DisableVulnerabilityAlerts(t *testing.T) { 624 client, mux, _, teardown := setup() 625 defer teardown() 626 627 mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { 628 testMethod(t, r, "DELETE") 629 testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 630 631 w.WriteHeader(http.StatusNoContent) 632 }) 633 634 ctx := context.Background() 635 if _, err := client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r"); err != nil { 636 t.Errorf("Repositories.DisableVulnerabilityAlerts returned error: %v", err) 637 } 638 639 const methodName = "DisableVulnerabilityAlerts" 640 testBadOptions(t, methodName, func() (err error) { 641 _, err = client.Repositories.DisableVulnerabilityAlerts(ctx, "\n", "\n") 642 return err 643 }) 644 645 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 646 return client.Repositories.DisableVulnerabilityAlerts(ctx, "o", "r") 647 }) 648 } 649 650 func TestRepositoriesService_EnableAutomatedSecurityFixes(t *testing.T) { 651 client, mux, _, teardown := setup() 652 defer teardown() 653 654 mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { 655 testMethod(t, r, "PUT") 656 testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 657 658 w.WriteHeader(http.StatusNoContent) 659 }) 660 661 ctx := context.Background() 662 if _, err := client.Repositories.EnableAutomatedSecurityFixes(ctx, "o", "r"); err != nil { 663 t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err) 664 } 665 } 666 667 func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) { 668 client, mux, _, teardown := setup() 669 defer teardown() 670 671 mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { 672 testMethod(t, r, "DELETE") 673 testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 674 675 w.WriteHeader(http.StatusNoContent) 676 }) 677 678 ctx := context.Background() 679 if _, err := client.Repositories.DisableAutomatedSecurityFixes(ctx, "o", "r"); err != nil { 680 t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err) 681 } 682 } 683 684 func TestRepositoriesService_ListContributors(t *testing.T) { 685 client, mux, _, teardown := setup() 686 defer teardown() 687 688 mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) { 689 testMethod(t, r, "GET") 690 testFormValues(t, r, values{ 691 "anon": "true", 692 "page": "2", 693 }) 694 fmt.Fprint(w, `[{"contributions":42}]`) 695 }) 696 697 opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}} 698 ctx := context.Background() 699 contributors, _, err := client.Repositories.ListContributors(ctx, "o", "r", opts) 700 if err != nil { 701 t.Errorf("Repositories.ListContributors returned error: %v", err) 702 } 703 704 want := []*Contributor{{Contributions: Int(42)}} 705 if !cmp.Equal(contributors, want) { 706 t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want) 707 } 708 709 const methodName = "ListContributors" 710 testBadOptions(t, methodName, func() (err error) { 711 _, _, err = client.Repositories.ListContributors(ctx, "\n", "\n", opts) 712 return err 713 }) 714 715 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 716 got, resp, err := client.Repositories.ListContributors(ctx, "o", "r", opts) 717 if got != nil { 718 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 719 } 720 return resp, err 721 }) 722 } 723 724 func TestRepositoriesService_ListLanguages(t *testing.T) { 725 client, mux, _, teardown := setup() 726 defer teardown() 727 728 mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) { 729 testMethod(t, r, "GET") 730 fmt.Fprint(w, `{"go":1}`) 731 }) 732 733 ctx := context.Background() 734 languages, _, err := client.Repositories.ListLanguages(ctx, "o", "r") 735 if err != nil { 736 t.Errorf("Repositories.ListLanguages returned error: %v", err) 737 } 738 739 want := map[string]int{"go": 1} 740 if !cmp.Equal(languages, want) { 741 t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want) 742 } 743 744 const methodName = "ListLanguages" 745 testBadOptions(t, methodName, func() (err error) { 746 _, _, err = client.Repositories.ListLanguages(ctx, "\n", "\n") 747 return err 748 }) 749 750 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 751 got, resp, err := client.Repositories.ListLanguages(ctx, "o", "r") 752 if got != nil { 753 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 754 } 755 return resp, err 756 }) 757 } 758 759 func TestRepositoriesService_ListTeams(t *testing.T) { 760 client, mux, _, teardown := setup() 761 defer teardown() 762 763 mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) { 764 testMethod(t, r, "GET") 765 testFormValues(t, r, values{"page": "2"}) 766 fmt.Fprint(w, `[{"id":1}]`) 767 }) 768 769 opt := &ListOptions{Page: 2} 770 ctx := context.Background() 771 teams, _, err := client.Repositories.ListTeams(ctx, "o", "r", opt) 772 if err != nil { 773 t.Errorf("Repositories.ListTeams returned error: %v", err) 774 } 775 776 want := []*Team{{ID: Int64(1)}} 777 if !cmp.Equal(teams, want) { 778 t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want) 779 } 780 781 const methodName = "ListTeams" 782 testBadOptions(t, methodName, func() (err error) { 783 _, _, err = client.Repositories.ListTeams(ctx, "\n", "\n", opt) 784 return err 785 }) 786 787 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 788 got, resp, err := client.Repositories.ListTeams(ctx, "o", "r", opt) 789 if got != nil { 790 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 791 } 792 return resp, err 793 }) 794 } 795 796 func TestRepositoriesService_ListTags(t *testing.T) { 797 client, mux, _, teardown := setup() 798 defer teardown() 799 800 mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) { 801 testMethod(t, r, "GET") 802 testFormValues(t, r, values{"page": "2"}) 803 fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`) 804 }) 805 806 opt := &ListOptions{Page: 2} 807 ctx := context.Background() 808 tags, _, err := client.Repositories.ListTags(ctx, "o", "r", opt) 809 if err != nil { 810 t.Errorf("Repositories.ListTags returned error: %v", err) 811 } 812 813 want := []*RepositoryTag{ 814 { 815 Name: String("n"), 816 Commit: &Commit{ 817 SHA: String("s"), 818 URL: String("u"), 819 }, 820 ZipballURL: String("z"), 821 TarballURL: String("t"), 822 }, 823 } 824 if !cmp.Equal(tags, want) { 825 t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want) 826 } 827 828 const methodName = "ListTags" 829 testBadOptions(t, methodName, func() (err error) { 830 _, _, err = client.Repositories.ListTags(ctx, "\n", "\n", opt) 831 return err 832 }) 833 834 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 835 got, resp, err := client.Repositories.ListTags(ctx, "o", "r", opt) 836 if got != nil { 837 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 838 } 839 return resp, err 840 }) 841 } 842 843 func TestRepositoriesService_ListBranches(t *testing.T) { 844 client, mux, _, teardown := setup() 845 defer teardown() 846 847 mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) { 848 testMethod(t, r, "GET") 849 testFormValues(t, r, values{"page": "2"}) 850 fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`) 851 }) 852 853 opt := &BranchListOptions{ 854 Protected: nil, 855 ListOptions: ListOptions{Page: 2}, 856 } 857 ctx := context.Background() 858 branches, _, err := client.Repositories.ListBranches(ctx, "o", "r", opt) 859 if err != nil { 860 t.Errorf("Repositories.ListBranches returned error: %v", err) 861 } 862 863 want := []*Branch{{Name: String("master"), Commit: &RepositoryCommit{SHA: String("a57781"), URL: String("https://api.github.com/repos/o/r/commits/a57781")}}} 864 if !cmp.Equal(branches, want) { 865 t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want) 866 } 867 868 const methodName = "ListBranches" 869 testBadOptions(t, methodName, func() (err error) { 870 _, _, err = client.Repositories.ListBranches(ctx, "\n", "\n", opt) 871 return err 872 }) 873 874 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 875 got, resp, err := client.Repositories.ListBranches(ctx, "o", "r", opt) 876 if got != nil { 877 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 878 } 879 return resp, err 880 }) 881 } 882 883 func TestRepositoriesService_GetBranch(t *testing.T) { 884 client, mux, _, teardown := setup() 885 defer teardown() 886 887 mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { 888 testMethod(t, r, "GET") 889 fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`) 890 }) 891 892 ctx := context.Background() 893 branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b", false) 894 if err != nil { 895 t.Errorf("Repositories.GetBranch returned error: %v", err) 896 } 897 898 want := &Branch{ 899 Name: String("n"), 900 Commit: &RepositoryCommit{ 901 SHA: String("s"), 902 Commit: &Commit{ 903 Message: String("m"), 904 }, 905 }, 906 Protected: Bool(true), 907 } 908 909 if !cmp.Equal(branch, want) { 910 t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want) 911 } 912 913 const methodName = "GetBranch" 914 testBadOptions(t, methodName, func() (err error) { 915 _, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", false) 916 return err 917 }) 918 } 919 920 func TestRepositoriesService_GetBranch_BadJSONResponse(t *testing.T) { 921 client, mux, _, teardown := setup() 922 defer teardown() 923 924 mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { 925 testMethod(t, r, "GET") 926 fmt.Fprint(w, `{"name":"n", "commit":{"sha":...truncated`) 927 }) 928 929 ctx := context.Background() 930 if _, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b", false); err == nil { 931 t.Error("Repositories.GetBranch returned no error; wanted JSON error") 932 } 933 } 934 935 func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) { 936 client, mux, serverURL, teardown := setup() 937 defer teardown() 938 939 mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { 940 testMethod(t, r, "GET") 941 redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br") 942 http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) 943 }) 944 mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) { 945 testMethod(t, r, "GET") 946 fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`) 947 }) 948 ctx := context.Background() 949 branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true) 950 if err != nil { 951 t.Errorf("Repositories.GetBranch returned error: %v", err) 952 } 953 if resp.StatusCode != http.StatusOK { 954 t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK) 955 } 956 957 want := &Branch{ 958 Name: String("n"), 959 Commit: &RepositoryCommit{ 960 SHA: String("s"), 961 Commit: &Commit{ 962 Message: String("m"), 963 }, 964 }, 965 Protected: Bool(true), 966 } 967 if !cmp.Equal(branch, want) { 968 t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want) 969 } 970 } 971 972 func TestRepositoriesService_GetBranch_notFound(t *testing.T) { 973 client, mux, _, teardown := setup() 974 defer teardown() 975 976 mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { 977 testMethod(t, r, "GET") 978 http.Error(w, "branch not found", http.StatusNotFound) 979 }) 980 ctx := context.Background() 981 _, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true) 982 if err == nil { 983 t.Error("Repositories.GetBranch returned error: nil") 984 } 985 if resp.StatusCode != http.StatusNotFound { 986 t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound) 987 } 988 989 // Add custom round tripper 990 client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) { 991 return nil, errors.New("failed to get branch") 992 }) 993 994 const methodName = "GetBranch" 995 testBadOptions(t, methodName, func() (err error) { 996 _, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", true) 997 return err 998 }) 999 } 1000 1001 func TestRepositoriesService_RenameBranch(t *testing.T) { 1002 client, mux, _, teardown := setup() 1003 defer teardown() 1004 1005 renameBranchReq := "nn" 1006 1007 mux.HandleFunc("/repos/o/r/branches/b/rename", func(w http.ResponseWriter, r *http.Request) { 1008 v := new(renameBranchRequest) 1009 json.NewDecoder(r.Body).Decode(v) 1010 1011 testMethod(t, r, "POST") 1012 want := &renameBranchRequest{NewName: "nn"} 1013 if !cmp.Equal(v, want) { 1014 t.Errorf("Request body = %+v, want %+v", v, want) 1015 } 1016 1017 fmt.Fprint(w, `{"protected":true,"name":"nn"}`) 1018 }) 1019 1020 ctx := context.Background() 1021 got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq) 1022 if err != nil { 1023 t.Errorf("Repositories.RenameBranch returned error: %v", err) 1024 } 1025 1026 want := &Branch{Name: String("nn"), Protected: Bool(true)} 1027 if !cmp.Equal(got, want) { 1028 t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want) 1029 } 1030 1031 const methodName = "RenameBranch" 1032 testBadOptions(t, methodName, func() (err error) { 1033 _, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq) 1034 return err 1035 }) 1036 1037 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1038 got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq) 1039 if got != nil { 1040 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1041 } 1042 return resp, err 1043 }) 1044 } 1045 1046 func TestRepositoriesService_GetBranchProtection(t *testing.T) { 1047 client, mux, _, teardown := setup() 1048 defer teardown() 1049 1050 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1051 v := new(ProtectionRequest) 1052 json.NewDecoder(r.Body).Decode(v) 1053 1054 testMethod(t, r, "GET") 1055 // TODO: remove custom Accept header when this API fully launches 1056 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1057 fmt.Fprintf(w, `{ 1058 "required_status_checks":{ 1059 "strict":true, 1060 "contexts":["continuous-integration"], 1061 "checks": [ 1062 { 1063 "context": "continuous-integration", 1064 "app_id": null 1065 } 1066 ] 1067 }, 1068 "required_pull_request_reviews":{ 1069 "dismissal_restrictions":{ 1070 "users":[{ 1071 "id":3, 1072 "login":"u" 1073 }], 1074 "teams":[{ 1075 "id":4, 1076 "slug":"t" 1077 }], 1078 "apps":[{ 1079 "id":5, 1080 "slug":"a" 1081 }] 1082 }, 1083 "dismiss_stale_reviews":true, 1084 "require_code_owner_reviews":true, 1085 "required_approving_review_count":1 1086 }, 1087 "enforce_admins":{ 1088 "url":"/repos/o/r/branches/b/protection/enforce_admins", 1089 "enabled":true 1090 }, 1091 "restrictions":{ 1092 "users":[{"id":1,"login":"u"}], 1093 "teams":[{"id":2,"slug":"t"}], 1094 "apps":[{"id":3,"slug":"a"}] 1095 }, 1096 "required_conversation_resolution": { 1097 "enabled": true 1098 } 1099 }`) 1100 }) 1101 1102 ctx := context.Background() 1103 protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b") 1104 if err != nil { 1105 t.Errorf("Repositories.GetBranchProtection returned error: %v", err) 1106 } 1107 1108 want := &Protection{ 1109 RequiredStatusChecks: &RequiredStatusChecks{ 1110 Strict: true, 1111 Contexts: []string{"continuous-integration"}, 1112 Checks: []*RequiredStatusCheck{ 1113 { 1114 Context: "continuous-integration", 1115 }, 1116 }, 1117 }, 1118 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1119 DismissStaleReviews: true, 1120 DismissalRestrictions: &DismissalRestrictions{ 1121 Users: []*User{ 1122 {Login: String("u"), ID: Int64(3)}, 1123 }, 1124 Teams: []*Team{ 1125 {Slug: String("t"), ID: Int64(4)}, 1126 }, 1127 Apps: []*App{ 1128 {Slug: String("a"), ID: Int64(5)}, 1129 }, 1130 }, 1131 RequireCodeOwnerReviews: true, 1132 RequiredApprovingReviewCount: 1, 1133 }, 1134 EnforceAdmins: &AdminEnforcement{ 1135 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 1136 Enabled: true, 1137 }, 1138 Restrictions: &BranchRestrictions{ 1139 Users: []*User{ 1140 {Login: String("u"), ID: Int64(1)}, 1141 }, 1142 Teams: []*Team{ 1143 {Slug: String("t"), ID: Int64(2)}, 1144 }, 1145 Apps: []*App{ 1146 {Slug: String("a"), ID: Int64(3)}, 1147 }, 1148 }, 1149 RequiredConversationResolution: &RequiredConversationResolution{ 1150 Enabled: true, 1151 }, 1152 } 1153 if !cmp.Equal(protection, want) { 1154 t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) 1155 } 1156 1157 const methodName = "GetBranchProtection" 1158 testBadOptions(t, methodName, func() (err error) { 1159 _, _, err = client.Repositories.GetBranchProtection(ctx, "\n", "\n", "\n") 1160 return err 1161 }) 1162 1163 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1164 got, resp, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b") 1165 if got != nil { 1166 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1167 } 1168 return resp, err 1169 }) 1170 } 1171 1172 func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) { 1173 client, mux, _, teardown := setup() 1174 defer teardown() 1175 1176 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1177 testMethod(t, r, "GET") 1178 // TODO: remove custom Accept header when this API fully launches 1179 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1180 fmt.Fprintf(w, `{ 1181 "required_status_checks":{ 1182 "strict":true, 1183 "contexts":["continuous-integration"], 1184 "checks": [ 1185 { 1186 "context": "continuous-integration", 1187 "app_id": null 1188 } 1189 ] 1190 }, 1191 "required_pull_request_reviews":{ 1192 "dismiss_stale_reviews":true, 1193 "require_code_owner_reviews":true, 1194 "required_approving_review_count":1 1195 }, 1196 "enforce_admins":{ 1197 "url":"/repos/o/r/branches/b/protection/enforce_admins", 1198 "enabled":true 1199 }, 1200 "restrictions":{ 1201 "users":[{"id":1,"login":"u"}], 1202 "teams":[{"id":2,"slug":"t"}] 1203 } 1204 }`) 1205 }) 1206 1207 ctx := context.Background() 1208 protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b") 1209 if err != nil { 1210 t.Errorf("Repositories.GetBranchProtection returned error: %v", err) 1211 } 1212 1213 want := &Protection{ 1214 RequiredStatusChecks: &RequiredStatusChecks{ 1215 Strict: true, 1216 Contexts: []string{"continuous-integration"}, 1217 Checks: []*RequiredStatusCheck{ 1218 { 1219 Context: "continuous-integration", 1220 }, 1221 }, 1222 }, 1223 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1224 DismissStaleReviews: true, 1225 DismissalRestrictions: nil, 1226 RequireCodeOwnerReviews: true, 1227 RequiredApprovingReviewCount: 1, 1228 }, 1229 EnforceAdmins: &AdminEnforcement{ 1230 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 1231 Enabled: true, 1232 }, 1233 Restrictions: &BranchRestrictions{ 1234 Users: []*User{ 1235 {Login: String("u"), ID: Int64(1)}, 1236 }, 1237 Teams: []*Team{ 1238 {Slug: String("t"), ID: Int64(2)}, 1239 }, 1240 }, 1241 } 1242 if !cmp.Equal(protection, want) { 1243 t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) 1244 } 1245 } 1246 1247 func TestRepositoriesService_GetBranchProtection_branchNotProtected(t *testing.T) { 1248 client, mux, _, teardown := setup() 1249 defer teardown() 1250 1251 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1252 testMethod(t, r, "GET") 1253 1254 w.WriteHeader(http.StatusBadRequest) 1255 fmt.Fprintf(w, `{ 1256 "message": %q, 1257 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 1258 }`, githubBranchNotProtected) 1259 }) 1260 1261 ctx := context.Background() 1262 protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", "b") 1263 1264 if protection != nil { 1265 t.Errorf("Repositories.GetBranchProtection returned non-nil protection data") 1266 } 1267 1268 if err != ErrBranchNotProtected { 1269 t.Errorf("Repositories.GetBranchProtection returned an invalid error: %v", err) 1270 } 1271 } 1272 1273 func TestRepositoriesService_UpdateBranchProtection_Contexts(t *testing.T) { 1274 client, mux, _, teardown := setup() 1275 defer teardown() 1276 1277 input := &ProtectionRequest{ 1278 RequiredStatusChecks: &RequiredStatusChecks{ 1279 Strict: true, 1280 Contexts: []string{"continuous-integration"}, 1281 }, 1282 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1283 DismissStaleReviews: true, 1284 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1285 Users: &[]string{"uu"}, 1286 Teams: &[]string{"tt"}, 1287 Apps: &[]string{"aa"}, 1288 }, 1289 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1290 Users: []string{"uuu"}, 1291 Teams: []string{"ttt"}, 1292 Apps: []string{"aaa"}, 1293 }, 1294 }, 1295 Restrictions: &BranchRestrictionsRequest{ 1296 Users: []string{"u"}, 1297 Teams: []string{"t"}, 1298 Apps: []string{"a"}, 1299 }, 1300 } 1301 1302 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1303 v := new(ProtectionRequest) 1304 json.NewDecoder(r.Body).Decode(v) 1305 1306 testMethod(t, r, "PUT") 1307 if !cmp.Equal(v, input) { 1308 t.Errorf("Request body = %+v, want %+v", v, input) 1309 } 1310 1311 // TODO: remove custom Accept header when this API fully launches 1312 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1313 fmt.Fprintf(w, `{ 1314 "required_status_checks":{ 1315 "strict":true, 1316 "contexts":["continuous-integration"], 1317 "checks": [ 1318 { 1319 "context": "continuous-integration", 1320 "app_id": null 1321 } 1322 ] 1323 }, 1324 "required_pull_request_reviews":{ 1325 "dismissal_restrictions":{ 1326 "users":[{ 1327 "id":3, 1328 "login":"uu" 1329 }], 1330 "teams":[{ 1331 "id":4, 1332 "slug":"tt" 1333 }], 1334 "apps":[{ 1335 "id":5, 1336 "slug":"aa" 1337 }] 1338 }, 1339 "dismiss_stale_reviews":true, 1340 "require_code_owner_reviews":true, 1341 "bypass_pull_request_allowances": { 1342 "users":[{"id":10,"login":"uuu"}], 1343 "teams":[{"id":20,"slug":"ttt"}], 1344 "apps":[{"id":30,"slug":"aaa"}] 1345 } 1346 }, 1347 "restrictions":{ 1348 "users":[{"id":1,"login":"u"}], 1349 "teams":[{"id":2,"slug":"t"}], 1350 "apps":[{"id":3,"slug":"a"}] 1351 } 1352 }`) 1353 }) 1354 1355 ctx := context.Background() 1356 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input) 1357 if err != nil { 1358 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1359 } 1360 1361 want := &Protection{ 1362 RequiredStatusChecks: &RequiredStatusChecks{ 1363 Strict: true, 1364 Contexts: []string{"continuous-integration"}, 1365 Checks: []*RequiredStatusCheck{ 1366 { 1367 Context: "continuous-integration", 1368 }, 1369 }, 1370 }, 1371 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1372 DismissStaleReviews: true, 1373 DismissalRestrictions: &DismissalRestrictions{ 1374 Users: []*User{ 1375 {Login: String("uu"), ID: Int64(3)}, 1376 }, 1377 Teams: []*Team{ 1378 {Slug: String("tt"), ID: Int64(4)}, 1379 }, 1380 Apps: []*App{ 1381 {Slug: String("aa"), ID: Int64(5)}, 1382 }, 1383 }, 1384 RequireCodeOwnerReviews: true, 1385 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1386 Users: []*User{ 1387 {Login: String("uuu"), ID: Int64(10)}, 1388 }, 1389 Teams: []*Team{ 1390 {Slug: String("ttt"), ID: Int64(20)}, 1391 }, 1392 Apps: []*App{ 1393 {Slug: String("aaa"), ID: Int64(30)}, 1394 }, 1395 }, 1396 }, 1397 Restrictions: &BranchRestrictions{ 1398 Users: []*User{ 1399 {Login: String("u"), ID: Int64(1)}, 1400 }, 1401 Teams: []*Team{ 1402 {Slug: String("t"), ID: Int64(2)}, 1403 }, 1404 Apps: []*App{ 1405 {Slug: String("a"), ID: Int64(3)}, 1406 }, 1407 }, 1408 } 1409 if !cmp.Equal(protection, want) { 1410 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1411 } 1412 1413 const methodName = "UpdateBranchProtection" 1414 testBadOptions(t, methodName, func() (err error) { 1415 _, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input) 1416 return err 1417 }) 1418 1419 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1420 got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input) 1421 if got != nil { 1422 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1423 } 1424 return resp, err 1425 }) 1426 } 1427 1428 func TestRepositoriesService_UpdateBranchProtection_Checks(t *testing.T) { 1429 client, mux, _, teardown := setup() 1430 defer teardown() 1431 1432 input := &ProtectionRequest{ 1433 RequiredStatusChecks: &RequiredStatusChecks{ 1434 Strict: true, 1435 Checks: []*RequiredStatusCheck{ 1436 { 1437 Context: "continuous-integration", 1438 }, 1439 }, 1440 }, 1441 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1442 DismissStaleReviews: true, 1443 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1444 Users: &[]string{"uu"}, 1445 Teams: &[]string{"tt"}, 1446 Apps: &[]string{"aa"}, 1447 }, 1448 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1449 Users: []string{"uuu"}, 1450 Teams: []string{"ttt"}, 1451 Apps: []string{"aaa"}, 1452 }, 1453 }, 1454 Restrictions: &BranchRestrictionsRequest{ 1455 Users: []string{"u"}, 1456 Teams: []string{"t"}, 1457 Apps: []string{"a"}, 1458 }, 1459 } 1460 1461 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1462 v := new(ProtectionRequest) 1463 json.NewDecoder(r.Body).Decode(v) 1464 1465 testMethod(t, r, "PUT") 1466 if !cmp.Equal(v, input) { 1467 t.Errorf("Request body = %+v, want %+v", v, input) 1468 } 1469 1470 // TODO: remove custom Accept header when this API fully launches 1471 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1472 fmt.Fprintf(w, `{ 1473 "required_status_checks":{ 1474 "strict":true, 1475 "contexts":["continuous-integration"], 1476 "checks": [ 1477 { 1478 "context": "continuous-integration", 1479 "app_id": null 1480 } 1481 ] 1482 }, 1483 "required_pull_request_reviews":{ 1484 "dismissal_restrictions":{ 1485 "users":[{ 1486 "id":3, 1487 "login":"uu" 1488 }], 1489 "teams":[{ 1490 "id":4, 1491 "slug":"tt" 1492 }], 1493 "apps":[{ 1494 "id":5, 1495 "slug":"aa" 1496 }] 1497 }, 1498 "dismiss_stale_reviews":true, 1499 "require_code_owner_reviews":true, 1500 "bypass_pull_request_allowances": { 1501 "users":[{"id":10,"login":"uuu"}], 1502 "teams":[{"id":20,"slug":"ttt"}], 1503 "apps":[{"id":30,"slug":"aaa"}] 1504 } 1505 }, 1506 "restrictions":{ 1507 "users":[{"id":1,"login":"u"}], 1508 "teams":[{"id":2,"slug":"t"}], 1509 "apps":[{"id":3,"slug":"a"}] 1510 } 1511 }`) 1512 }) 1513 1514 ctx := context.Background() 1515 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input) 1516 if err != nil { 1517 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1518 } 1519 1520 want := &Protection{ 1521 RequiredStatusChecks: &RequiredStatusChecks{ 1522 Strict: true, 1523 Contexts: []string{"continuous-integration"}, 1524 Checks: []*RequiredStatusCheck{ 1525 { 1526 Context: "continuous-integration", 1527 }, 1528 }, 1529 }, 1530 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1531 DismissStaleReviews: true, 1532 DismissalRestrictions: &DismissalRestrictions{ 1533 Users: []*User{ 1534 {Login: String("uu"), ID: Int64(3)}, 1535 }, 1536 Teams: []*Team{ 1537 {Slug: String("tt"), ID: Int64(4)}, 1538 }, 1539 Apps: []*App{ 1540 {Slug: String("aa"), ID: Int64(5)}, 1541 }, 1542 }, 1543 RequireCodeOwnerReviews: true, 1544 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1545 Users: []*User{ 1546 {Login: String("uuu"), ID: Int64(10)}, 1547 }, 1548 Teams: []*Team{ 1549 {Slug: String("ttt"), ID: Int64(20)}, 1550 }, 1551 Apps: []*App{ 1552 {Slug: String("aaa"), ID: Int64(30)}, 1553 }, 1554 }, 1555 }, 1556 Restrictions: &BranchRestrictions{ 1557 Users: []*User{ 1558 {Login: String("u"), ID: Int64(1)}, 1559 }, 1560 Teams: []*Team{ 1561 {Slug: String("t"), ID: Int64(2)}, 1562 }, 1563 Apps: []*App{ 1564 {Slug: String("a"), ID: Int64(3)}, 1565 }, 1566 }, 1567 } 1568 if !cmp.Equal(protection, want) { 1569 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1570 } 1571 } 1572 1573 func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T) { 1574 client, mux, _, teardown := setup() 1575 defer teardown() 1576 1577 input := &ProtectionRequest{ 1578 RequiredStatusChecks: &RequiredStatusChecks{ 1579 Strict: true, 1580 Checks: []*RequiredStatusCheck{}, 1581 }, 1582 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1583 DismissStaleReviews: true, 1584 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1585 Users: &[]string{"uu"}, 1586 Teams: &[]string{"tt"}, 1587 Apps: &[]string{"aa"}, 1588 }, 1589 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1590 Users: []string{"uuu"}, 1591 Teams: []string{"ttt"}, 1592 Apps: []string{"aaa"}, 1593 }, 1594 }, 1595 Restrictions: &BranchRestrictionsRequest{ 1596 Users: []string{"u"}, 1597 Teams: []string{"t"}, 1598 Apps: []string{"a"}, 1599 }, 1600 } 1601 1602 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1603 v := new(ProtectionRequest) 1604 json.NewDecoder(r.Body).Decode(v) 1605 1606 testMethod(t, r, "PUT") 1607 if !cmp.Equal(v, input) { 1608 t.Errorf("Request body = %+v, want %+v", v, input) 1609 } 1610 1611 // TODO: remove custom Accept header when this API fully launches 1612 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1613 fmt.Fprintf(w, `{ 1614 "required_status_checks":{ 1615 "strict":true, 1616 "contexts":[], 1617 "checks": [] 1618 }, 1619 "required_pull_request_reviews":{ 1620 "dismissal_restrictions":{ 1621 "users":[{ 1622 "id":3, 1623 "login":"uu" 1624 }], 1625 "teams":[{ 1626 "id":4, 1627 "slug":"tt" 1628 }], 1629 "apps":[{ 1630 "id":5, 1631 "slug":"aa" 1632 }] 1633 }, 1634 "dismiss_stale_reviews":true, 1635 "require_code_owner_reviews":true, 1636 "bypass_pull_request_allowances": { 1637 "users":[{"id":10,"login":"uuu"}], 1638 "teams":[{"id":20,"slug":"ttt"}], 1639 "apps":[{"id":30,"slug":"aaa"}] 1640 } 1641 }, 1642 "restrictions":{ 1643 "users":[{"id":1,"login":"u"}], 1644 "teams":[{"id":2,"slug":"t"}], 1645 "apps":[{"id":3,"slug":"a"}] 1646 } 1647 }`) 1648 }) 1649 1650 ctx := context.Background() 1651 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input) 1652 if err != nil { 1653 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1654 } 1655 1656 want := &Protection{ 1657 RequiredStatusChecks: &RequiredStatusChecks{ 1658 Strict: true, 1659 Contexts: []string{}, 1660 Checks: []*RequiredStatusCheck{}, 1661 }, 1662 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1663 DismissStaleReviews: true, 1664 DismissalRestrictions: &DismissalRestrictions{ 1665 Users: []*User{ 1666 {Login: String("uu"), ID: Int64(3)}, 1667 }, 1668 Teams: []*Team{ 1669 {Slug: String("tt"), ID: Int64(4)}, 1670 }, 1671 Apps: []*App{ 1672 {Slug: String("aa"), ID: Int64(5)}, 1673 }, 1674 }, 1675 RequireCodeOwnerReviews: true, 1676 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1677 Users: []*User{ 1678 {Login: String("uuu"), ID: Int64(10)}, 1679 }, 1680 Teams: []*Team{ 1681 {Slug: String("ttt"), ID: Int64(20)}, 1682 }, 1683 Apps: []*App{ 1684 {Slug: String("aaa"), ID: Int64(30)}, 1685 }, 1686 }, 1687 }, 1688 Restrictions: &BranchRestrictions{ 1689 Users: []*User{ 1690 {Login: String("u"), ID: Int64(1)}, 1691 }, 1692 Teams: []*Team{ 1693 {Slug: String("t"), ID: Int64(2)}, 1694 }, 1695 Apps: []*App{ 1696 {Slug: String("a"), ID: Int64(3)}, 1697 }, 1698 }, 1699 } 1700 if !cmp.Equal(protection, want) { 1701 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1702 } 1703 } 1704 1705 func TestRepositoriesService_RemoveBranchProtection(t *testing.T) { 1706 client, mux, _, teardown := setup() 1707 defer teardown() 1708 1709 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1710 testMethod(t, r, "DELETE") 1711 w.WriteHeader(http.StatusNoContent) 1712 }) 1713 1714 ctx := context.Background() 1715 _, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", "b") 1716 if err != nil { 1717 t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err) 1718 } 1719 1720 const methodName = "RemoveBranchProtection" 1721 testBadOptions(t, methodName, func() (err error) { 1722 _, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n") 1723 return err 1724 }) 1725 1726 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1727 return client.Repositories.RemoveBranchProtection(ctx, "o", "r", "b") 1728 }) 1729 } 1730 1731 func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) { 1732 client, _, _, teardown := setup() 1733 defer teardown() 1734 1735 ctx := context.Background() 1736 _, _, err := client.Repositories.ListLanguages(ctx, "%", "%") 1737 testURLParseError(t, err) 1738 } 1739 1740 func TestRepositoriesService_License(t *testing.T) { 1741 client, mux, _, teardown := setup() 1742 defer teardown() 1743 1744 mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) { 1745 testMethod(t, r, "GET") 1746 fmt.Fprint(w, `{"name": "LICENSE", "path": "LICENSE", "license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","featured":true}}`) 1747 }) 1748 1749 ctx := context.Background() 1750 got, _, err := client.Repositories.License(ctx, "o", "r") 1751 if err != nil { 1752 t.Errorf("Repositories.License returned error: %v", err) 1753 } 1754 1755 want := &RepositoryLicense{ 1756 Name: String("LICENSE"), 1757 Path: String("LICENSE"), 1758 License: &License{ 1759 Name: String("MIT License"), 1760 Key: String("mit"), 1761 SPDXID: String("MIT"), 1762 URL: String("https://api.github.com/licenses/mit"), 1763 Featured: Bool(true), 1764 }, 1765 } 1766 1767 if !cmp.Equal(got, want) { 1768 t.Errorf("Repositories.License returned %+v, want %+v", got, want) 1769 } 1770 1771 const methodName = "License" 1772 testBadOptions(t, methodName, func() (err error) { 1773 _, _, err = client.Repositories.License(ctx, "\n", "\n") 1774 return err 1775 }) 1776 1777 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1778 got, resp, err := client.Repositories.License(ctx, "o", "r") 1779 if got != nil { 1780 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1781 } 1782 return resp, err 1783 }) 1784 } 1785 1786 func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) { 1787 client, mux, _, teardown := setup() 1788 defer teardown() 1789 1790 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 1791 v := new(ProtectionRequest) 1792 json.NewDecoder(r.Body).Decode(v) 1793 1794 testMethod(t, r, "GET") 1795 fmt.Fprint(w, `{ 1796 "strict": true, 1797 "contexts": ["x","y","z"], 1798 "checks": [ 1799 { 1800 "context": "x", 1801 "app_id": null 1802 }, 1803 { 1804 "context": "y", 1805 "app_id": null 1806 }, 1807 { 1808 "context": "z", 1809 "app_id": null 1810 } 1811 ] 1812 }`) 1813 }) 1814 1815 ctx := context.Background() 1816 checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b") 1817 if err != nil { 1818 t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err) 1819 } 1820 1821 want := &RequiredStatusChecks{ 1822 Strict: true, 1823 Contexts: []string{"x", "y", "z"}, 1824 Checks: []*RequiredStatusCheck{ 1825 { 1826 Context: "x", 1827 }, 1828 { 1829 Context: "y", 1830 }, 1831 { 1832 Context: "z", 1833 }, 1834 }, 1835 } 1836 if !cmp.Equal(checks, want) { 1837 t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want) 1838 } 1839 1840 const methodName = "GetRequiredStatusChecks" 1841 testBadOptions(t, methodName, func() (err error) { 1842 _, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n") 1843 return err 1844 }) 1845 1846 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1847 got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b") 1848 if got != nil { 1849 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1850 } 1851 return resp, err 1852 }) 1853 } 1854 1855 func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) { 1856 client, mux, _, teardown := setup() 1857 defer teardown() 1858 1859 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 1860 testMethod(t, r, "GET") 1861 1862 w.WriteHeader(http.StatusBadRequest) 1863 fmt.Fprintf(w, `{ 1864 "message": %q, 1865 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 1866 }`, githubBranchNotProtected) 1867 }) 1868 1869 ctx := context.Background() 1870 checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", "b") 1871 1872 if checks != nil { 1873 t.Errorf("Repositories.GetRequiredStatusChecks returned non-nil status-checks data") 1874 } 1875 1876 if err != ErrBranchNotProtected { 1877 t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err) 1878 } 1879 } 1880 1881 func TestRepositoriesService_UpdateRequiredStatusChecks_Contexts(t *testing.T) { 1882 client, mux, _, teardown := setup() 1883 defer teardown() 1884 1885 input := &RequiredStatusChecksRequest{ 1886 Strict: Bool(true), 1887 Contexts: []string{"continuous-integration"}, 1888 } 1889 1890 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 1891 v := new(RequiredStatusChecksRequest) 1892 json.NewDecoder(r.Body).Decode(v) 1893 1894 testMethod(t, r, "PATCH") 1895 if !cmp.Equal(v, input) { 1896 t.Errorf("Request body = %+v, want %+v", v, input) 1897 } 1898 testHeader(t, r, "Accept", mediaTypeV3) 1899 fmt.Fprintf(w, `{ 1900 "strict":true, 1901 "contexts":["continuous-integration"], 1902 "checks": [ 1903 { 1904 "context": "continuous-integration", 1905 "app_id": null 1906 } 1907 ] 1908 }`) 1909 }) 1910 1911 ctx := context.Background() 1912 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input) 1913 if err != nil { 1914 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 1915 } 1916 1917 want := &RequiredStatusChecks{ 1918 Strict: true, 1919 Contexts: []string{"continuous-integration"}, 1920 Checks: []*RequiredStatusCheck{ 1921 { 1922 Context: "continuous-integration", 1923 }, 1924 }, 1925 } 1926 if !cmp.Equal(statusChecks, want) { 1927 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 1928 } 1929 1930 const methodName = "UpdateRequiredStatusChecks" 1931 testBadOptions(t, methodName, func() (err error) { 1932 _, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input) 1933 return err 1934 }) 1935 1936 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1937 got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input) 1938 if got != nil { 1939 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1940 } 1941 return resp, err 1942 }) 1943 } 1944 1945 func TestRepositoriesService_UpdateRequiredStatusChecks_Checks(t *testing.T) { 1946 client, mux, _, teardown := setup() 1947 defer teardown() 1948 1949 appID := int64(123) 1950 noAppID := int64(-1) 1951 input := &RequiredStatusChecksRequest{ 1952 Strict: Bool(true), 1953 Checks: []*RequiredStatusCheck{ 1954 { 1955 Context: "continuous-integration", 1956 }, 1957 { 1958 Context: "continuous-integration2", 1959 AppID: &appID, 1960 }, 1961 { 1962 Context: "continuous-integration3", 1963 AppID: &noAppID, 1964 }, 1965 }, 1966 } 1967 1968 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 1969 v := new(RequiredStatusChecksRequest) 1970 json.NewDecoder(r.Body).Decode(v) 1971 1972 testMethod(t, r, "PATCH") 1973 if !cmp.Equal(v, input) { 1974 t.Errorf("Request body = %+v, want %+v", v, input) 1975 } 1976 testHeader(t, r, "Accept", mediaTypeV3) 1977 fmt.Fprintf(w, `{ 1978 "strict":true, 1979 "contexts":["continuous-integration"], 1980 "checks": [ 1981 { 1982 "context": "continuous-integration", 1983 "app_id": null 1984 }, 1985 { 1986 "context": "continuous-integration2", 1987 "app_id": 123 1988 }, 1989 { 1990 "context": "continuous-integration3", 1991 "app_id": null 1992 } 1993 ] 1994 }`) 1995 }) 1996 1997 ctx := context.Background() 1998 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", "b", input) 1999 if err != nil { 2000 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 2001 } 2002 2003 want := &RequiredStatusChecks{ 2004 Strict: true, 2005 Contexts: []string{"continuous-integration"}, 2006 Checks: []*RequiredStatusCheck{ 2007 { 2008 Context: "continuous-integration", 2009 }, 2010 { 2011 Context: "continuous-integration2", 2012 AppID: &appID, 2013 }, 2014 { 2015 Context: "continuous-integration3", 2016 }, 2017 }, 2018 } 2019 if !cmp.Equal(statusChecks, want) { 2020 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 2021 } 2022 } 2023 2024 func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) { 2025 client, mux, _, teardown := setup() 2026 defer teardown() 2027 2028 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 2029 testMethod(t, r, "DELETE") 2030 testHeader(t, r, "Accept", mediaTypeV3) 2031 w.WriteHeader(http.StatusNoContent) 2032 }) 2033 2034 ctx := context.Background() 2035 _, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", "b") 2036 if err != nil { 2037 t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err) 2038 } 2039 2040 const methodName = "RemoveRequiredStatusChecks" 2041 testBadOptions(t, methodName, func() (err error) { 2042 _, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n") 2043 return err 2044 }) 2045 2046 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2047 return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", "b") 2048 }) 2049 } 2050 2051 func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) { 2052 client, mux, _, teardown := setup() 2053 defer teardown() 2054 2055 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) { 2056 v := new(ProtectionRequest) 2057 json.NewDecoder(r.Body).Decode(v) 2058 2059 testMethod(t, r, "GET") 2060 fmt.Fprint(w, `["x", "y", "z"]`) 2061 }) 2062 2063 ctx := context.Background() 2064 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b") 2065 if err != nil { 2066 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err) 2067 } 2068 2069 want := []string{"x", "y", "z"} 2070 if !cmp.Equal(contexts, want) { 2071 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want) 2072 } 2073 2074 const methodName = "ListRequiredStatusChecksContexts" 2075 testBadOptions(t, methodName, func() (err error) { 2076 _, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n") 2077 return err 2078 }) 2079 2080 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2081 got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b") 2082 if got != nil { 2083 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2084 } 2085 return resp, err 2086 }) 2087 } 2088 2089 func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) { 2090 client, mux, _, teardown := setup() 2091 defer teardown() 2092 2093 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) { 2094 testMethod(t, r, "GET") 2095 2096 w.WriteHeader(http.StatusBadRequest) 2097 fmt.Fprintf(w, `{ 2098 "message": %q, 2099 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 2100 }`, githubBranchNotProtected) 2101 }) 2102 2103 ctx := context.Background() 2104 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", "b") 2105 2106 if contexts != nil { 2107 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data") 2108 } 2109 2110 if err != ErrBranchNotProtected { 2111 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err) 2112 } 2113 } 2114 2115 func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { 2116 client, mux, _, teardown := setup() 2117 defer teardown() 2118 2119 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 2120 testMethod(t, r, "GET") 2121 // TODO: remove custom Accept header when this API fully launches 2122 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2123 fmt.Fprintf(w, `{ 2124 "dismissal_restrictions":{ 2125 "users":[{"id":1,"login":"u"}], 2126 "teams":[{"id":2,"slug":"t"}], 2127 "apps":[{"id":3,"slug":"a"}] 2128 }, 2129 "dismiss_stale_reviews":true, 2130 "require_code_owner_reviews":true, 2131 "required_approving_review_count":1 2132 }`) 2133 }) 2134 2135 ctx := context.Background() 2136 enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", "b") 2137 if err != nil { 2138 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err) 2139 } 2140 2141 want := &PullRequestReviewsEnforcement{ 2142 DismissStaleReviews: true, 2143 DismissalRestrictions: &DismissalRestrictions{ 2144 Users: []*User{ 2145 {Login: String("u"), ID: Int64(1)}, 2146 }, 2147 Teams: []*Team{ 2148 {Slug: String("t"), ID: Int64(2)}, 2149 }, 2150 Apps: []*App{ 2151 {Slug: String("a"), ID: Int64(3)}, 2152 }, 2153 }, 2154 RequireCodeOwnerReviews: true, 2155 RequiredApprovingReviewCount: 1, 2156 } 2157 2158 if !cmp.Equal(enforcement, want) { 2159 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 2160 } 2161 2162 const methodName = "GetPullRequestReviewEnforcement" 2163 testBadOptions(t, methodName, func() (err error) { 2164 _, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n") 2165 return err 2166 }) 2167 2168 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2169 got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", "b") 2170 if got != nil { 2171 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2172 } 2173 return resp, err 2174 }) 2175 } 2176 2177 func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { 2178 client, mux, _, teardown := setup() 2179 defer teardown() 2180 2181 input := &PullRequestReviewsEnforcementUpdate{ 2182 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 2183 Users: &[]string{"u"}, 2184 Teams: &[]string{"t"}, 2185 Apps: &[]string{"a"}, 2186 }, 2187 } 2188 2189 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 2190 v := new(PullRequestReviewsEnforcementUpdate) 2191 json.NewDecoder(r.Body).Decode(v) 2192 2193 testMethod(t, r, "PATCH") 2194 if !cmp.Equal(v, input) { 2195 t.Errorf("Request body = %+v, want %+v", v, input) 2196 } 2197 // TODO: remove custom Accept header when this API fully launches 2198 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2199 fmt.Fprintf(w, `{ 2200 "dismissal_restrictions":{ 2201 "users":[{"id":1,"login":"u"}], 2202 "teams":[{"id":2,"slug":"t"}], 2203 "apps":[{"id":3,"slug":"a"}] 2204 }, 2205 "dismiss_stale_reviews":true, 2206 "require_code_owner_reviews":true, 2207 "required_approving_review_count":3 2208 }`) 2209 }) 2210 2211 ctx := context.Background() 2212 enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", "b", input) 2213 if err != nil { 2214 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err) 2215 } 2216 2217 want := &PullRequestReviewsEnforcement{ 2218 DismissStaleReviews: true, 2219 DismissalRestrictions: &DismissalRestrictions{ 2220 Users: []*User{ 2221 {Login: String("u"), ID: Int64(1)}, 2222 }, 2223 Teams: []*Team{ 2224 {Slug: String("t"), ID: Int64(2)}, 2225 }, 2226 Apps: []*App{ 2227 {Slug: String("a"), ID: Int64(3)}, 2228 }, 2229 }, 2230 RequireCodeOwnerReviews: true, 2231 RequiredApprovingReviewCount: 3, 2232 } 2233 if !cmp.Equal(enforcement, want) { 2234 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 2235 } 2236 2237 const methodName = "UpdatePullRequestReviewEnforcement" 2238 testBadOptions(t, methodName, func() (err error) { 2239 _, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input) 2240 return err 2241 }) 2242 2243 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2244 got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", "b", input) 2245 if got != nil { 2246 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2247 } 2248 return resp, err 2249 }) 2250 } 2251 2252 func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { 2253 client, mux, _, teardown := setup() 2254 defer teardown() 2255 2256 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 2257 testMethod(t, r, "PATCH") 2258 // TODO: remove custom Accept header when this API fully launches 2259 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2260 testBody(t, r, `{"dismissal_restrictions":{}}`+"\n") 2261 fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`) 2262 }) 2263 2264 ctx := context.Background() 2265 enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", "b") 2266 if err != nil { 2267 t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err) 2268 } 2269 2270 want := &PullRequestReviewsEnforcement{ 2271 DismissStaleReviews: true, 2272 DismissalRestrictions: nil, 2273 RequireCodeOwnerReviews: true, 2274 RequiredApprovingReviewCount: 1, 2275 } 2276 if !cmp.Equal(enforcement, want) { 2277 t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want) 2278 } 2279 2280 const methodName = "DisableDismissalRestrictions" 2281 testBadOptions(t, methodName, func() (err error) { 2282 _, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n") 2283 return err 2284 }) 2285 2286 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2287 got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", "b") 2288 if got != nil { 2289 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2290 } 2291 return resp, err 2292 }) 2293 } 2294 2295 func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { 2296 client, mux, _, teardown := setup() 2297 defer teardown() 2298 2299 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 2300 testMethod(t, r, "DELETE") 2301 w.WriteHeader(http.StatusNoContent) 2302 }) 2303 2304 ctx := context.Background() 2305 _, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", "b") 2306 if err != nil { 2307 t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err) 2308 } 2309 2310 const methodName = "RemovePullRequestReviewEnforcement" 2311 testBadOptions(t, methodName, func() (err error) { 2312 _, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n") 2313 return err 2314 }) 2315 2316 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2317 return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", "b") 2318 }) 2319 } 2320 2321 func TestRepositoriesService_GetAdminEnforcement(t *testing.T) { 2322 client, mux, _, teardown := setup() 2323 defer teardown() 2324 2325 mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { 2326 testMethod(t, r, "GET") 2327 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 2328 }) 2329 2330 ctx := context.Background() 2331 enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", "b") 2332 if err != nil { 2333 t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err) 2334 } 2335 2336 want := &AdminEnforcement{ 2337 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 2338 Enabled: true, 2339 } 2340 2341 if !cmp.Equal(enforcement, want) { 2342 t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want) 2343 } 2344 2345 const methodName = "GetAdminEnforcement" 2346 testBadOptions(t, methodName, func() (err error) { 2347 _, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n") 2348 return err 2349 }) 2350 2351 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2352 got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", "b") 2353 if got != nil { 2354 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2355 } 2356 return resp, err 2357 }) 2358 } 2359 2360 func TestRepositoriesService_AddAdminEnforcement(t *testing.T) { 2361 client, mux, _, teardown := setup() 2362 defer teardown() 2363 2364 mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { 2365 testMethod(t, r, "POST") 2366 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 2367 }) 2368 2369 ctx := context.Background() 2370 enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", "b") 2371 if err != nil { 2372 t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err) 2373 } 2374 2375 want := &AdminEnforcement{ 2376 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 2377 Enabled: true, 2378 } 2379 if !cmp.Equal(enforcement, want) { 2380 t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want) 2381 } 2382 2383 const methodName = "AddAdminEnforcement" 2384 testBadOptions(t, methodName, func() (err error) { 2385 _, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n") 2386 return err 2387 }) 2388 2389 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2390 got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", "b") 2391 if got != nil { 2392 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2393 } 2394 return resp, err 2395 }) 2396 } 2397 2398 func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) { 2399 client, mux, _, teardown := setup() 2400 defer teardown() 2401 2402 mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { 2403 testMethod(t, r, "DELETE") 2404 w.WriteHeader(http.StatusNoContent) 2405 }) 2406 2407 ctx := context.Background() 2408 _, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", "b") 2409 if err != nil { 2410 t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err) 2411 } 2412 2413 const methodName = "RemoveAdminEnforcement" 2414 testBadOptions(t, methodName, func() (err error) { 2415 _, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n") 2416 return err 2417 }) 2418 2419 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2420 return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", "b") 2421 }) 2422 } 2423 2424 func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) { 2425 client, mux, _, teardown := setup() 2426 defer teardown() 2427 2428 mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) { 2429 testMethod(t, r, "GET") 2430 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 2431 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`) 2432 }) 2433 2434 ctx := context.Background() 2435 signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", "b") 2436 if err != nil { 2437 t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err) 2438 } 2439 2440 want := &SignaturesProtectedBranch{ 2441 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 2442 Enabled: Bool(false), 2443 } 2444 2445 if !cmp.Equal(signature, want) { 2446 t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want) 2447 } 2448 2449 const methodName = "GetSignaturesProtectedBranch" 2450 testBadOptions(t, methodName, func() (err error) { 2451 _, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n") 2452 return err 2453 }) 2454 2455 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2456 got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", "b") 2457 if got != nil { 2458 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2459 } 2460 return resp, err 2461 }) 2462 } 2463 2464 func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) { 2465 client, mux, _, teardown := setup() 2466 defer teardown() 2467 2468 mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) { 2469 testMethod(t, r, "POST") 2470 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 2471 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`) 2472 }) 2473 2474 ctx := context.Background() 2475 signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", "b") 2476 if err != nil { 2477 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err) 2478 } 2479 2480 want := &SignaturesProtectedBranch{ 2481 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 2482 Enabled: Bool(true), 2483 } 2484 2485 if !cmp.Equal(signature, want) { 2486 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want) 2487 } 2488 2489 const methodName = "RequireSignaturesOnProtectedBranch" 2490 testBadOptions(t, methodName, func() (err error) { 2491 _, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n") 2492 return err 2493 }) 2494 2495 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2496 got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", "b") 2497 if got != nil { 2498 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2499 } 2500 return resp, err 2501 }) 2502 } 2503 2504 func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) { 2505 client, mux, _, teardown := setup() 2506 defer teardown() 2507 2508 mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) { 2509 testMethod(t, r, "DELETE") 2510 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 2511 w.WriteHeader(http.StatusNoContent) 2512 }) 2513 2514 ctx := context.Background() 2515 _, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", "b") 2516 if err != nil { 2517 t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err) 2518 } 2519 2520 const methodName = "OptionalSignaturesOnProtectedBranch" 2521 testBadOptions(t, methodName, func() (err error) { 2522 _, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n") 2523 return err 2524 }) 2525 2526 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2527 return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", "b") 2528 }) 2529 } 2530 2531 func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) { 2532 req := PullRequestReviewsEnforcementRequest{} 2533 2534 got, err := json.Marshal(req) 2535 if err != nil { 2536 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 2537 } 2538 2539 want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 2540 if want != string(got) { 2541 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 2542 } 2543 2544 req = PullRequestReviewsEnforcementRequest{ 2545 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{}, 2546 } 2547 2548 got, err = json.Marshal(req) 2549 if err != nil { 2550 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 2551 } 2552 2553 want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 2554 if want != string(got) { 2555 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 2556 } 2557 2558 req = PullRequestReviewsEnforcementRequest{ 2559 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 2560 Users: &[]string{}, 2561 Teams: &[]string{}, 2562 Apps: &[]string{}, 2563 }, 2564 } 2565 2566 got, err = json.Marshal(req) 2567 if err != nil { 2568 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 2569 } 2570 2571 want = `{"dismissal_restrictions":{"users":[],"teams":[],"apps":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 2572 if want != string(got) { 2573 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 2574 } 2575 } 2576 2577 func TestRepositoriesService_ListAllTopics(t *testing.T) { 2578 client, mux, _, teardown := setup() 2579 defer teardown() 2580 2581 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 2582 testMethod(t, r, "GET") 2583 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 2584 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 2585 }) 2586 2587 ctx := context.Background() 2588 got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r") 2589 if err != nil { 2590 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 2591 } 2592 2593 want := []string{"go", "go-github", "github"} 2594 if !cmp.Equal(got, want) { 2595 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 2596 } 2597 2598 const methodName = "ListAllTopics" 2599 testBadOptions(t, methodName, func() (err error) { 2600 _, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n") 2601 return err 2602 }) 2603 2604 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2605 got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r") 2606 if got != nil { 2607 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2608 } 2609 return resp, err 2610 }) 2611 } 2612 2613 func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) { 2614 client, mux, _, teardown := setup() 2615 defer teardown() 2616 2617 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 2618 testMethod(t, r, "GET") 2619 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 2620 fmt.Fprint(w, `{"names":[]}`) 2621 }) 2622 2623 ctx := context.Background() 2624 got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r") 2625 if err != nil { 2626 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 2627 } 2628 2629 want := []string{} 2630 if !cmp.Equal(got, want) { 2631 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 2632 } 2633 } 2634 2635 func TestRepositoriesService_ReplaceAllTopics(t *testing.T) { 2636 client, mux, _, teardown := setup() 2637 defer teardown() 2638 2639 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 2640 testMethod(t, r, "PUT") 2641 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 2642 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 2643 }) 2644 2645 ctx := context.Background() 2646 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"}) 2647 if err != nil { 2648 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 2649 } 2650 2651 want := []string{"go", "go-github", "github"} 2652 if !cmp.Equal(got, want) { 2653 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 2654 } 2655 2656 const methodName = "ReplaceAllTopics" 2657 testBadOptions(t, methodName, func() (err error) { 2658 _, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"}) 2659 return err 2660 }) 2661 2662 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2663 got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"}) 2664 if got != nil { 2665 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2666 } 2667 return resp, err 2668 }) 2669 } 2670 2671 func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) { 2672 client, mux, _, teardown := setup() 2673 defer teardown() 2674 2675 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 2676 testMethod(t, r, "PUT") 2677 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 2678 testBody(t, r, `{"names":[]}`+"\n") 2679 fmt.Fprint(w, `{"names":[]}`) 2680 }) 2681 2682 ctx := context.Background() 2683 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil) 2684 if err != nil { 2685 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 2686 } 2687 2688 want := []string{} 2689 if !cmp.Equal(got, want) { 2690 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 2691 } 2692 } 2693 2694 func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) { 2695 client, mux, _, teardown := setup() 2696 defer teardown() 2697 2698 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 2699 testMethod(t, r, "PUT") 2700 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 2701 testBody(t, r, `{"names":[]}`+"\n") 2702 fmt.Fprint(w, `{"names":[]}`) 2703 }) 2704 2705 ctx := context.Background() 2706 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{}) 2707 if err != nil { 2708 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 2709 } 2710 2711 want := []string{} 2712 if !cmp.Equal(got, want) { 2713 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 2714 } 2715 } 2716 2717 func TestRepositoriesService_ListApps(t *testing.T) { 2718 client, mux, _, teardown := setup() 2719 defer teardown() 2720 2721 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 2722 testMethod(t, r, "GET") 2723 }) 2724 2725 ctx := context.Background() 2726 _, _, err := client.Repositories.ListApps(ctx, "o", "r", "b") 2727 if err != nil { 2728 t.Errorf("Repositories.ListApps returned error: %v", err) 2729 } 2730 2731 const methodName = "ListApps" 2732 testBadOptions(t, methodName, func() (err error) { 2733 _, _, err = client.Repositories.ListApps(ctx, "\n", "\n", "\n") 2734 return err 2735 }) 2736 2737 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2738 got, resp, err := client.Repositories.ListApps(ctx, "o", "r", "b") 2739 if got != nil { 2740 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2741 } 2742 return resp, err 2743 }) 2744 } 2745 2746 func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) { 2747 client, mux, _, teardown := setup() 2748 defer teardown() 2749 2750 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 2751 testMethod(t, r, "PUT") 2752 fmt.Fprint(w, `[{ 2753 "name": "octocat" 2754 }]`) 2755 }) 2756 input := []string{"octocat"} 2757 ctx := context.Background() 2758 got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", "b", input) 2759 if err != nil { 2760 t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err) 2761 } 2762 want := []*App{ 2763 {Name: String("octocat")}, 2764 } 2765 if !cmp.Equal(got, want) { 2766 t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want) 2767 } 2768 2769 const methodName = "ReplaceAppRestrictions" 2770 testBadOptions(t, methodName, func() (err error) { 2771 _, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input) 2772 return err 2773 }) 2774 2775 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2776 got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", "b", input) 2777 if got != nil { 2778 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2779 } 2780 return resp, err 2781 }) 2782 } 2783 2784 func TestRepositoriesService_AddAppRestrictions(t *testing.T) { 2785 client, mux, _, teardown := setup() 2786 defer teardown() 2787 2788 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 2789 testMethod(t, r, "POST") 2790 fmt.Fprint(w, `[{ 2791 "name": "octocat" 2792 }]`) 2793 }) 2794 input := []string{"octocat"} 2795 ctx := context.Background() 2796 got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", "b", input) 2797 if err != nil { 2798 t.Errorf("Repositories.AddAppRestrictions returned error: %v", err) 2799 } 2800 want := []*App{ 2801 {Name: String("octocat")}, 2802 } 2803 if !cmp.Equal(got, want) { 2804 t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want) 2805 } 2806 2807 const methodName = "AddAppRestrictions" 2808 testBadOptions(t, methodName, func() (err error) { 2809 _, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input) 2810 return err 2811 }) 2812 2813 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2814 got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", "b", input) 2815 if got != nil { 2816 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2817 } 2818 return resp, err 2819 }) 2820 } 2821 2822 func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) { 2823 client, mux, _, teardown := setup() 2824 defer teardown() 2825 2826 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 2827 testMethod(t, r, "DELETE") 2828 fmt.Fprint(w, `[]`) 2829 }) 2830 input := []string{"octocat"} 2831 ctx := context.Background() 2832 got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", "b", input) 2833 if err != nil { 2834 t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err) 2835 } 2836 want := []*App{} 2837 if !cmp.Equal(got, want) { 2838 t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want) 2839 } 2840 2841 const methodName = "RemoveAppRestrictions" 2842 testBadOptions(t, methodName, func() (err error) { 2843 _, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input) 2844 return err 2845 }) 2846 2847 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2848 got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", "b", input) 2849 if got != nil { 2850 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2851 } 2852 return resp, err 2853 }) 2854 } 2855 2856 func TestRepositoriesService_Transfer(t *testing.T) { 2857 client, mux, _, teardown := setup() 2858 defer teardown() 2859 2860 input := TransferRequest{NewOwner: "a", TeamID: []int64{123}} 2861 2862 mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) { 2863 var v TransferRequest 2864 json.NewDecoder(r.Body).Decode(&v) 2865 2866 testMethod(t, r, "POST") 2867 if !cmp.Equal(v, input) { 2868 t.Errorf("Request body = %+v, want %+v", v, input) 2869 } 2870 2871 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 2872 }) 2873 2874 ctx := context.Background() 2875 got, _, err := client.Repositories.Transfer(ctx, "o", "r", input) 2876 if err != nil { 2877 t.Errorf("Repositories.Transfer returned error: %v", err) 2878 } 2879 2880 want := &Repository{Owner: &User{Login: String("a")}} 2881 if !cmp.Equal(got, want) { 2882 t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want) 2883 } 2884 2885 const methodName = "Transfer" 2886 testBadOptions(t, methodName, func() (err error) { 2887 _, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input) 2888 return err 2889 }) 2890 2891 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2892 got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input) 2893 if got != nil { 2894 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2895 } 2896 return resp, err 2897 }) 2898 } 2899 2900 func TestRepositoriesService_Dispatch(t *testing.T) { 2901 client, mux, _, teardown := setup() 2902 defer teardown() 2903 2904 var input DispatchRequestOptions 2905 2906 mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) { 2907 var v DispatchRequestOptions 2908 json.NewDecoder(r.Body).Decode(&v) 2909 2910 testMethod(t, r, "POST") 2911 if !cmp.Equal(v, input) { 2912 t.Errorf("Request body = %+v, want %+v", v, input) 2913 } 2914 2915 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 2916 }) 2917 2918 ctx := context.Background() 2919 2920 testCases := []interface{}{ 2921 nil, 2922 struct { 2923 Foo string 2924 }{ 2925 Foo: "test", 2926 }, 2927 struct { 2928 Bar int 2929 }{ 2930 Bar: 42, 2931 }, 2932 struct { 2933 Foo string 2934 Bar int 2935 Baz bool 2936 }{ 2937 Foo: "test", 2938 Bar: 42, 2939 Baz: false, 2940 }, 2941 } 2942 2943 for _, tc := range testCases { 2944 if tc == nil { 2945 input = DispatchRequestOptions{EventType: "go"} 2946 } else { 2947 bytes, _ := json.Marshal(tc) 2948 payload := json.RawMessage(bytes) 2949 input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload} 2950 } 2951 2952 got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input) 2953 if err != nil { 2954 t.Errorf("Repositories.Dispatch returned error: %v", err) 2955 } 2956 2957 want := &Repository{Owner: &User{Login: String("a")}} 2958 if !cmp.Equal(got, want) { 2959 t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want) 2960 } 2961 } 2962 2963 const methodName = "Dispatch" 2964 testBadOptions(t, methodName, func() (err error) { 2965 _, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input) 2966 return err 2967 }) 2968 2969 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2970 got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input) 2971 if got != nil { 2972 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2973 } 2974 return resp, err 2975 }) 2976 } 2977 2978 func TestAdvancedSecurity_Marshal(t *testing.T) { 2979 testJSONMarshal(t, &AdvancedSecurity{}, "{}") 2980 2981 u := &AdvancedSecurity{ 2982 Status: String("status"), 2983 } 2984 2985 want := `{ 2986 "status": "status" 2987 }` 2988 2989 testJSONMarshal(t, u, want) 2990 } 2991 2992 func TestAuthorizedActorsOnly_Marshal(t *testing.T) { 2993 testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}") 2994 2995 u := &AuthorizedActorsOnly{ 2996 From: Bool(true), 2997 } 2998 2999 want := `{ 3000 "from" : true 3001 }` 3002 3003 testJSONMarshal(t, u, want) 3004 } 3005 3006 func TestDispatchRequestOptions_Marshal(t *testing.T) { 3007 testJSONMarshal(t, &DispatchRequestOptions{}, "{}") 3008 3009 cp := json.RawMessage(`{"testKey":"testValue"}`) 3010 u := &DispatchRequestOptions{ 3011 EventType: "test_event_type", 3012 ClientPayload: &cp, 3013 } 3014 3015 want := `{ 3016 "event_type": "test_event_type", 3017 "client_payload": { 3018 "testKey": "testValue" 3019 } 3020 }` 3021 3022 testJSONMarshal(t, u, want) 3023 } 3024 3025 func TestTransferRequest_Marshal(t *testing.T) { 3026 testJSONMarshal(t, &TransferRequest{}, "{}") 3027 3028 u := &TransferRequest{ 3029 NewOwner: "testOwner", 3030 TeamID: []int64{1, 2}, 3031 } 3032 3033 want := `{ 3034 "new_owner": "testOwner", 3035 "team_ids": [1,2] 3036 }` 3037 3038 testJSONMarshal(t, u, want) 3039 } 3040 3041 func TestSignaturesProtectedBranch_Marshal(t *testing.T) { 3042 testJSONMarshal(t, &SignaturesProtectedBranch{}, "{}") 3043 3044 u := &SignaturesProtectedBranch{ 3045 URL: String("https://www.testURL.in"), 3046 Enabled: Bool(false), 3047 } 3048 3049 want := `{ 3050 "url": "https://www.testURL.in", 3051 "enabled": false 3052 }` 3053 3054 testJSONMarshal(t, u, want) 3055 3056 u2 := &SignaturesProtectedBranch{ 3057 URL: String("testURL"), 3058 Enabled: Bool(true), 3059 } 3060 3061 want2 := `{ 3062 "url": "testURL", 3063 "enabled": true 3064 }` 3065 3066 testJSONMarshal(t, u2, want2) 3067 } 3068 3069 func TestDismissalRestrictionsRequest_Marshal(t *testing.T) { 3070 testJSONMarshal(t, &DismissalRestrictionsRequest{}, "{}") 3071 3072 u := &DismissalRestrictionsRequest{ 3073 Users: &[]string{"user1", "user2"}, 3074 Teams: &[]string{"team1", "team2"}, 3075 Apps: &[]string{"app1", "app2"}, 3076 } 3077 3078 want := `{ 3079 "users": ["user1","user2"], 3080 "teams": ["team1","team2"], 3081 "apps": ["app1","app2"] 3082 }` 3083 3084 testJSONMarshal(t, u, want) 3085 } 3086 3087 func TestAdminEnforcement_Marshal(t *testing.T) { 3088 testJSONMarshal(t, &AdminEnforcement{}, "{}") 3089 3090 u := &AdminEnforcement{ 3091 URL: String("https://www.test-url.in"), 3092 Enabled: false, 3093 } 3094 3095 want := `{ 3096 "url": "https://www.test-url.in", 3097 "enabled": false 3098 }` 3099 3100 testJSONMarshal(t, u, want) 3101 } 3102 3103 func TestPullRequestReviewsEnforcementUpdate_Marshal(t *testing.T) { 3104 testJSONMarshal(t, &PullRequestReviewsEnforcementUpdate{}, "{}") 3105 3106 u := &PullRequestReviewsEnforcementUpdate{ 3107 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 3108 Users: []string{"user1", "user2"}, 3109 Teams: []string{"team1", "team2"}, 3110 Apps: []string{"app1", "app2"}, 3111 }, 3112 DismissStaleReviews: Bool(false), 3113 RequireCodeOwnerReviews: Bool(true), 3114 RequiredApprovingReviewCount: 2, 3115 } 3116 3117 want := `{ 3118 "bypass_pull_request_allowances": { 3119 "users": ["user1","user2"], 3120 "teams": ["team1","team2"], 3121 "apps": ["app1","app2"] 3122 }, 3123 "dismiss_stale_reviews": false, 3124 "require_code_owner_reviews": true, 3125 "required_approving_review_count": 2 3126 }` 3127 3128 testJSONMarshal(t, u, want) 3129 } 3130 3131 func TestRequiredStatusCheck_Marshal(t *testing.T) { 3132 testJSONMarshal(t, &RequiredStatusCheck{}, "{}") 3133 3134 u := &RequiredStatusCheck{ 3135 Context: "ctx", 3136 AppID: Int64(1), 3137 } 3138 3139 want := `{ 3140 "context": "ctx", 3141 "app_id": 1 3142 }` 3143 3144 testJSONMarshal(t, u, want) 3145 }