github.com/google/go-github/v60@v60.0.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_ListByAuthenticatedUser(t *testing.T) { 22 client, mux, _, teardown := setup() 23 defer teardown() 24 25 mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { 26 testMethod(t, r, "GET") 27 fmt.Fprint(w, `[{"id":1},{"id":2}]`) 28 }) 29 30 ctx := context.Background() 31 got, _, err := client.Repositories.ListByAuthenticatedUser(ctx, nil) 32 if err != nil { 33 t.Errorf("Repositories.List returned error: %v", err) 34 } 35 36 want := []*Repository{{ID: Int64(1)}, {ID: Int64(2)}} 37 if !cmp.Equal(got, want) { 38 t.Errorf("Repositories.ListByAuthenticatedUser returned %+v, want %+v", got, want) 39 } 40 41 const methodName = "ListByAuthenticatedUser" 42 43 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 44 got, resp, err := client.Repositories.ListByAuthenticatedUser(ctx, nil) 45 if got != nil { 46 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 47 } 48 return resp, err 49 }) 50 } 51 52 func TestRepositoriesService_ListByUser(t *testing.T) { 53 client, mux, _, teardown := setup() 54 defer teardown() 55 56 mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) { 57 testMethod(t, r, "GET") 58 testFormValues(t, r, values{ 59 "sort": "created", 60 "direction": "asc", 61 "page": "2", 62 }) 63 fmt.Fprint(w, `[{"id":1}]`) 64 }) 65 66 opt := &RepositoryListByUserOptions{ 67 Sort: "created", 68 Direction: "asc", 69 ListOptions: ListOptions{Page: 2}, 70 } 71 ctx := context.Background() 72 repos, _, err := client.Repositories.ListByUser(ctx, "u", opt) 73 if err != nil { 74 t.Errorf("Repositories.List returned error: %v", err) 75 } 76 77 want := []*Repository{{ID: Int64(1)}} 78 if !cmp.Equal(repos, want) { 79 t.Errorf("Repositories.ListByUser returned %+v, want %+v", repos, want) 80 } 81 82 const methodName = "ListByUser" 83 testBadOptions(t, methodName, func() (err error) { 84 _, _, err = client.Repositories.ListByUser(ctx, "\n", &RepositoryListByUserOptions{}) 85 return err 86 }) 87 88 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 89 got, resp, err := client.Repositories.ListByUser(ctx, "u", nil) 90 if got != nil { 91 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 92 } 93 return resp, err 94 }) 95 } 96 97 func TestRepositoriesService_ListByUser_type(t *testing.T) { 98 client, mux, _, teardown := setup() 99 defer teardown() 100 101 mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) { 102 testMethod(t, r, "GET") 103 testFormValues(t, r, values{ 104 "type": "owner", 105 }) 106 fmt.Fprint(w, `[{"id":1}]`) 107 }) 108 109 opt := &RepositoryListByUserOptions{ 110 Type: "owner", 111 } 112 ctx := context.Background() 113 repos, _, err := client.Repositories.ListByUser(ctx, "u", opt) 114 if err != nil { 115 t.Errorf("Repositories.ListByUser returned error: %v", err) 116 } 117 118 want := []*Repository{{ID: Int64(1)}} 119 if !cmp.Equal(repos, want) { 120 t.Errorf("Repositories.ListByUser returned %+v, want %+v", repos, want) 121 } 122 } 123 124 func TestRepositoriesService_ListByUser_invalidUser(t *testing.T) { 125 client, _, _, teardown := setup() 126 defer teardown() 127 128 ctx := context.Background() 129 _, _, err := client.Repositories.ListByUser(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 assertNilError(t, 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 assertNilError(t, 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 assertNilError(t, 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"},"dependabot_security_updates":{"status": "enabled"}, "secret_scanning_validity_checks":{"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")}, DependabotSecurityUpdates: &DependabotSecurityUpdates{String("enabled")}, SecretScanningValidityChecks: &SecretScanningValidityChecks{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 assertNilError(t, 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 657 w.WriteHeader(http.StatusNoContent) 658 }) 659 660 ctx := context.Background() 661 if _, err := client.Repositories.EnableAutomatedSecurityFixes(ctx, "o", "r"); err != nil { 662 t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err) 663 } 664 } 665 666 func TestRepositoriesService_GetAutomatedSecurityFixes(t *testing.T) { 667 client, mux, _, teardown := setup() 668 defer teardown() 669 670 mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { 671 testMethod(t, r, "GET") 672 fmt.Fprint(w, `{"enabled": true, "paused": false}`) 673 }) 674 675 ctx := context.Background() 676 fixes, _, err := client.Repositories.GetAutomatedSecurityFixes(ctx, "o", "r") 677 if err != nil { 678 t.Errorf("Repositories.GetAutomatedSecurityFixes returned errpr: #{err}") 679 } 680 681 want := &AutomatedSecurityFixes{ 682 Enabled: Bool(true), 683 Paused: Bool(false), 684 } 685 if !cmp.Equal(fixes, want) { 686 t.Errorf("Repositories.GetAutomatedSecurityFixes returned #{fixes}, want #{want}") 687 } 688 689 const methodName = "GetAutomatedSecurityFixes" 690 testBadOptions(t, methodName, func() (err error) { 691 _, _, err = client.Repositories.GetAutomatedSecurityFixes(ctx, "\n", "\n") 692 return err 693 }) 694 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 695 got, resp, err := client.Repositories.GetAutomatedSecurityFixes(ctx, "o", "r") 696 if got != nil { 697 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 698 } 699 return resp, err 700 }) 701 } 702 703 func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) { 704 client, mux, _, teardown := setup() 705 defer teardown() 706 707 mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { 708 testMethod(t, r, "DELETE") 709 710 w.WriteHeader(http.StatusNoContent) 711 }) 712 713 ctx := context.Background() 714 if _, err := client.Repositories.DisableAutomatedSecurityFixes(ctx, "o", "r"); err != nil { 715 t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err) 716 } 717 } 718 719 func TestRepositoriesService_ListContributors(t *testing.T) { 720 client, mux, _, teardown := setup() 721 defer teardown() 722 723 mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) { 724 testMethod(t, r, "GET") 725 testFormValues(t, r, values{ 726 "anon": "true", 727 "page": "2", 728 }) 729 fmt.Fprint(w, `[{"contributions":42}]`) 730 }) 731 732 opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}} 733 ctx := context.Background() 734 contributors, _, err := client.Repositories.ListContributors(ctx, "o", "r", opts) 735 if err != nil { 736 t.Errorf("Repositories.ListContributors returned error: %v", err) 737 } 738 739 want := []*Contributor{{Contributions: Int(42)}} 740 if !cmp.Equal(contributors, want) { 741 t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want) 742 } 743 744 const methodName = "ListContributors" 745 testBadOptions(t, methodName, func() (err error) { 746 _, _, err = client.Repositories.ListContributors(ctx, "\n", "\n", opts) 747 return err 748 }) 749 750 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 751 got, resp, err := client.Repositories.ListContributors(ctx, "o", "r", opts) 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_ListLanguages(t *testing.T) { 760 client, mux, _, teardown := setup() 761 defer teardown() 762 763 mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) { 764 testMethod(t, r, "GET") 765 fmt.Fprint(w, `{"go":1}`) 766 }) 767 768 ctx := context.Background() 769 languages, _, err := client.Repositories.ListLanguages(ctx, "o", "r") 770 if err != nil { 771 t.Errorf("Repositories.ListLanguages returned error: %v", err) 772 } 773 774 want := map[string]int{"go": 1} 775 if !cmp.Equal(languages, want) { 776 t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want) 777 } 778 779 const methodName = "ListLanguages" 780 testBadOptions(t, methodName, func() (err error) { 781 _, _, err = client.Repositories.ListLanguages(ctx, "\n", "\n") 782 return err 783 }) 784 785 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 786 got, resp, err := client.Repositories.ListLanguages(ctx, "o", "r") 787 if got != nil { 788 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 789 } 790 return resp, err 791 }) 792 } 793 794 func TestRepositoriesService_ListTeams(t *testing.T) { 795 client, mux, _, teardown := setup() 796 defer teardown() 797 798 mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) { 799 testMethod(t, r, "GET") 800 testFormValues(t, r, values{"page": "2"}) 801 fmt.Fprint(w, `[{"id":1}]`) 802 }) 803 804 opt := &ListOptions{Page: 2} 805 ctx := context.Background() 806 teams, _, err := client.Repositories.ListTeams(ctx, "o", "r", opt) 807 if err != nil { 808 t.Errorf("Repositories.ListTeams returned error: %v", err) 809 } 810 811 want := []*Team{{ID: Int64(1)}} 812 if !cmp.Equal(teams, want) { 813 t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want) 814 } 815 816 const methodName = "ListTeams" 817 testBadOptions(t, methodName, func() (err error) { 818 _, _, err = client.Repositories.ListTeams(ctx, "\n", "\n", opt) 819 return err 820 }) 821 822 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 823 got, resp, err := client.Repositories.ListTeams(ctx, "o", "r", opt) 824 if got != nil { 825 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 826 } 827 return resp, err 828 }) 829 } 830 831 func TestRepositoriesService_ListTags(t *testing.T) { 832 client, mux, _, teardown := setup() 833 defer teardown() 834 835 mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) { 836 testMethod(t, r, "GET") 837 testFormValues(t, r, values{"page": "2"}) 838 fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`) 839 }) 840 841 opt := &ListOptions{Page: 2} 842 ctx := context.Background() 843 tags, _, err := client.Repositories.ListTags(ctx, "o", "r", opt) 844 if err != nil { 845 t.Errorf("Repositories.ListTags returned error: %v", err) 846 } 847 848 want := []*RepositoryTag{ 849 { 850 Name: String("n"), 851 Commit: &Commit{ 852 SHA: String("s"), 853 URL: String("u"), 854 }, 855 ZipballURL: String("z"), 856 TarballURL: String("t"), 857 }, 858 } 859 if !cmp.Equal(tags, want) { 860 t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want) 861 } 862 863 const methodName = "ListTags" 864 testBadOptions(t, methodName, func() (err error) { 865 _, _, err = client.Repositories.ListTags(ctx, "\n", "\n", opt) 866 return err 867 }) 868 869 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 870 got, resp, err := client.Repositories.ListTags(ctx, "o", "r", opt) 871 if got != nil { 872 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 873 } 874 return resp, err 875 }) 876 } 877 878 func TestRepositoriesService_ListBranches(t *testing.T) { 879 client, mux, _, teardown := setup() 880 defer teardown() 881 882 mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) { 883 testMethod(t, r, "GET") 884 testFormValues(t, r, values{"page": "2"}) 885 fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`) 886 }) 887 888 opt := &BranchListOptions{ 889 Protected: nil, 890 ListOptions: ListOptions{Page: 2}, 891 } 892 ctx := context.Background() 893 branches, _, err := client.Repositories.ListBranches(ctx, "o", "r", opt) 894 if err != nil { 895 t.Errorf("Repositories.ListBranches returned error: %v", err) 896 } 897 898 want := []*Branch{{Name: String("master"), Commit: &RepositoryCommit{SHA: String("a57781"), URL: String("https://api.github.com/repos/o/r/commits/a57781")}}} 899 if !cmp.Equal(branches, want) { 900 t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want) 901 } 902 903 const methodName = "ListBranches" 904 testBadOptions(t, methodName, func() (err error) { 905 _, _, err = client.Repositories.ListBranches(ctx, "\n", "\n", opt) 906 return err 907 }) 908 909 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 910 got, resp, err := client.Repositories.ListBranches(ctx, "o", "r", opt) 911 if got != nil { 912 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 913 } 914 return resp, err 915 }) 916 } 917 918 func TestRepositoriesService_GetBranch(t *testing.T) { 919 client, mux, _, teardown := setup() 920 defer teardown() 921 922 tests := []struct { 923 branch string 924 urlPath string 925 }{ 926 {branch: "b", urlPath: "/repos/o/r/branches/b"}, 927 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%"}, 928 } 929 930 for _, test := range tests { 931 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 932 testMethod(t, r, "GET") 933 fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`) 934 }) 935 936 ctx := context.Background() 937 branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 0) 938 if err != nil { 939 t.Errorf("Repositories.GetBranch returned error: %v", err) 940 } 941 942 want := &Branch{ 943 Name: String("n"), 944 Commit: &RepositoryCommit{ 945 SHA: String("s"), 946 Commit: &Commit{ 947 Message: String("m"), 948 }, 949 }, 950 Protected: Bool(true), 951 } 952 953 if !cmp.Equal(branch, want) { 954 t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want) 955 } 956 957 const methodName = "GetBranch" 958 testBadOptions(t, methodName, func() (err error) { 959 _, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", 0) 960 return err 961 }) 962 } 963 } 964 965 func TestRepositoriesService_GetBranch_BadJSONResponse(t *testing.T) { 966 tests := []struct { 967 branch string 968 urlPath string 969 }{ 970 {branch: "b", urlPath: "/repos/o/r/branches/b"}, 971 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%"}, 972 } 973 974 for _, test := range tests { 975 t.Run(test.branch, func(t *testing.T) { 976 client, mux, _, teardown := setup() 977 defer teardown() 978 979 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 980 testMethod(t, r, "GET") 981 fmt.Fprint(w, `{"name":"n", "commit":{"sha":...truncated`) 982 }) 983 984 ctx := context.Background() 985 if _, _, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 0); err == nil { 986 t.Error("Repositories.GetBranch returned no error; wanted JSON error") 987 } 988 }) 989 } 990 } 991 992 func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) { 993 client, mux, serverURL, teardown := setup() 994 defer teardown() 995 996 mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { 997 testMethod(t, r, "GET") 998 redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br") 999 http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) 1000 }) 1001 mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) { 1002 testMethod(t, r, "GET") 1003 fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`) 1004 }) 1005 ctx := context.Background() 1006 branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", 1) 1007 if err != nil { 1008 t.Errorf("Repositories.GetBranch returned error: %v", err) 1009 } 1010 if resp.StatusCode != http.StatusOK { 1011 t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK) 1012 } 1013 1014 want := &Branch{ 1015 Name: String("n"), 1016 Commit: &RepositoryCommit{ 1017 SHA: String("s"), 1018 Commit: &Commit{ 1019 Message: String("m"), 1020 }, 1021 }, 1022 Protected: Bool(true), 1023 } 1024 if !cmp.Equal(branch, want) { 1025 t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want) 1026 } 1027 } 1028 1029 func TestRepositoriesService_GetBranch_notFound(t *testing.T) { 1030 tests := []struct { 1031 branch string 1032 urlPath string 1033 }{ 1034 {branch: "b", urlPath: "/repos/o/r/branches/b"}, 1035 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat-branch-50%"}, 1036 } 1037 1038 for _, test := range tests { 1039 t.Run(test.branch, func(t *testing.T) { 1040 client, mux, _, teardown := setup() 1041 defer teardown() 1042 1043 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1044 testMethod(t, r, "GET") 1045 http.Error(w, "branch not found", http.StatusNotFound) 1046 }) 1047 ctx := context.Background() 1048 _, resp, err := client.Repositories.GetBranch(ctx, "o", "r", test.branch, 1) 1049 if err == nil { 1050 t.Error("Repositories.GetBranch returned error: nil") 1051 } 1052 if resp.StatusCode != http.StatusNotFound { 1053 t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound) 1054 } 1055 1056 // Add custom round tripper 1057 client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) { 1058 return nil, errors.New("failed to get branch") 1059 }) 1060 1061 const methodName = "GetBranch" 1062 testBadOptions(t, methodName, func() (err error) { 1063 _, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", 1) 1064 return err 1065 }) 1066 }) 1067 } 1068 } 1069 1070 func TestRepositoriesService_RenameBranch(t *testing.T) { 1071 tests := []struct { 1072 branch string 1073 urlPath string 1074 }{ 1075 {branch: "b", urlPath: "/repos/o/r/branches/b/rename"}, 1076 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/rename"}, 1077 } 1078 1079 for _, test := range tests { 1080 t.Run(test.branch, func(t *testing.T) { 1081 client, mux, _, teardown := setup() 1082 defer teardown() 1083 1084 renameBranchReq := "nn" 1085 1086 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1087 v := new(renameBranchRequest) 1088 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1089 1090 testMethod(t, r, "POST") 1091 want := &renameBranchRequest{NewName: renameBranchReq} 1092 if !cmp.Equal(v, want) { 1093 t.Errorf("Request body = %+v, want %+v", v, want) 1094 } 1095 1096 fmt.Fprint(w, `{"protected":true,"name":"nn"}`) 1097 }) 1098 1099 ctx := context.Background() 1100 got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", test.branch, renameBranchReq) 1101 if err != nil { 1102 t.Errorf("Repositories.RenameBranch returned error: %v", err) 1103 } 1104 1105 want := &Branch{Name: String("nn"), Protected: Bool(true)} 1106 if !cmp.Equal(got, want) { 1107 t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want) 1108 } 1109 1110 const methodName = "RenameBranch" 1111 testBadOptions(t, methodName, func() (err error) { 1112 _, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq) 1113 return err 1114 }) 1115 1116 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1117 got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", test.branch, renameBranchReq) 1118 if got != nil { 1119 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1120 } 1121 return resp, err 1122 }) 1123 }) 1124 } 1125 } 1126 1127 func TestRepositoriesService_GetBranchProtection(t *testing.T) { 1128 tests := []struct { 1129 branch string 1130 urlPath string 1131 enforceAdminsURLPath string 1132 }{ 1133 {branch: "b", urlPath: "/repos/o/r/branches/b/protection", enforceAdminsURLPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 1134 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection", enforceAdminsURLPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 1135 } 1136 1137 for _, test := range tests { 1138 t.Run(test.branch, func(t *testing.T) { 1139 client, mux, _, teardown := setup() 1140 defer teardown() 1141 1142 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1143 testMethod(t, r, "GET") 1144 // TODO: remove custom Accept header when this API fully launches 1145 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1146 fmt.Fprintf(w, `{ 1147 "required_status_checks":{ 1148 "strict":true, 1149 "contexts":["continuous-integration"], 1150 "checks": [ 1151 { 1152 "context": "continuous-integration", 1153 "app_id": null 1154 } 1155 ] 1156 }, 1157 "required_pull_request_reviews":{ 1158 "dismissal_restrictions":{ 1159 "users":[{ 1160 "id":3, 1161 "login":"u" 1162 }], 1163 "teams":[{ 1164 "id":4, 1165 "slug":"t" 1166 }], 1167 "apps":[{ 1168 "id":5, 1169 "slug":"a" 1170 }] 1171 }, 1172 "dismiss_stale_reviews":true, 1173 "require_code_owner_reviews":true, 1174 "require_last_push_approval":false, 1175 "required_approving_review_count":1 1176 }, 1177 "enforce_admins":{ 1178 "url":"%s", 1179 "enabled":true 1180 }, 1181 "restrictions":{ 1182 "users":[{"id":1,"login":"u"}], 1183 "teams":[{"id":2,"slug":"t"}], 1184 "apps":[{"id":3,"slug":"a"}] 1185 }, 1186 "required_conversation_resolution": { 1187 "enabled": true 1188 }, 1189 "block_creations": { 1190 "enabled": false 1191 }, 1192 "lock_branch": { 1193 "enabled": false 1194 }, 1195 "allow_fork_syncing": { 1196 "enabled": false 1197 } 1198 }`, test.enforceAdminsURLPath) 1199 }) 1200 1201 ctx := context.Background() 1202 protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch) 1203 if err != nil { 1204 t.Errorf("Repositories.GetBranchProtection returned error: %v", err) 1205 } 1206 1207 want := &Protection{ 1208 RequiredStatusChecks: &RequiredStatusChecks{ 1209 Strict: true, 1210 Contexts: &[]string{"continuous-integration"}, 1211 Checks: &[]*RequiredStatusCheck{ 1212 { 1213 Context: "continuous-integration", 1214 }, 1215 }, 1216 }, 1217 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1218 DismissStaleReviews: true, 1219 DismissalRestrictions: &DismissalRestrictions{ 1220 Users: []*User{ 1221 {Login: String("u"), ID: Int64(3)}, 1222 }, 1223 Teams: []*Team{ 1224 {Slug: String("t"), ID: Int64(4)}, 1225 }, 1226 Apps: []*App{ 1227 {Slug: String("a"), ID: Int64(5)}, 1228 }, 1229 }, 1230 RequireCodeOwnerReviews: true, 1231 RequiredApprovingReviewCount: 1, 1232 RequireLastPushApproval: false, 1233 }, 1234 EnforceAdmins: &AdminEnforcement{ 1235 URL: String(test.enforceAdminsURLPath), 1236 Enabled: true, 1237 }, 1238 Restrictions: &BranchRestrictions{ 1239 Users: []*User{ 1240 {Login: String("u"), ID: Int64(1)}, 1241 }, 1242 Teams: []*Team{ 1243 {Slug: String("t"), ID: Int64(2)}, 1244 }, 1245 Apps: []*App{ 1246 {Slug: String("a"), ID: Int64(3)}, 1247 }, 1248 }, 1249 RequiredConversationResolution: &RequiredConversationResolution{ 1250 Enabled: true, 1251 }, 1252 BlockCreations: &BlockCreations{ 1253 Enabled: Bool(false), 1254 }, 1255 LockBranch: &LockBranch{ 1256 Enabled: Bool(false), 1257 }, 1258 AllowForkSyncing: &AllowForkSyncing{ 1259 Enabled: Bool(false), 1260 }, 1261 } 1262 if !cmp.Equal(protection, want) { 1263 t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) 1264 } 1265 1266 const methodName = "GetBranchProtection" 1267 testBadOptions(t, methodName, func() (err error) { 1268 _, _, err = client.Repositories.GetBranchProtection(ctx, "\n", "\n", "\n") 1269 return err 1270 }) 1271 1272 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1273 got, resp, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch) 1274 if got != nil { 1275 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1276 } 1277 return resp, err 1278 }) 1279 }) 1280 } 1281 } 1282 1283 func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) { 1284 client, mux, _, teardown := setup() 1285 defer teardown() 1286 1287 tests := []struct { 1288 branch string 1289 urlPath string 1290 enforceAdminsURLPath string 1291 }{ 1292 {branch: "b", urlPath: "/repos/o/r/branches/b/protection", enforceAdminsURLPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 1293 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection", enforceAdminsURLPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 1294 } 1295 1296 for _, test := range tests { 1297 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1298 testMethod(t, r, "GET") 1299 // TODO: remove custom Accept header when this API fully launches 1300 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1301 fmt.Fprintf(w, `{ 1302 "required_status_checks":{ 1303 "strict":true, 1304 "contexts":["continuous-integration"], 1305 "checks": [ 1306 { 1307 "context": "continuous-integration", 1308 "app_id": null 1309 } 1310 ] 1311 }, 1312 "required_pull_request_reviews":{ 1313 "dismiss_stale_reviews":true, 1314 "require_code_owner_reviews":true, 1315 "required_approving_review_count":1 1316 }, 1317 "enforce_admins":{ 1318 "url":"%s", 1319 "enabled":true 1320 }, 1321 "restrictions":{ 1322 "users":[{"id":1,"login":"u"}], 1323 "teams":[{"id":2,"slug":"t"}] 1324 } 1325 }`, test.enforceAdminsURLPath) 1326 }) 1327 1328 ctx := context.Background() 1329 protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch) 1330 if err != nil { 1331 t.Errorf("Repositories.GetBranchProtection returned error: %v", err) 1332 } 1333 1334 want := &Protection{ 1335 RequiredStatusChecks: &RequiredStatusChecks{ 1336 Strict: true, 1337 Contexts: &[]string{"continuous-integration"}, 1338 Checks: &[]*RequiredStatusCheck{ 1339 { 1340 Context: "continuous-integration", 1341 }, 1342 }, 1343 }, 1344 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1345 DismissStaleReviews: true, 1346 DismissalRestrictions: nil, 1347 RequireCodeOwnerReviews: true, 1348 RequiredApprovingReviewCount: 1, 1349 }, 1350 EnforceAdmins: &AdminEnforcement{ 1351 URL: String(test.enforceAdminsURLPath), 1352 Enabled: true, 1353 }, 1354 Restrictions: &BranchRestrictions{ 1355 Users: []*User{ 1356 {Login: String("u"), ID: Int64(1)}, 1357 }, 1358 Teams: []*Team{ 1359 {Slug: String("t"), ID: Int64(2)}, 1360 }, 1361 }, 1362 } 1363 if !cmp.Equal(protection, want) { 1364 t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) 1365 } 1366 } 1367 } 1368 1369 func TestRepositoriesService_GetBranchProtection_branchNotProtected(t *testing.T) { 1370 tests := []struct { 1371 branch string 1372 urlPath string 1373 }{ 1374 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1375 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1376 } 1377 1378 for _, test := range tests { 1379 t.Run(test.branch, func(t *testing.T) { 1380 client, mux, _, teardown := setup() 1381 defer teardown() 1382 1383 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1384 testMethod(t, r, "GET") 1385 1386 w.WriteHeader(http.StatusBadRequest) 1387 fmt.Fprintf(w, `{ 1388 "message": %q, 1389 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 1390 }`, githubBranchNotProtected) 1391 }) 1392 1393 ctx := context.Background() 1394 protection, _, err := client.Repositories.GetBranchProtection(ctx, "o", "r", test.branch) 1395 1396 if protection != nil { 1397 t.Errorf("Repositories.GetBranchProtection returned non-nil protection data") 1398 } 1399 1400 if err != ErrBranchNotProtected { 1401 t.Errorf("Repositories.GetBranchProtection returned an invalid error: %v", err) 1402 } 1403 }) 1404 } 1405 } 1406 1407 func TestRepositoriesService_UpdateBranchProtection_Contexts(t *testing.T) { 1408 tests := []struct { 1409 branch string 1410 urlPath string 1411 }{ 1412 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1413 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1414 } 1415 1416 for _, test := range tests { 1417 t.Run(test.branch, func(t *testing.T) { 1418 client, mux, _, teardown := setup() 1419 defer teardown() 1420 1421 input := &ProtectionRequest{ 1422 RequiredStatusChecks: &RequiredStatusChecks{ 1423 Strict: true, 1424 Contexts: &[]string{"continuous-integration"}, 1425 }, 1426 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1427 DismissStaleReviews: true, 1428 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1429 Users: &[]string{"uu"}, 1430 Teams: &[]string{"tt"}, 1431 Apps: &[]string{"aa"}, 1432 }, 1433 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1434 Users: []string{"uuu"}, 1435 Teams: []string{"ttt"}, 1436 Apps: []string{"aaa"}, 1437 }, 1438 }, 1439 Restrictions: &BranchRestrictionsRequest{ 1440 Users: []string{"u"}, 1441 Teams: []string{"t"}, 1442 Apps: []string{"a"}, 1443 }, 1444 BlockCreations: Bool(true), 1445 LockBranch: Bool(true), 1446 AllowForkSyncing: Bool(true), 1447 } 1448 1449 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1450 v := new(ProtectionRequest) 1451 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1452 1453 testMethod(t, r, "PUT") 1454 if !cmp.Equal(v, input) { 1455 t.Errorf("Request body = %+v, want %+v", v, input) 1456 } 1457 1458 // TODO: remove custom Accept header when this API fully launches 1459 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1460 fmt.Fprintf(w, `{ 1461 "required_status_checks":{ 1462 "strict":true, 1463 "contexts":["continuous-integration"], 1464 "checks": [ 1465 { 1466 "context": "continuous-integration", 1467 "app_id": null 1468 } 1469 ] 1470 }, 1471 "required_pull_request_reviews":{ 1472 "dismissal_restrictions":{ 1473 "users":[{ 1474 "id":3, 1475 "login":"uu" 1476 }], 1477 "teams":[{ 1478 "id":4, 1479 "slug":"tt" 1480 }], 1481 "apps":[{ 1482 "id":5, 1483 "slug":"aa" 1484 }] 1485 }, 1486 "dismiss_stale_reviews":true, 1487 "require_code_owner_reviews":true, 1488 "bypass_pull_request_allowances": { 1489 "users":[{"id":10,"login":"uuu"}], 1490 "teams":[{"id":20,"slug":"ttt"}], 1491 "apps":[{"id":30,"slug":"aaa"}] 1492 } 1493 }, 1494 "restrictions":{ 1495 "users":[{"id":1,"login":"u"}], 1496 "teams":[{"id":2,"slug":"t"}], 1497 "apps":[{"id":3,"slug":"a"}] 1498 }, 1499 "block_creations": { 1500 "enabled": true 1501 }, 1502 "lock_branch": { 1503 "enabled": true 1504 }, 1505 "allow_fork_syncing": { 1506 "enabled": true 1507 } 1508 }`) 1509 }) 1510 1511 ctx := context.Background() 1512 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1513 if err != nil { 1514 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1515 } 1516 1517 want := &Protection{ 1518 RequiredStatusChecks: &RequiredStatusChecks{ 1519 Strict: true, 1520 Contexts: &[]string{"continuous-integration"}, 1521 Checks: &[]*RequiredStatusCheck{ 1522 { 1523 Context: "continuous-integration", 1524 }, 1525 }, 1526 }, 1527 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1528 DismissStaleReviews: true, 1529 DismissalRestrictions: &DismissalRestrictions{ 1530 Users: []*User{ 1531 {Login: String("uu"), ID: Int64(3)}, 1532 }, 1533 Teams: []*Team{ 1534 {Slug: String("tt"), ID: Int64(4)}, 1535 }, 1536 Apps: []*App{ 1537 {Slug: String("aa"), ID: Int64(5)}, 1538 }, 1539 }, 1540 RequireCodeOwnerReviews: true, 1541 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1542 Users: []*User{ 1543 {Login: String("uuu"), ID: Int64(10)}, 1544 }, 1545 Teams: []*Team{ 1546 {Slug: String("ttt"), ID: Int64(20)}, 1547 }, 1548 Apps: []*App{ 1549 {Slug: String("aaa"), ID: Int64(30)}, 1550 }, 1551 }, 1552 }, 1553 Restrictions: &BranchRestrictions{ 1554 Users: []*User{ 1555 {Login: String("u"), ID: Int64(1)}, 1556 }, 1557 Teams: []*Team{ 1558 {Slug: String("t"), ID: Int64(2)}, 1559 }, 1560 Apps: []*App{ 1561 {Slug: String("a"), ID: Int64(3)}, 1562 }, 1563 }, 1564 BlockCreations: &BlockCreations{ 1565 Enabled: Bool(true), 1566 }, 1567 LockBranch: &LockBranch{ 1568 Enabled: Bool(true), 1569 }, 1570 AllowForkSyncing: &AllowForkSyncing{ 1571 Enabled: Bool(true), 1572 }, 1573 } 1574 if !cmp.Equal(protection, want) { 1575 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1576 } 1577 1578 const methodName = "UpdateBranchProtection" 1579 testBadOptions(t, methodName, func() (err error) { 1580 _, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input) 1581 return err 1582 }) 1583 1584 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1585 got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1586 if got != nil { 1587 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1588 } 1589 return resp, err 1590 }) 1591 }) 1592 } 1593 } 1594 1595 func TestRepositoriesService_UpdateBranchProtection_EmptyContexts(t *testing.T) { 1596 tests := []struct { 1597 branch string 1598 urlPath string 1599 }{ 1600 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1601 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1602 } 1603 1604 for _, test := range tests { 1605 t.Run(test.branch, func(t *testing.T) { 1606 client, mux, _, teardown := setup() 1607 defer teardown() 1608 1609 input := &ProtectionRequest{ 1610 RequiredStatusChecks: &RequiredStatusChecks{ 1611 Strict: true, 1612 Contexts: &[]string{}, 1613 }, 1614 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1615 DismissStaleReviews: true, 1616 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1617 Users: &[]string{"uu"}, 1618 Teams: &[]string{"tt"}, 1619 Apps: &[]string{"aa"}, 1620 }, 1621 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1622 Users: []string{"uuu"}, 1623 Teams: []string{"ttt"}, 1624 Apps: []string{"aaa"}, 1625 }, 1626 }, 1627 Restrictions: &BranchRestrictionsRequest{ 1628 Users: []string{"u"}, 1629 Teams: []string{"t"}, 1630 Apps: []string{"a"}, 1631 }, 1632 BlockCreations: Bool(true), 1633 LockBranch: Bool(true), 1634 AllowForkSyncing: Bool(true), 1635 } 1636 1637 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1638 v := new(ProtectionRequest) 1639 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1640 1641 testMethod(t, r, "PUT") 1642 if !cmp.Equal(v, input) { 1643 t.Errorf("Request body = %+v, want %+v", v, input) 1644 } 1645 1646 // TODO: remove custom Accept header when this API fully launches 1647 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1648 fmt.Fprintf(w, `{ 1649 "required_status_checks":{ 1650 "strict":true, 1651 "contexts":[], 1652 "checks": null 1653 }, 1654 "required_pull_request_reviews":{ 1655 "dismissal_restrictions":{ 1656 "users":[{ 1657 "id":3, 1658 "login":"uu" 1659 }], 1660 "teams":[{ 1661 "id":4, 1662 "slug":"tt" 1663 }], 1664 "apps":[{ 1665 "id":5, 1666 "slug":"aa" 1667 }] 1668 }, 1669 "dismiss_stale_reviews":true, 1670 "require_code_owner_reviews":true, 1671 "bypass_pull_request_allowances": { 1672 "users":[{"id":10,"login":"uuu"}], 1673 "teams":[{"id":20,"slug":"ttt"}], 1674 "apps":[{"id":30,"slug":"aaa"}] 1675 } 1676 }, 1677 "restrictions":{ 1678 "users":[{"id":1,"login":"u"}], 1679 "teams":[{"id":2,"slug":"t"}], 1680 "apps":[{"id":3,"slug":"a"}] 1681 }, 1682 "block_creations": { 1683 "enabled": true 1684 }, 1685 "lock_branch": { 1686 "enabled": true 1687 }, 1688 "allow_fork_syncing": { 1689 "enabled": true 1690 } 1691 }`) 1692 }) 1693 1694 ctx := context.Background() 1695 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1696 if err != nil { 1697 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1698 } 1699 1700 want := &Protection{ 1701 RequiredStatusChecks: &RequiredStatusChecks{ 1702 Strict: true, 1703 Contexts: &[]string{}, 1704 }, 1705 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1706 DismissStaleReviews: true, 1707 DismissalRestrictions: &DismissalRestrictions{ 1708 Users: []*User{ 1709 {Login: String("uu"), ID: Int64(3)}, 1710 }, 1711 Teams: []*Team{ 1712 {Slug: String("tt"), ID: Int64(4)}, 1713 }, 1714 Apps: []*App{ 1715 {Slug: String("aa"), ID: Int64(5)}, 1716 }, 1717 }, 1718 RequireCodeOwnerReviews: true, 1719 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1720 Users: []*User{ 1721 {Login: String("uuu"), ID: Int64(10)}, 1722 }, 1723 Teams: []*Team{ 1724 {Slug: String("ttt"), ID: Int64(20)}, 1725 }, 1726 Apps: []*App{ 1727 {Slug: String("aaa"), ID: Int64(30)}, 1728 }, 1729 }, 1730 }, 1731 Restrictions: &BranchRestrictions{ 1732 Users: []*User{ 1733 {Login: String("u"), ID: Int64(1)}, 1734 }, 1735 Teams: []*Team{ 1736 {Slug: String("t"), ID: Int64(2)}, 1737 }, 1738 Apps: []*App{ 1739 {Slug: String("a"), ID: Int64(3)}, 1740 }, 1741 }, 1742 BlockCreations: &BlockCreations{ 1743 Enabled: Bool(true), 1744 }, 1745 LockBranch: &LockBranch{ 1746 Enabled: Bool(true), 1747 }, 1748 AllowForkSyncing: &AllowForkSyncing{ 1749 Enabled: Bool(true), 1750 }, 1751 } 1752 if !cmp.Equal(protection, want) { 1753 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1754 } 1755 1756 const methodName = "UpdateBranchProtection" 1757 testBadOptions(t, methodName, func() (err error) { 1758 _, _, err = client.Repositories.UpdateBranchProtection(ctx, "\n", "\n", "\n", input) 1759 return err 1760 }) 1761 1762 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1763 got, resp, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1764 if got != nil { 1765 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1766 } 1767 return resp, err 1768 }) 1769 }) 1770 } 1771 } 1772 1773 func TestRepositoriesService_UpdateBranchProtection_Checks(t *testing.T) { 1774 tests := []struct { 1775 branch string 1776 urlPath string 1777 }{ 1778 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1779 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1780 } 1781 1782 for _, test := range tests { 1783 t.Run(test.branch, func(t *testing.T) { 1784 client, mux, _, teardown := setup() 1785 defer teardown() 1786 1787 input := &ProtectionRequest{ 1788 RequiredStatusChecks: &RequiredStatusChecks{ 1789 Strict: true, 1790 Checks: &[]*RequiredStatusCheck{ 1791 { 1792 Context: "continuous-integration", 1793 }, 1794 }, 1795 }, 1796 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1797 DismissStaleReviews: true, 1798 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1799 Users: &[]string{"uu"}, 1800 Teams: &[]string{"tt"}, 1801 Apps: &[]string{"aa"}, 1802 }, 1803 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1804 Users: []string{"uuu"}, 1805 Teams: []string{"ttt"}, 1806 Apps: []string{"aaa"}, 1807 }, 1808 }, 1809 Restrictions: &BranchRestrictionsRequest{ 1810 Users: []string{"u"}, 1811 Teams: []string{"t"}, 1812 Apps: []string{"a"}, 1813 }, 1814 } 1815 1816 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1817 v := new(ProtectionRequest) 1818 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1819 1820 testMethod(t, r, "PUT") 1821 if !cmp.Equal(v, input) { 1822 t.Errorf("Request body = %+v, want %+v", v, input) 1823 } 1824 1825 // TODO: remove custom Accept header when this API fully launches 1826 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1827 fmt.Fprintf(w, `{ 1828 "required_status_checks":{ 1829 "strict":true, 1830 "contexts":["continuous-integration"], 1831 "checks": [ 1832 { 1833 "context": "continuous-integration", 1834 "app_id": null 1835 } 1836 ] 1837 }, 1838 "required_pull_request_reviews":{ 1839 "dismissal_restrictions":{ 1840 "users":[{ 1841 "id":3, 1842 "login":"uu" 1843 }], 1844 "teams":[{ 1845 "id":4, 1846 "slug":"tt" 1847 }], 1848 "apps":[{ 1849 "id":5, 1850 "slug":"aa" 1851 }] 1852 }, 1853 "dismiss_stale_reviews":true, 1854 "require_code_owner_reviews":true, 1855 "bypass_pull_request_allowances": { 1856 "users":[{"id":10,"login":"uuu"}], 1857 "teams":[{"id":20,"slug":"ttt"}], 1858 "apps":[{"id":30,"slug":"aaa"}] 1859 } 1860 }, 1861 "restrictions":{ 1862 "users":[{"id":1,"login":"u"}], 1863 "teams":[{"id":2,"slug":"t"}], 1864 "apps":[{"id":3,"slug":"a"}] 1865 } 1866 }`) 1867 }) 1868 1869 ctx := context.Background() 1870 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1871 if err != nil { 1872 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1873 } 1874 1875 want := &Protection{ 1876 RequiredStatusChecks: &RequiredStatusChecks{ 1877 Strict: true, 1878 Contexts: &[]string{"continuous-integration"}, 1879 Checks: &[]*RequiredStatusCheck{ 1880 { 1881 Context: "continuous-integration", 1882 }, 1883 }, 1884 }, 1885 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1886 DismissStaleReviews: true, 1887 DismissalRestrictions: &DismissalRestrictions{ 1888 Users: []*User{ 1889 {Login: String("uu"), ID: Int64(3)}, 1890 }, 1891 Teams: []*Team{ 1892 {Slug: String("tt"), ID: Int64(4)}, 1893 }, 1894 Apps: []*App{ 1895 {Slug: String("aa"), ID: Int64(5)}, 1896 }, 1897 }, 1898 RequireCodeOwnerReviews: true, 1899 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1900 Users: []*User{ 1901 {Login: String("uuu"), ID: Int64(10)}, 1902 }, 1903 Teams: []*Team{ 1904 {Slug: String("ttt"), ID: Int64(20)}, 1905 }, 1906 Apps: []*App{ 1907 {Slug: String("aaa"), ID: Int64(30)}, 1908 }, 1909 }, 1910 }, 1911 Restrictions: &BranchRestrictions{ 1912 Users: []*User{ 1913 {Login: String("u"), ID: Int64(1)}, 1914 }, 1915 Teams: []*Team{ 1916 {Slug: String("t"), ID: Int64(2)}, 1917 }, 1918 Apps: []*App{ 1919 {Slug: String("a"), ID: Int64(3)}, 1920 }, 1921 }, 1922 } 1923 if !cmp.Equal(protection, want) { 1924 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1925 } 1926 }) 1927 } 1928 } 1929 1930 func TestRepositoriesService_UpdateBranchProtection_EmptyChecks(t *testing.T) { 1931 tests := []struct { 1932 branch string 1933 urlPath string 1934 }{ 1935 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1936 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1937 } 1938 1939 for _, test := range tests { 1940 t.Run(test.branch, func(t *testing.T) { 1941 client, mux, _, teardown := setup() 1942 defer teardown() 1943 1944 input := &ProtectionRequest{ 1945 RequiredStatusChecks: &RequiredStatusChecks{ 1946 Strict: true, 1947 Checks: &[]*RequiredStatusCheck{}, 1948 }, 1949 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1950 DismissStaleReviews: true, 1951 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1952 Users: &[]string{"uu"}, 1953 Teams: &[]string{"tt"}, 1954 Apps: &[]string{"aa"}, 1955 }, 1956 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1957 Users: []string{"uuu"}, 1958 Teams: []string{"ttt"}, 1959 Apps: []string{"aaa"}, 1960 }, 1961 }, 1962 Restrictions: &BranchRestrictionsRequest{ 1963 Users: []string{"u"}, 1964 Teams: []string{"t"}, 1965 Apps: []string{"a"}, 1966 }, 1967 } 1968 1969 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1970 v := new(ProtectionRequest) 1971 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1972 1973 testMethod(t, r, "PUT") 1974 if !cmp.Equal(v, input) { 1975 t.Errorf("Request body = %+v, want %+v", v, input) 1976 } 1977 1978 // TODO: remove custom Accept header when this API fully launches 1979 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1980 fmt.Fprintf(w, `{ 1981 "required_status_checks":{ 1982 "strict":true, 1983 "contexts":null, 1984 "checks": [] 1985 }, 1986 "required_pull_request_reviews":{ 1987 "dismissal_restrictions":{ 1988 "users":[{ 1989 "id":3, 1990 "login":"uu" 1991 }], 1992 "teams":[{ 1993 "id":4, 1994 "slug":"tt" 1995 }], 1996 "apps":[{ 1997 "id":5, 1998 "slug":"aa" 1999 }] 2000 }, 2001 "dismiss_stale_reviews":true, 2002 "require_code_owner_reviews":true, 2003 "bypass_pull_request_allowances": { 2004 "users":[{"id":10,"login":"uuu"}], 2005 "teams":[{"id":20,"slug":"ttt"}], 2006 "apps":[{"id":30,"slug":"aaa"}] 2007 } 2008 }, 2009 "restrictions":{ 2010 "users":[{"id":1,"login":"u"}], 2011 "teams":[{"id":2,"slug":"t"}], 2012 "apps":[{"id":3,"slug":"a"}] 2013 } 2014 }`) 2015 }) 2016 2017 ctx := context.Background() 2018 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 2019 if err != nil { 2020 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 2021 } 2022 2023 want := &Protection{ 2024 RequiredStatusChecks: &RequiredStatusChecks{ 2025 Strict: true, 2026 Checks: &[]*RequiredStatusCheck{}, 2027 }, 2028 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 2029 DismissStaleReviews: true, 2030 DismissalRestrictions: &DismissalRestrictions{ 2031 Users: []*User{ 2032 {Login: String("uu"), ID: Int64(3)}, 2033 }, 2034 Teams: []*Team{ 2035 {Slug: String("tt"), ID: Int64(4)}, 2036 }, 2037 Apps: []*App{ 2038 {Slug: String("aa"), ID: Int64(5)}, 2039 }, 2040 }, 2041 RequireCodeOwnerReviews: true, 2042 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 2043 Users: []*User{ 2044 {Login: String("uuu"), ID: Int64(10)}, 2045 }, 2046 Teams: []*Team{ 2047 {Slug: String("ttt"), ID: Int64(20)}, 2048 }, 2049 Apps: []*App{ 2050 {Slug: String("aaa"), ID: Int64(30)}, 2051 }, 2052 }, 2053 }, 2054 Restrictions: &BranchRestrictions{ 2055 Users: []*User{ 2056 {Login: String("u"), ID: Int64(1)}, 2057 }, 2058 Teams: []*Team{ 2059 {Slug: String("t"), ID: Int64(2)}, 2060 }, 2061 Apps: []*App{ 2062 {Slug: String("a"), ID: Int64(3)}, 2063 }, 2064 }, 2065 } 2066 if !cmp.Equal(protection, want) { 2067 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 2068 } 2069 }) 2070 } 2071 } 2072 2073 func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T) { 2074 tests := []struct { 2075 branch string 2076 urlPath string 2077 }{ 2078 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 2079 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 2080 } 2081 2082 for _, test := range tests { 2083 t.Run(test.branch, func(t *testing.T) { 2084 client, mux, _, teardown := setup() 2085 defer teardown() 2086 2087 input := &ProtectionRequest{ 2088 RequiredStatusChecks: &RequiredStatusChecks{ 2089 Strict: true, 2090 }, 2091 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 2092 DismissStaleReviews: true, 2093 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 2094 Users: &[]string{"uu"}, 2095 Teams: &[]string{"tt"}, 2096 Apps: &[]string{"aa"}, 2097 }, 2098 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 2099 Users: []string{"uuu"}, 2100 Teams: []string{"ttt"}, 2101 Apps: []string{"aaa"}, 2102 }, 2103 }, 2104 Restrictions: &BranchRestrictionsRequest{ 2105 Users: []string{"u"}, 2106 Teams: []string{"t"}, 2107 Apps: []string{"a"}, 2108 }, 2109 } 2110 2111 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2112 v := new(ProtectionRequest) 2113 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2114 2115 testMethod(t, r, "PUT") 2116 if !cmp.Equal(v, input) { 2117 t.Errorf("Request body = %+v, want %+v", v, input) 2118 } 2119 2120 // TODO: remove custom Accept header when this API fully launches 2121 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2122 fmt.Fprintf(w, `{ 2123 "required_status_checks":{ 2124 "strict":true, 2125 "contexts":[] 2126 }, 2127 "required_pull_request_reviews":{ 2128 "dismissal_restrictions":{ 2129 "users":[{ 2130 "id":3, 2131 "login":"uu" 2132 }], 2133 "teams":[{ 2134 "id":4, 2135 "slug":"tt" 2136 }], 2137 "apps":[{ 2138 "id":5, 2139 "slug":"aa" 2140 }] 2141 }, 2142 "dismiss_stale_reviews":true, 2143 "require_code_owner_reviews":true, 2144 "require_last_push_approval":false, 2145 "bypass_pull_request_allowances": { 2146 "users":[{"id":10,"login":"uuu"}], 2147 "teams":[{"id":20,"slug":"ttt"}], 2148 "apps":[{"id":30,"slug":"aaa"}] 2149 } 2150 }, 2151 "restrictions":{ 2152 "users":[{"id":1,"login":"u"}], 2153 "teams":[{"id":2,"slug":"t"}], 2154 "apps":[{"id":3,"slug":"a"}] 2155 } 2156 }`) 2157 }) 2158 2159 ctx := context.Background() 2160 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 2161 if err != nil { 2162 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 2163 } 2164 2165 want := &Protection{ 2166 RequiredStatusChecks: &RequiredStatusChecks{ 2167 Strict: true, 2168 Contexts: &[]string{}, 2169 }, 2170 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 2171 DismissStaleReviews: true, 2172 DismissalRestrictions: &DismissalRestrictions{ 2173 Users: []*User{ 2174 {Login: String("uu"), ID: Int64(3)}, 2175 }, 2176 Teams: []*Team{ 2177 {Slug: String("tt"), ID: Int64(4)}, 2178 }, 2179 Apps: []*App{ 2180 {Slug: String("aa"), ID: Int64(5)}, 2181 }, 2182 }, 2183 RequireCodeOwnerReviews: true, 2184 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 2185 Users: []*User{ 2186 {Login: String("uuu"), ID: Int64(10)}, 2187 }, 2188 Teams: []*Team{ 2189 {Slug: String("ttt"), ID: Int64(20)}, 2190 }, 2191 Apps: []*App{ 2192 {Slug: String("aaa"), ID: Int64(30)}, 2193 }, 2194 }, 2195 }, 2196 Restrictions: &BranchRestrictions{ 2197 Users: []*User{ 2198 {Login: String("u"), ID: Int64(1)}, 2199 }, 2200 Teams: []*Team{ 2201 {Slug: String("t"), ID: Int64(2)}, 2202 }, 2203 Apps: []*App{ 2204 {Slug: String("a"), ID: Int64(3)}, 2205 }, 2206 }, 2207 } 2208 if !cmp.Equal(protection, want) { 2209 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 2210 } 2211 }) 2212 } 2213 } 2214 2215 func TestRepositoriesService_UpdateBranchProtection_RequireLastPushApproval(t *testing.T) { 2216 tests := []struct { 2217 branch string 2218 urlPath string 2219 }{ 2220 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 2221 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 2222 } 2223 2224 for _, test := range tests { 2225 t.Run(test.branch, func(t *testing.T) { 2226 client, mux, _, teardown := setup() 2227 defer teardown() 2228 2229 input := &ProtectionRequest{ 2230 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 2231 RequireLastPushApproval: Bool(true), 2232 }, 2233 } 2234 2235 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2236 v := new(ProtectionRequest) 2237 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2238 2239 testMethod(t, r, "PUT") 2240 if !cmp.Equal(v, input) { 2241 t.Errorf("Request body = %+v, want %+v", v, input) 2242 } 2243 2244 fmt.Fprintf(w, `{ 2245 "required_pull_request_reviews":{ 2246 "require_last_push_approval":true 2247 } 2248 }`) 2249 }) 2250 2251 ctx := context.Background() 2252 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 2253 if err != nil { 2254 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 2255 } 2256 2257 want := &Protection{ 2258 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 2259 RequireLastPushApproval: true, 2260 }, 2261 } 2262 if !cmp.Equal(protection, want) { 2263 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 2264 } 2265 }) 2266 } 2267 } 2268 2269 func TestRepositoriesService_RemoveBranchProtection(t *testing.T) { 2270 tests := []struct { 2271 branch string 2272 urlPath string 2273 }{ 2274 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 2275 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 2276 } 2277 2278 for _, test := range tests { 2279 t.Run(test.branch, func(t *testing.T) { 2280 client, mux, _, teardown := setup() 2281 defer teardown() 2282 2283 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2284 testMethod(t, r, "DELETE") 2285 w.WriteHeader(http.StatusNoContent) 2286 }) 2287 2288 ctx := context.Background() 2289 _, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch) 2290 if err != nil { 2291 t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err) 2292 } 2293 2294 const methodName = "RemoveBranchProtection" 2295 testBadOptions(t, methodName, func() (err error) { 2296 _, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n") 2297 return err 2298 }) 2299 2300 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2301 return client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch) 2302 }) 2303 }) 2304 } 2305 } 2306 2307 func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) { 2308 client, _, _, teardown := setup() 2309 defer teardown() 2310 2311 ctx := context.Background() 2312 _, _, err := client.Repositories.ListLanguages(ctx, "%", "%") 2313 testURLParseError(t, err) 2314 } 2315 2316 func TestRepositoriesService_License(t *testing.T) { 2317 client, mux, _, teardown := setup() 2318 defer teardown() 2319 2320 mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) { 2321 testMethod(t, r, "GET") 2322 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}}`) 2323 }) 2324 2325 ctx := context.Background() 2326 got, _, err := client.Repositories.License(ctx, "o", "r") 2327 if err != nil { 2328 t.Errorf("Repositories.License returned error: %v", err) 2329 } 2330 2331 want := &RepositoryLicense{ 2332 Name: String("LICENSE"), 2333 Path: String("LICENSE"), 2334 License: &License{ 2335 Name: String("MIT License"), 2336 Key: String("mit"), 2337 SPDXID: String("MIT"), 2338 URL: String("https://api.github.com/licenses/mit"), 2339 Featured: Bool(true), 2340 }, 2341 } 2342 2343 if !cmp.Equal(got, want) { 2344 t.Errorf("Repositories.License returned %+v, want %+v", got, want) 2345 } 2346 2347 const methodName = "License" 2348 testBadOptions(t, methodName, func() (err error) { 2349 _, _, err = client.Repositories.License(ctx, "\n", "\n") 2350 return err 2351 }) 2352 2353 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2354 got, resp, err := client.Repositories.License(ctx, "o", "r") 2355 if got != nil { 2356 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2357 } 2358 return resp, err 2359 }) 2360 } 2361 2362 func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) { 2363 tests := []struct { 2364 branch string 2365 urlPath string 2366 }{ 2367 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2368 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2369 } 2370 2371 for _, test := range tests { 2372 t.Run(test.branch, func(t *testing.T) { 2373 client, mux, _, teardown := setup() 2374 defer teardown() 2375 2376 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2377 testMethod(t, r, "GET") 2378 fmt.Fprint(w, `{ 2379 "strict": true, 2380 "contexts": ["x","y","z"], 2381 "checks": [ 2382 { 2383 "context": "x", 2384 "app_id": null 2385 }, 2386 { 2387 "context": "y", 2388 "app_id": null 2389 }, 2390 { 2391 "context": "z", 2392 "app_id": null 2393 } 2394 ] 2395 }`) 2396 }) 2397 2398 ctx := context.Background() 2399 checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch) 2400 if err != nil { 2401 t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err) 2402 } 2403 2404 want := &RequiredStatusChecks{ 2405 Strict: true, 2406 Contexts: &[]string{"x", "y", "z"}, 2407 Checks: &[]*RequiredStatusCheck{ 2408 { 2409 Context: "x", 2410 }, 2411 { 2412 Context: "y", 2413 }, 2414 { 2415 Context: "z", 2416 }, 2417 }, 2418 } 2419 if !cmp.Equal(checks, want) { 2420 t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want) 2421 } 2422 2423 const methodName = "GetRequiredStatusChecks" 2424 testBadOptions(t, methodName, func() (err error) { 2425 _, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n") 2426 return err 2427 }) 2428 2429 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2430 got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch) 2431 if got != nil { 2432 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2433 } 2434 return resp, err 2435 }) 2436 }) 2437 } 2438 } 2439 2440 func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) { 2441 tests := []struct { 2442 branch string 2443 urlPath string 2444 }{ 2445 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2446 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2447 } 2448 2449 for _, test := range tests { 2450 t.Run(test.branch, func(t *testing.T) { 2451 client, mux, _, teardown := setup() 2452 defer teardown() 2453 2454 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2455 testMethod(t, r, "GET") 2456 2457 w.WriteHeader(http.StatusBadRequest) 2458 fmt.Fprintf(w, `{ 2459 "message": %q, 2460 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 2461 }`, githubBranchNotProtected) 2462 }) 2463 2464 ctx := context.Background() 2465 checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch) 2466 2467 if checks != nil { 2468 t.Errorf("Repositories.GetRequiredStatusChecks returned non-nil status-checks data") 2469 } 2470 2471 if err != ErrBranchNotProtected { 2472 t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err) 2473 } 2474 }) 2475 } 2476 } 2477 2478 func TestRepositoriesService_UpdateRequiredStatusChecks_Contexts(t *testing.T) { 2479 tests := []struct { 2480 branch string 2481 urlPath string 2482 }{ 2483 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2484 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2485 } 2486 2487 for _, test := range tests { 2488 t.Run(test.branch, func(t *testing.T) { 2489 client, mux, _, teardown := setup() 2490 defer teardown() 2491 2492 input := &RequiredStatusChecksRequest{ 2493 Strict: Bool(true), 2494 Contexts: []string{"continuous-integration"}, 2495 } 2496 2497 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2498 v := new(RequiredStatusChecksRequest) 2499 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2500 2501 testMethod(t, r, "PATCH") 2502 if !cmp.Equal(v, input) { 2503 t.Errorf("Request body = %+v, want %+v", v, input) 2504 } 2505 testHeader(t, r, "Accept", mediaTypeV3) 2506 fmt.Fprintf(w, `{ 2507 "strict":true, 2508 "contexts":["continuous-integration"], 2509 "checks": [ 2510 { 2511 "context": "continuous-integration", 2512 "app_id": null 2513 } 2514 ] 2515 }`) 2516 }) 2517 2518 ctx := context.Background() 2519 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input) 2520 if err != nil { 2521 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 2522 } 2523 2524 want := &RequiredStatusChecks{ 2525 Strict: true, 2526 Contexts: &[]string{"continuous-integration"}, 2527 Checks: &[]*RequiredStatusCheck{ 2528 { 2529 Context: "continuous-integration", 2530 }, 2531 }, 2532 } 2533 if !cmp.Equal(statusChecks, want) { 2534 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 2535 } 2536 2537 const methodName = "UpdateRequiredStatusChecks" 2538 testBadOptions(t, methodName, func() (err error) { 2539 _, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input) 2540 return err 2541 }) 2542 2543 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2544 got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input) 2545 if got != nil { 2546 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2547 } 2548 return resp, err 2549 }) 2550 }) 2551 } 2552 } 2553 2554 func TestRepositoriesService_UpdateRequiredStatusChecks_Checks(t *testing.T) { 2555 tests := []struct { 2556 branch string 2557 urlPath string 2558 }{ 2559 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2560 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2561 } 2562 2563 for _, test := range tests { 2564 t.Run(test.branch, func(t *testing.T) { 2565 client, mux, _, teardown := setup() 2566 defer teardown() 2567 2568 appID := int64(123) 2569 noAppID := int64(-1) 2570 input := &RequiredStatusChecksRequest{ 2571 Strict: Bool(true), 2572 Checks: []*RequiredStatusCheck{ 2573 { 2574 Context: "continuous-integration", 2575 }, 2576 { 2577 Context: "continuous-integration2", 2578 AppID: &appID, 2579 }, 2580 { 2581 Context: "continuous-integration3", 2582 AppID: &noAppID, 2583 }, 2584 }, 2585 } 2586 2587 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2588 v := new(RequiredStatusChecksRequest) 2589 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2590 2591 testMethod(t, r, "PATCH") 2592 if !cmp.Equal(v, input) { 2593 t.Errorf("Request body = %+v, want %+v", v, input) 2594 } 2595 testHeader(t, r, "Accept", mediaTypeV3) 2596 fmt.Fprintf(w, `{ 2597 "strict":true, 2598 "contexts":["continuous-integration"], 2599 "checks": [ 2600 { 2601 "context": "continuous-integration", 2602 "app_id": null 2603 }, 2604 { 2605 "context": "continuous-integration2", 2606 "app_id": 123 2607 }, 2608 { 2609 "context": "continuous-integration3", 2610 "app_id": null 2611 } 2612 ] 2613 }`) 2614 }) 2615 2616 ctx := context.Background() 2617 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input) 2618 if err != nil { 2619 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 2620 } 2621 2622 want := &RequiredStatusChecks{ 2623 Strict: true, 2624 Contexts: &[]string{"continuous-integration"}, 2625 Checks: &[]*RequiredStatusCheck{ 2626 { 2627 Context: "continuous-integration", 2628 }, 2629 { 2630 Context: "continuous-integration2", 2631 AppID: &appID, 2632 }, 2633 { 2634 Context: "continuous-integration3", 2635 }, 2636 }, 2637 } 2638 if !cmp.Equal(statusChecks, want) { 2639 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 2640 } 2641 }) 2642 } 2643 } 2644 2645 func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) { 2646 tests := []struct { 2647 branch string 2648 urlPath string 2649 }{ 2650 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2651 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2652 } 2653 2654 for _, test := range tests { 2655 t.Run(test.branch, func(t *testing.T) { 2656 client, mux, _, teardown := setup() 2657 defer teardown() 2658 2659 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2660 testMethod(t, r, "DELETE") 2661 testHeader(t, r, "Accept", mediaTypeV3) 2662 w.WriteHeader(http.StatusNoContent) 2663 }) 2664 2665 ctx := context.Background() 2666 _, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch) 2667 if err != nil { 2668 t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err) 2669 } 2670 2671 const methodName = "RemoveRequiredStatusChecks" 2672 testBadOptions(t, methodName, func() (err error) { 2673 _, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n") 2674 return err 2675 }) 2676 2677 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2678 return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch) 2679 }) 2680 }) 2681 } 2682 } 2683 2684 func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) { 2685 tests := []struct { 2686 branch string 2687 urlPath string 2688 }{ 2689 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"}, 2690 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks/contexts"}, 2691 } 2692 2693 for _, test := range tests { 2694 t.Run(test.branch, func(t *testing.T) { 2695 client, mux, _, teardown := setup() 2696 defer teardown() 2697 2698 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2699 testMethod(t, r, "GET") 2700 fmt.Fprint(w, `["x", "y", "z"]`) 2701 }) 2702 2703 ctx := context.Background() 2704 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch) 2705 if err != nil { 2706 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err) 2707 } 2708 2709 want := []string{"x", "y", "z"} 2710 if !cmp.Equal(contexts, want) { 2711 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want) 2712 } 2713 2714 const methodName = "ListRequiredStatusChecksContexts" 2715 testBadOptions(t, methodName, func() (err error) { 2716 _, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n") 2717 return err 2718 }) 2719 2720 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2721 got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch) 2722 if got != nil { 2723 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2724 } 2725 return resp, err 2726 }) 2727 }) 2728 } 2729 } 2730 2731 func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) { 2732 tests := []struct { 2733 branch string 2734 urlPath string 2735 }{ 2736 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"}, 2737 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks/contexts"}, 2738 } 2739 2740 for _, test := range tests { 2741 t.Run(test.branch, func(t *testing.T) { 2742 client, mux, _, teardown := setup() 2743 defer teardown() 2744 2745 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2746 testMethod(t, r, "GET") 2747 2748 w.WriteHeader(http.StatusBadRequest) 2749 fmt.Fprintf(w, `{ 2750 "message": %q, 2751 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 2752 }`, githubBranchNotProtected) 2753 }) 2754 2755 ctx := context.Background() 2756 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch) 2757 2758 if contexts != nil { 2759 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data") 2760 } 2761 2762 if err != ErrBranchNotProtected { 2763 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err) 2764 } 2765 }) 2766 } 2767 } 2768 2769 func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { 2770 tests := []struct { 2771 branch string 2772 urlPath string 2773 }{ 2774 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2775 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2776 } 2777 2778 for _, test := range tests { 2779 t.Run(test.branch, func(t *testing.T) { 2780 client, mux, _, teardown := setup() 2781 defer teardown() 2782 2783 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2784 testMethod(t, r, "GET") 2785 // TODO: remove custom Accept header when this API fully launches 2786 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2787 fmt.Fprintf(w, `{ 2788 "dismissal_restrictions":{ 2789 "users":[{"id":1,"login":"u"}], 2790 "teams":[{"id":2,"slug":"t"}], 2791 "apps":[{"id":3,"slug":"a"}] 2792 }, 2793 "dismiss_stale_reviews":true, 2794 "require_code_owner_reviews":true, 2795 "required_approving_review_count":1 2796 }`) 2797 }) 2798 2799 ctx := context.Background() 2800 enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch) 2801 if err != nil { 2802 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err) 2803 } 2804 2805 want := &PullRequestReviewsEnforcement{ 2806 DismissStaleReviews: true, 2807 DismissalRestrictions: &DismissalRestrictions{ 2808 Users: []*User{ 2809 {Login: String("u"), ID: Int64(1)}, 2810 }, 2811 Teams: []*Team{ 2812 {Slug: String("t"), ID: Int64(2)}, 2813 }, 2814 Apps: []*App{ 2815 {Slug: String("a"), ID: Int64(3)}, 2816 }, 2817 }, 2818 RequireCodeOwnerReviews: true, 2819 RequiredApprovingReviewCount: 1, 2820 } 2821 2822 if !cmp.Equal(enforcement, want) { 2823 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 2824 } 2825 2826 const methodName = "GetPullRequestReviewEnforcement" 2827 testBadOptions(t, methodName, func() (err error) { 2828 _, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n") 2829 return err 2830 }) 2831 2832 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2833 got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch) 2834 if got != nil { 2835 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2836 } 2837 return resp, err 2838 }) 2839 }) 2840 } 2841 } 2842 2843 func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { 2844 tests := []struct { 2845 branch string 2846 urlPath string 2847 }{ 2848 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2849 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2850 } 2851 2852 for _, test := range tests { 2853 t.Run(test.branch, func(t *testing.T) { 2854 client, mux, _, teardown := setup() 2855 defer teardown() 2856 2857 input := &PullRequestReviewsEnforcementUpdate{ 2858 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 2859 Users: &[]string{"u"}, 2860 Teams: &[]string{"t"}, 2861 Apps: &[]string{"a"}, 2862 }, 2863 } 2864 2865 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2866 v := new(PullRequestReviewsEnforcementUpdate) 2867 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2868 2869 testMethod(t, r, "PATCH") 2870 if !cmp.Equal(v, input) { 2871 t.Errorf("Request body = %+v, want %+v", v, input) 2872 } 2873 // TODO: remove custom Accept header when this API fully launches 2874 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2875 fmt.Fprintf(w, `{ 2876 "dismissal_restrictions":{ 2877 "users":[{"id":1,"login":"u"}], 2878 "teams":[{"id":2,"slug":"t"}], 2879 "apps":[{"id":3,"slug":"a"}] 2880 }, 2881 "dismiss_stale_reviews":true, 2882 "require_code_owner_reviews":true, 2883 "required_approving_review_count":3 2884 }`) 2885 }) 2886 2887 ctx := context.Background() 2888 enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input) 2889 if err != nil { 2890 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err) 2891 } 2892 2893 want := &PullRequestReviewsEnforcement{ 2894 DismissStaleReviews: true, 2895 DismissalRestrictions: &DismissalRestrictions{ 2896 Users: []*User{ 2897 {Login: String("u"), ID: Int64(1)}, 2898 }, 2899 Teams: []*Team{ 2900 {Slug: String("t"), ID: Int64(2)}, 2901 }, 2902 Apps: []*App{ 2903 {Slug: String("a"), ID: Int64(3)}, 2904 }, 2905 }, 2906 RequireCodeOwnerReviews: true, 2907 RequiredApprovingReviewCount: 3, 2908 } 2909 if !cmp.Equal(enforcement, want) { 2910 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 2911 } 2912 2913 const methodName = "UpdatePullRequestReviewEnforcement" 2914 testBadOptions(t, methodName, func() (err error) { 2915 _, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input) 2916 return err 2917 }) 2918 2919 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2920 got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input) 2921 if got != nil { 2922 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2923 } 2924 return resp, err 2925 }) 2926 }) 2927 } 2928 } 2929 2930 func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { 2931 tests := []struct { 2932 branch string 2933 urlPath string 2934 }{ 2935 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2936 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2937 } 2938 2939 for _, test := range tests { 2940 t.Run(test.branch, func(t *testing.T) { 2941 client, mux, _, teardown := setup() 2942 defer teardown() 2943 2944 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2945 testMethod(t, r, "PATCH") 2946 // TODO: remove custom Accept header when this API fully launches 2947 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2948 testBody(t, r, `{"dismissal_restrictions":{}}`+"\n") 2949 fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`) 2950 }) 2951 2952 ctx := context.Background() 2953 enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch) 2954 if err != nil { 2955 t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err) 2956 } 2957 2958 want := &PullRequestReviewsEnforcement{ 2959 DismissStaleReviews: true, 2960 DismissalRestrictions: nil, 2961 RequireCodeOwnerReviews: true, 2962 RequiredApprovingReviewCount: 1, 2963 } 2964 if !cmp.Equal(enforcement, want) { 2965 t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want) 2966 } 2967 2968 const methodName = "DisableDismissalRestrictions" 2969 testBadOptions(t, methodName, func() (err error) { 2970 _, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n") 2971 return err 2972 }) 2973 2974 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2975 got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch) 2976 if got != nil { 2977 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2978 } 2979 return resp, err 2980 }) 2981 }) 2982 } 2983 } 2984 2985 func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { 2986 tests := []struct { 2987 branch string 2988 urlPath string 2989 }{ 2990 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2991 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2992 } 2993 2994 for _, test := range tests { 2995 t.Run(test.branch, func(t *testing.T) { 2996 client, mux, _, teardown := setup() 2997 defer teardown() 2998 2999 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3000 testMethod(t, r, "DELETE") 3001 w.WriteHeader(http.StatusNoContent) 3002 }) 3003 3004 ctx := context.Background() 3005 _, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch) 3006 if err != nil { 3007 t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err) 3008 } 3009 3010 const methodName = "RemovePullRequestReviewEnforcement" 3011 testBadOptions(t, methodName, func() (err error) { 3012 _, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n") 3013 return err 3014 }) 3015 3016 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3017 return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch) 3018 }) 3019 }) 3020 } 3021 } 3022 3023 func TestRepositoriesService_GetAdminEnforcement(t *testing.T) { 3024 tests := []struct { 3025 branch string 3026 urlPath string 3027 }{ 3028 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 3029 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 3030 } 3031 3032 for _, test := range tests { 3033 t.Run(test.branch, func(t *testing.T) { 3034 client, mux, _, teardown := setup() 3035 defer teardown() 3036 3037 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3038 testMethod(t, r, "GET") 3039 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 3040 }) 3041 3042 ctx := context.Background() 3043 enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch) 3044 if err != nil { 3045 t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err) 3046 } 3047 3048 want := &AdminEnforcement{ 3049 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 3050 Enabled: true, 3051 } 3052 3053 if !cmp.Equal(enforcement, want) { 3054 t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want) 3055 } 3056 3057 const methodName = "GetAdminEnforcement" 3058 testBadOptions(t, methodName, func() (err error) { 3059 _, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n") 3060 return err 3061 }) 3062 3063 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3064 got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch) 3065 if got != nil { 3066 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3067 } 3068 return resp, err 3069 }) 3070 }) 3071 } 3072 } 3073 3074 func TestRepositoriesService_AddAdminEnforcement(t *testing.T) { 3075 tests := []struct { 3076 branch string 3077 urlPath string 3078 }{ 3079 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 3080 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 3081 } 3082 3083 for _, test := range tests { 3084 t.Run(test.branch, func(t *testing.T) { 3085 client, mux, _, teardown := setup() 3086 defer teardown() 3087 3088 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3089 testMethod(t, r, "POST") 3090 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 3091 }) 3092 3093 ctx := context.Background() 3094 enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch) 3095 if err != nil { 3096 t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err) 3097 } 3098 3099 want := &AdminEnforcement{ 3100 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 3101 Enabled: true, 3102 } 3103 if !cmp.Equal(enforcement, want) { 3104 t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want) 3105 } 3106 3107 const methodName = "AddAdminEnforcement" 3108 testBadOptions(t, methodName, func() (err error) { 3109 _, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n") 3110 return err 3111 }) 3112 3113 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3114 got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch) 3115 if got != nil { 3116 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3117 } 3118 return resp, err 3119 }) 3120 }) 3121 } 3122 } 3123 3124 func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) { 3125 tests := []struct { 3126 branch string 3127 urlPath string 3128 }{ 3129 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 3130 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 3131 } 3132 3133 for _, test := range tests { 3134 t.Run(test.branch, func(t *testing.T) { 3135 client, mux, _, teardown := setup() 3136 defer teardown() 3137 3138 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3139 testMethod(t, r, "DELETE") 3140 w.WriteHeader(http.StatusNoContent) 3141 }) 3142 3143 ctx := context.Background() 3144 _, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch) 3145 if err != nil { 3146 t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err) 3147 } 3148 3149 const methodName = "RemoveAdminEnforcement" 3150 testBadOptions(t, methodName, func() (err error) { 3151 _, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n") 3152 return err 3153 }) 3154 3155 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3156 return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch) 3157 }) 3158 }) 3159 } 3160 } 3161 3162 func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) { 3163 tests := []struct { 3164 branch string 3165 urlPath string 3166 }{ 3167 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"}, 3168 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"}, 3169 } 3170 3171 for _, test := range tests { 3172 t.Run(test.branch, func(t *testing.T) { 3173 client, mux, _, teardown := setup() 3174 defer teardown() 3175 3176 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3177 testMethod(t, r, "GET") 3178 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 3179 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`) 3180 }) 3181 3182 ctx := context.Background() 3183 signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch) 3184 if err != nil { 3185 t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err) 3186 } 3187 3188 want := &SignaturesProtectedBranch{ 3189 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 3190 Enabled: Bool(false), 3191 } 3192 3193 if !cmp.Equal(signature, want) { 3194 t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want) 3195 } 3196 3197 const methodName = "GetSignaturesProtectedBranch" 3198 testBadOptions(t, methodName, func() (err error) { 3199 _, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n") 3200 return err 3201 }) 3202 3203 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3204 got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch) 3205 if got != nil { 3206 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3207 } 3208 return resp, err 3209 }) 3210 }) 3211 } 3212 } 3213 3214 func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) { 3215 tests := []struct { 3216 branch string 3217 urlPath string 3218 }{ 3219 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"}, 3220 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"}, 3221 } 3222 3223 for _, test := range tests { 3224 t.Run(test.branch, func(t *testing.T) { 3225 client, mux, _, teardown := setup() 3226 defer teardown() 3227 3228 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3229 testMethod(t, r, "POST") 3230 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 3231 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`) 3232 }) 3233 3234 ctx := context.Background() 3235 signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 3236 if err != nil { 3237 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err) 3238 } 3239 3240 want := &SignaturesProtectedBranch{ 3241 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 3242 Enabled: Bool(true), 3243 } 3244 3245 if !cmp.Equal(signature, want) { 3246 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want) 3247 } 3248 3249 const methodName = "RequireSignaturesOnProtectedBranch" 3250 testBadOptions(t, methodName, func() (err error) { 3251 _, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n") 3252 return err 3253 }) 3254 3255 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3256 got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 3257 if got != nil { 3258 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3259 } 3260 return resp, err 3261 }) 3262 }) 3263 } 3264 } 3265 3266 func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) { 3267 tests := []struct { 3268 branch string 3269 urlPath string 3270 }{ 3271 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"}, 3272 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"}, 3273 } 3274 3275 for _, test := range tests { 3276 t.Run(test.branch, func(t *testing.T) { 3277 client, mux, _, teardown := setup() 3278 defer teardown() 3279 3280 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3281 testMethod(t, r, "DELETE") 3282 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 3283 w.WriteHeader(http.StatusNoContent) 3284 }) 3285 3286 ctx := context.Background() 3287 _, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 3288 if err != nil { 3289 t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err) 3290 } 3291 3292 const methodName = "OptionalSignaturesOnProtectedBranch" 3293 testBadOptions(t, methodName, func() (err error) { 3294 _, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n") 3295 return err 3296 }) 3297 3298 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3299 return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 3300 }) 3301 }) 3302 } 3303 } 3304 3305 func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) { 3306 req := PullRequestReviewsEnforcementRequest{} 3307 3308 got, err := json.Marshal(req) 3309 if err != nil { 3310 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 3311 } 3312 3313 want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 3314 if want != string(got) { 3315 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 3316 } 3317 3318 req = PullRequestReviewsEnforcementRequest{ 3319 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{}, 3320 } 3321 3322 got, err = json.Marshal(req) 3323 if err != nil { 3324 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 3325 } 3326 3327 want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 3328 if want != string(got) { 3329 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 3330 } 3331 3332 req = PullRequestReviewsEnforcementRequest{ 3333 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 3334 Users: &[]string{}, 3335 Teams: &[]string{}, 3336 Apps: &[]string{}, 3337 }, 3338 RequireLastPushApproval: Bool(true), 3339 } 3340 3341 got, err = json.Marshal(req) 3342 if err != nil { 3343 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 3344 } 3345 3346 want = `{"dismissal_restrictions":{"users":[],"teams":[],"apps":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0,"require_last_push_approval":true}` 3347 if want != string(got) { 3348 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 3349 } 3350 } 3351 3352 func TestRepositoriesService_ListAllTopics(t *testing.T) { 3353 client, mux, _, teardown := setup() 3354 defer teardown() 3355 3356 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3357 testMethod(t, r, "GET") 3358 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3359 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 3360 }) 3361 3362 ctx := context.Background() 3363 got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r") 3364 if err != nil { 3365 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 3366 } 3367 3368 want := []string{"go", "go-github", "github"} 3369 if !cmp.Equal(got, want) { 3370 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 3371 } 3372 3373 const methodName = "ListAllTopics" 3374 testBadOptions(t, methodName, func() (err error) { 3375 _, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n") 3376 return err 3377 }) 3378 3379 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3380 got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r") 3381 if got != nil { 3382 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3383 } 3384 return resp, err 3385 }) 3386 } 3387 3388 func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) { 3389 client, mux, _, teardown := setup() 3390 defer teardown() 3391 3392 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3393 testMethod(t, r, "GET") 3394 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3395 fmt.Fprint(w, `{"names":[]}`) 3396 }) 3397 3398 ctx := context.Background() 3399 got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r") 3400 if err != nil { 3401 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 3402 } 3403 3404 want := []string{} 3405 if !cmp.Equal(got, want) { 3406 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 3407 } 3408 } 3409 3410 func TestRepositoriesService_ReplaceAllTopics(t *testing.T) { 3411 client, mux, _, teardown := setup() 3412 defer teardown() 3413 3414 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3415 testMethod(t, r, "PUT") 3416 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3417 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 3418 }) 3419 3420 ctx := context.Background() 3421 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"}) 3422 if err != nil { 3423 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 3424 } 3425 3426 want := []string{"go", "go-github", "github"} 3427 if !cmp.Equal(got, want) { 3428 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 3429 } 3430 3431 const methodName = "ReplaceAllTopics" 3432 testBadOptions(t, methodName, func() (err error) { 3433 _, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"}) 3434 return err 3435 }) 3436 3437 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3438 got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"}) 3439 if got != nil { 3440 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3441 } 3442 return resp, err 3443 }) 3444 } 3445 3446 func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) { 3447 client, mux, _, teardown := setup() 3448 defer teardown() 3449 3450 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3451 testMethod(t, r, "PUT") 3452 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3453 testBody(t, r, `{"names":[]}`+"\n") 3454 fmt.Fprint(w, `{"names":[]}`) 3455 }) 3456 3457 ctx := context.Background() 3458 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil) 3459 if err != nil { 3460 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 3461 } 3462 3463 want := []string{} 3464 if !cmp.Equal(got, want) { 3465 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 3466 } 3467 } 3468 3469 func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) { 3470 client, mux, _, teardown := setup() 3471 defer teardown() 3472 3473 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3474 testMethod(t, r, "PUT") 3475 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3476 testBody(t, r, `{"names":[]}`+"\n") 3477 fmt.Fprint(w, `{"names":[]}`) 3478 }) 3479 3480 ctx := context.Background() 3481 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{}) 3482 if err != nil { 3483 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 3484 } 3485 3486 want := []string{} 3487 if !cmp.Equal(got, want) { 3488 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 3489 } 3490 } 3491 3492 func TestRepositoriesService_ListAppRestrictions(t *testing.T) { 3493 tests := []struct { 3494 branch string 3495 urlPath string 3496 }{ 3497 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3498 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3499 } 3500 3501 for _, test := range tests { 3502 t.Run(test.branch, func(t *testing.T) { 3503 client, mux, _, teardown := setup() 3504 defer teardown() 3505 3506 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3507 testMethod(t, r, "GET") 3508 }) 3509 3510 ctx := context.Background() 3511 _, _, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch) 3512 if err != nil { 3513 t.Errorf("Repositories.ListAppRestrictions returned error: %v", err) 3514 } 3515 3516 const methodName = "ListAppRestrictions" 3517 testBadOptions(t, methodName, func() (err error) { 3518 _, _, err = client.Repositories.ListAppRestrictions(ctx, "\n", "\n", "\n") 3519 return err 3520 }) 3521 3522 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3523 got, resp, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch) 3524 if got != nil { 3525 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3526 } 3527 return resp, err 3528 }) 3529 }) 3530 } 3531 } 3532 3533 func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) { 3534 tests := []struct { 3535 branch string 3536 urlPath string 3537 }{ 3538 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3539 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3540 } 3541 3542 for _, test := range tests { 3543 t.Run(test.branch, func(t *testing.T) { 3544 client, mux, _, teardown := setup() 3545 defer teardown() 3546 3547 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3548 testMethod(t, r, "PUT") 3549 fmt.Fprint(w, `[{ 3550 "name": "octocat" 3551 }]`) 3552 }) 3553 input := []string{"octocat"} 3554 ctx := context.Background() 3555 got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input) 3556 if err != nil { 3557 t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err) 3558 } 3559 want := []*App{ 3560 {Name: String("octocat")}, 3561 } 3562 if !cmp.Equal(got, want) { 3563 t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want) 3564 } 3565 3566 const methodName = "ReplaceAppRestrictions" 3567 testBadOptions(t, methodName, func() (err error) { 3568 _, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input) 3569 return err 3570 }) 3571 3572 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3573 got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input) 3574 if got != nil { 3575 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3576 } 3577 return resp, err 3578 }) 3579 }) 3580 } 3581 } 3582 3583 func TestRepositoriesService_AddAppRestrictions(t *testing.T) { 3584 tests := []struct { 3585 branch string 3586 urlPath string 3587 }{ 3588 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3589 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3590 } 3591 3592 for _, test := range tests { 3593 t.Run(test.branch, func(t *testing.T) { 3594 client, mux, _, teardown := setup() 3595 defer teardown() 3596 3597 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3598 testMethod(t, r, "POST") 3599 fmt.Fprint(w, `[{ 3600 "name": "octocat" 3601 }]`) 3602 }) 3603 input := []string{"octocat"} 3604 ctx := context.Background() 3605 got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input) 3606 if err != nil { 3607 t.Errorf("Repositories.AddAppRestrictions returned error: %v", err) 3608 } 3609 want := []*App{ 3610 {Name: String("octocat")}, 3611 } 3612 if !cmp.Equal(got, want) { 3613 t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want) 3614 } 3615 3616 const methodName = "AddAppRestrictions" 3617 testBadOptions(t, methodName, func() (err error) { 3618 _, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input) 3619 return err 3620 }) 3621 3622 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3623 got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input) 3624 if got != nil { 3625 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3626 } 3627 return resp, err 3628 }) 3629 }) 3630 } 3631 } 3632 3633 func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) { 3634 tests := []struct { 3635 branch string 3636 urlPath string 3637 }{ 3638 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3639 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3640 } 3641 3642 for _, test := range tests { 3643 t.Run(test.branch, func(t *testing.T) { 3644 client, mux, _, teardown := setup() 3645 defer teardown() 3646 3647 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3648 testMethod(t, r, "DELETE") 3649 fmt.Fprint(w, `[]`) 3650 }) 3651 input := []string{"octocat"} 3652 ctx := context.Background() 3653 got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input) 3654 if err != nil { 3655 t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err) 3656 } 3657 want := []*App{} 3658 if !cmp.Equal(got, want) { 3659 t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want) 3660 } 3661 3662 const methodName = "RemoveAppRestrictions" 3663 testBadOptions(t, methodName, func() (err error) { 3664 _, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input) 3665 return err 3666 }) 3667 3668 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3669 got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input) 3670 if got != nil { 3671 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3672 } 3673 return resp, err 3674 }) 3675 }) 3676 } 3677 } 3678 3679 func TestRepositoriesService_ListTeamRestrictions(t *testing.T) { 3680 tests := []struct { 3681 branch string 3682 urlPath string 3683 }{ 3684 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3685 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3686 } 3687 3688 for _, test := range tests { 3689 t.Run(test.branch, func(t *testing.T) { 3690 client, mux, _, teardown := setup() 3691 defer teardown() 3692 3693 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3694 testMethod(t, r, "GET") 3695 }) 3696 3697 ctx := context.Background() 3698 _, _, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch) 3699 if err != nil { 3700 t.Errorf("Repositories.ListTeamRestrictions returned error: %v", err) 3701 } 3702 3703 const methodName = "ListTeamRestrictions" 3704 testBadOptions(t, methodName, func() (err error) { 3705 _, _, err = client.Repositories.ListTeamRestrictions(ctx, "\n", "\n", "\n") 3706 return err 3707 }) 3708 3709 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3710 got, resp, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch) 3711 if got != nil { 3712 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3713 } 3714 return resp, err 3715 }) 3716 }) 3717 } 3718 } 3719 3720 func TestRepositoriesService_ReplaceTeamRestrictions(t *testing.T) { 3721 tests := []struct { 3722 branch string 3723 urlPath string 3724 }{ 3725 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3726 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3727 } 3728 3729 for _, test := range tests { 3730 t.Run(test.branch, func(t *testing.T) { 3731 client, mux, _, teardown := setup() 3732 defer teardown() 3733 3734 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3735 testMethod(t, r, "PUT") 3736 fmt.Fprint(w, `[{ 3737 "name": "octocat" 3738 }]`) 3739 }) 3740 input := []string{"octocat"} 3741 ctx := context.Background() 3742 got, _, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input) 3743 if err != nil { 3744 t.Errorf("Repositories.ReplaceTeamRestrictions returned error: %v", err) 3745 } 3746 want := []*Team{ 3747 {Name: String("octocat")}, 3748 } 3749 if !cmp.Equal(got, want) { 3750 t.Errorf("Repositories.ReplaceTeamRestrictions returned %+v, want %+v", got, want) 3751 } 3752 3753 const methodName = "ReplaceTeamRestrictions" 3754 testBadOptions(t, methodName, func() (err error) { 3755 _, _, err = client.Repositories.ReplaceTeamRestrictions(ctx, "\n", "\n", "\n", input) 3756 return err 3757 }) 3758 3759 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3760 got, resp, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input) 3761 if got != nil { 3762 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3763 } 3764 return resp, err 3765 }) 3766 }) 3767 } 3768 } 3769 3770 func TestRepositoriesService_AddTeamRestrictions(t *testing.T) { 3771 tests := []struct { 3772 branch string 3773 urlPath string 3774 }{ 3775 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3776 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3777 } 3778 3779 for _, test := range tests { 3780 t.Run(test.branch, func(t *testing.T) { 3781 client, mux, _, teardown := setup() 3782 defer teardown() 3783 3784 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3785 testMethod(t, r, "POST") 3786 fmt.Fprint(w, `[{ 3787 "name": "octocat" 3788 }]`) 3789 }) 3790 input := []string{"octocat"} 3791 ctx := context.Background() 3792 got, _, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input) 3793 if err != nil { 3794 t.Errorf("Repositories.AddTeamRestrictions returned error: %v", err) 3795 } 3796 want := []*Team{ 3797 {Name: String("octocat")}, 3798 } 3799 if !cmp.Equal(got, want) { 3800 t.Errorf("Repositories.AddTeamRestrictions returned %+v, want %+v", got, want) 3801 } 3802 3803 const methodName = "AddTeamRestrictions" 3804 testBadOptions(t, methodName, func() (err error) { 3805 _, _, err = client.Repositories.AddTeamRestrictions(ctx, "\n", "\n", "\n", input) 3806 return err 3807 }) 3808 3809 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3810 got, resp, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input) 3811 if got != nil { 3812 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3813 } 3814 return resp, err 3815 }) 3816 }) 3817 } 3818 } 3819 3820 func TestRepositoriesService_RemoveTeamRestrictions(t *testing.T) { 3821 tests := []struct { 3822 branch string 3823 urlPath string 3824 }{ 3825 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3826 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3827 } 3828 3829 for _, test := range tests { 3830 t.Run(test.branch, func(t *testing.T) { 3831 client, mux, _, teardown := setup() 3832 defer teardown() 3833 3834 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3835 testMethod(t, r, "DELETE") 3836 fmt.Fprint(w, `[]`) 3837 }) 3838 input := []string{"octocat"} 3839 ctx := context.Background() 3840 got, _, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input) 3841 if err != nil { 3842 t.Errorf("Repositories.RemoveTeamRestrictions returned error: %v", err) 3843 } 3844 want := []*Team{} 3845 if !cmp.Equal(got, want) { 3846 t.Errorf("Repositories.RemoveTeamRestrictions returned %+v, want %+v", got, want) 3847 } 3848 3849 const methodName = "RemoveTeamRestrictions" 3850 testBadOptions(t, methodName, func() (err error) { 3851 _, _, err = client.Repositories.RemoveTeamRestrictions(ctx, "\n", "\n", "\n", input) 3852 return err 3853 }) 3854 3855 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3856 got, resp, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input) 3857 if got != nil { 3858 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3859 } 3860 return resp, err 3861 }) 3862 }) 3863 } 3864 } 3865 3866 func TestRepositoriesService_ListUserRestrictions(t *testing.T) { 3867 tests := []struct { 3868 branch string 3869 urlPath string 3870 }{ 3871 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3872 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3873 } 3874 3875 for _, test := range tests { 3876 t.Run(test.branch, func(t *testing.T) { 3877 client, mux, _, teardown := setup() 3878 defer teardown() 3879 3880 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3881 testMethod(t, r, "GET") 3882 }) 3883 3884 ctx := context.Background() 3885 _, _, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch) 3886 if err != nil { 3887 t.Errorf("Repositories.ListUserRestrictions returned error: %v", err) 3888 } 3889 3890 const methodName = "ListUserRestrictions" 3891 testBadOptions(t, methodName, func() (err error) { 3892 _, _, err = client.Repositories.ListUserRestrictions(ctx, "\n", "\n", "\n") 3893 return err 3894 }) 3895 3896 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3897 got, resp, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch) 3898 if got != nil { 3899 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3900 } 3901 return resp, err 3902 }) 3903 }) 3904 } 3905 } 3906 3907 func TestRepositoriesService_ReplaceUserRestrictions(t *testing.T) { 3908 tests := []struct { 3909 branch string 3910 urlPath string 3911 }{ 3912 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3913 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3914 } 3915 3916 for _, test := range tests { 3917 t.Run(test.branch, func(t *testing.T) { 3918 client, mux, _, teardown := setup() 3919 defer teardown() 3920 3921 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3922 testMethod(t, r, "PUT") 3923 fmt.Fprint(w, `[{ 3924 "name": "octocat" 3925 }]`) 3926 }) 3927 input := []string{"octocat"} 3928 ctx := context.Background() 3929 got, _, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input) 3930 if err != nil { 3931 t.Errorf("Repositories.ReplaceUserRestrictions returned error: %v", err) 3932 } 3933 want := []*User{ 3934 {Name: String("octocat")}, 3935 } 3936 if !cmp.Equal(got, want) { 3937 t.Errorf("Repositories.ReplaceUserRestrictions returned %+v, want %+v", got, want) 3938 } 3939 3940 const methodName = "ReplaceUserRestrictions" 3941 testBadOptions(t, methodName, func() (err error) { 3942 _, _, err = client.Repositories.ReplaceUserRestrictions(ctx, "\n", "\n", "\n", input) 3943 return err 3944 }) 3945 3946 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3947 got, resp, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input) 3948 if got != nil { 3949 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3950 } 3951 return resp, err 3952 }) 3953 }) 3954 } 3955 } 3956 3957 func TestRepositoriesService_AddUserRestrictions(t *testing.T) { 3958 tests := []struct { 3959 branch string 3960 urlPath string 3961 }{ 3962 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3963 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3964 } 3965 3966 for _, test := range tests { 3967 t.Run(test.branch, func(t *testing.T) { 3968 client, mux, _, teardown := setup() 3969 defer teardown() 3970 3971 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3972 testMethod(t, r, "POST") 3973 fmt.Fprint(w, `[{ 3974 "name": "octocat" 3975 }]`) 3976 }) 3977 input := []string{"octocat"} 3978 ctx := context.Background() 3979 got, _, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input) 3980 if err != nil { 3981 t.Errorf("Repositories.AddUserRestrictions returned error: %v", err) 3982 } 3983 want := []*User{ 3984 {Name: String("octocat")}, 3985 } 3986 if !cmp.Equal(got, want) { 3987 t.Errorf("Repositories.AddUserRestrictions returned %+v, want %+v", got, want) 3988 } 3989 3990 const methodName = "AddUserRestrictions" 3991 testBadOptions(t, methodName, func() (err error) { 3992 _, _, err = client.Repositories.AddUserRestrictions(ctx, "\n", "\n", "\n", input) 3993 return err 3994 }) 3995 3996 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3997 got, resp, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input) 3998 if got != nil { 3999 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 4000 } 4001 return resp, err 4002 }) 4003 }) 4004 } 4005 } 4006 4007 func TestRepositoriesService_RemoveUserRestrictions(t *testing.T) { 4008 tests := []struct { 4009 branch string 4010 urlPath string 4011 }{ 4012 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 4013 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 4014 } 4015 4016 for _, test := range tests { 4017 t.Run(test.branch, func(t *testing.T) { 4018 client, mux, _, teardown := setup() 4019 defer teardown() 4020 4021 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 4022 testMethod(t, r, "DELETE") 4023 fmt.Fprint(w, `[]`) 4024 }) 4025 input := []string{"octocat"} 4026 ctx := context.Background() 4027 got, _, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input) 4028 if err != nil { 4029 t.Errorf("Repositories.RemoveUserRestrictions returned error: %v", err) 4030 } 4031 want := []*User{} 4032 if !cmp.Equal(got, want) { 4033 t.Errorf("Repositories.RemoveUserRestrictions returned %+v, want %+v", got, want) 4034 } 4035 4036 const methodName = "RemoveUserRestrictions" 4037 testBadOptions(t, methodName, func() (err error) { 4038 _, _, err = client.Repositories.RemoveUserRestrictions(ctx, "\n", "\n", "\n", input) 4039 return err 4040 }) 4041 4042 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4043 got, resp, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input) 4044 if got != nil { 4045 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 4046 } 4047 return resp, err 4048 }) 4049 }) 4050 } 4051 } 4052 4053 func TestRepositoriesService_Transfer(t *testing.T) { 4054 client, mux, _, teardown := setup() 4055 defer teardown() 4056 4057 input := TransferRequest{NewOwner: "a", NewName: String("b"), TeamID: []int64{123}} 4058 4059 mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) { 4060 var v TransferRequest 4061 assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) 4062 4063 testMethod(t, r, "POST") 4064 if !cmp.Equal(v, input) { 4065 t.Errorf("Request body = %+v, want %+v", v, input) 4066 } 4067 4068 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 4069 }) 4070 4071 ctx := context.Background() 4072 got, _, err := client.Repositories.Transfer(ctx, "o", "r", input) 4073 if err != nil { 4074 t.Errorf("Repositories.Transfer returned error: %v", err) 4075 } 4076 4077 want := &Repository{Owner: &User{Login: String("a")}} 4078 if !cmp.Equal(got, want) { 4079 t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want) 4080 } 4081 4082 const methodName = "Transfer" 4083 testBadOptions(t, methodName, func() (err error) { 4084 _, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input) 4085 return err 4086 }) 4087 4088 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4089 got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input) 4090 if got != nil { 4091 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 4092 } 4093 return resp, err 4094 }) 4095 } 4096 4097 func TestRepositoriesService_Dispatch(t *testing.T) { 4098 client, mux, _, teardown := setup() 4099 defer teardown() 4100 4101 var input DispatchRequestOptions 4102 4103 mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) { 4104 var v DispatchRequestOptions 4105 assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) 4106 4107 testMethod(t, r, "POST") 4108 if !cmp.Equal(v, input) { 4109 t.Errorf("Request body = %+v, want %+v", v, input) 4110 } 4111 4112 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 4113 }) 4114 4115 ctx := context.Background() 4116 4117 testCases := []interface{}{ 4118 nil, 4119 struct { 4120 Foo string 4121 }{ 4122 Foo: "test", 4123 }, 4124 struct { 4125 Bar int 4126 }{ 4127 Bar: 42, 4128 }, 4129 struct { 4130 Foo string 4131 Bar int 4132 Baz bool 4133 }{ 4134 Foo: "test", 4135 Bar: 42, 4136 Baz: false, 4137 }, 4138 } 4139 4140 for _, tc := range testCases { 4141 if tc == nil { 4142 input = DispatchRequestOptions{EventType: "go"} 4143 } else { 4144 bytes, _ := json.Marshal(tc) 4145 payload := json.RawMessage(bytes) 4146 input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload} 4147 } 4148 4149 got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input) 4150 if err != nil { 4151 t.Errorf("Repositories.Dispatch returned error: %v", err) 4152 } 4153 4154 want := &Repository{Owner: &User{Login: String("a")}} 4155 if !cmp.Equal(got, want) { 4156 t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want) 4157 } 4158 } 4159 4160 const methodName = "Dispatch" 4161 testBadOptions(t, methodName, func() (err error) { 4162 _, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input) 4163 return err 4164 }) 4165 4166 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4167 got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input) 4168 if got != nil { 4169 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 4170 } 4171 return resp, err 4172 }) 4173 } 4174 4175 func TestAdvancedSecurity_Marshal(t *testing.T) { 4176 testJSONMarshal(t, &AdvancedSecurity{}, "{}") 4177 4178 u := &AdvancedSecurity{ 4179 Status: String("status"), 4180 } 4181 4182 want := `{ 4183 "status": "status" 4184 }` 4185 4186 testJSONMarshal(t, u, want) 4187 } 4188 4189 func TestAuthorizedActorsOnly_Marshal(t *testing.T) { 4190 testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}") 4191 4192 u := &AuthorizedActorsOnly{ 4193 From: Bool(true), 4194 } 4195 4196 want := `{ 4197 "from" : true 4198 }` 4199 4200 testJSONMarshal(t, u, want) 4201 } 4202 4203 func TestDispatchRequestOptions_Marshal(t *testing.T) { 4204 testJSONMarshal(t, &DispatchRequestOptions{}, "{}") 4205 4206 cp := json.RawMessage(`{"testKey":"testValue"}`) 4207 u := &DispatchRequestOptions{ 4208 EventType: "test_event_type", 4209 ClientPayload: &cp, 4210 } 4211 4212 want := `{ 4213 "event_type": "test_event_type", 4214 "client_payload": { 4215 "testKey": "testValue" 4216 } 4217 }` 4218 4219 testJSONMarshal(t, u, want) 4220 } 4221 4222 func TestTransferRequest_Marshal(t *testing.T) { 4223 testJSONMarshal(t, &TransferRequest{}, "{}") 4224 4225 u := &TransferRequest{ 4226 NewOwner: "testOwner", 4227 NewName: String("testName"), 4228 TeamID: []int64{1, 2}, 4229 } 4230 4231 want := `{ 4232 "new_owner": "testOwner", 4233 "new_name": "testName", 4234 "team_ids": [1,2] 4235 }` 4236 4237 testJSONMarshal(t, u, want) 4238 } 4239 4240 func TestSignaturesProtectedBranch_Marshal(t *testing.T) { 4241 testJSONMarshal(t, &SignaturesProtectedBranch{}, "{}") 4242 4243 u := &SignaturesProtectedBranch{ 4244 URL: String("https://www.testURL.in"), 4245 Enabled: Bool(false), 4246 } 4247 4248 want := `{ 4249 "url": "https://www.testURL.in", 4250 "enabled": false 4251 }` 4252 4253 testJSONMarshal(t, u, want) 4254 4255 u2 := &SignaturesProtectedBranch{ 4256 URL: String("testURL"), 4257 Enabled: Bool(true), 4258 } 4259 4260 want2 := `{ 4261 "url": "testURL", 4262 "enabled": true 4263 }` 4264 4265 testJSONMarshal(t, u2, want2) 4266 } 4267 4268 func TestDismissalRestrictionsRequest_Marshal(t *testing.T) { 4269 testJSONMarshal(t, &DismissalRestrictionsRequest{}, "{}") 4270 4271 u := &DismissalRestrictionsRequest{ 4272 Users: &[]string{"user1", "user2"}, 4273 Teams: &[]string{"team1", "team2"}, 4274 Apps: &[]string{"app1", "app2"}, 4275 } 4276 4277 want := `{ 4278 "users": ["user1","user2"], 4279 "teams": ["team1","team2"], 4280 "apps": ["app1","app2"] 4281 }` 4282 4283 testJSONMarshal(t, u, want) 4284 } 4285 4286 func TestAdminEnforcement_Marshal(t *testing.T) { 4287 testJSONMarshal(t, &AdminEnforcement{}, "{}") 4288 4289 u := &AdminEnforcement{ 4290 URL: String("https://www.test-url.in"), 4291 Enabled: false, 4292 } 4293 4294 want := `{ 4295 "url": "https://www.test-url.in", 4296 "enabled": false 4297 }` 4298 4299 testJSONMarshal(t, u, want) 4300 } 4301 4302 func TestPullRequestReviewsEnforcementUpdate_Marshal(t *testing.T) { 4303 testJSONMarshal(t, &PullRequestReviewsEnforcementUpdate{}, "{}") 4304 4305 u := &PullRequestReviewsEnforcementUpdate{ 4306 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 4307 Users: []string{"user1", "user2"}, 4308 Teams: []string{"team1", "team2"}, 4309 Apps: []string{"app1", "app2"}, 4310 }, 4311 DismissStaleReviews: Bool(false), 4312 RequireCodeOwnerReviews: Bool(true), 4313 RequiredApprovingReviewCount: 2, 4314 } 4315 4316 want := `{ 4317 "bypass_pull_request_allowances": { 4318 "users": ["user1","user2"], 4319 "teams": ["team1","team2"], 4320 "apps": ["app1","app2"] 4321 }, 4322 "dismiss_stale_reviews": false, 4323 "require_code_owner_reviews": true, 4324 "required_approving_review_count": 2 4325 }` 4326 4327 testJSONMarshal(t, u, want) 4328 } 4329 4330 func TestRequiredStatusCheck_Marshal(t *testing.T) { 4331 testJSONMarshal(t, &RequiredStatusCheck{}, "{}") 4332 4333 u := &RequiredStatusCheck{ 4334 Context: "ctx", 4335 AppID: Int64(1), 4336 } 4337 4338 want := `{ 4339 "context": "ctx", 4340 "app_id": 1 4341 }` 4342 4343 testJSONMarshal(t, u, want) 4344 } 4345 4346 func TestRepositoryTag_Marshal(t *testing.T) { 4347 testJSONMarshal(t, &RepositoryTag{}, "{}") 4348 4349 u := &RepositoryTag{ 4350 Name: String("v0.1"), 4351 Commit: &Commit{ 4352 SHA: String("sha"), 4353 URL: String("url"), 4354 }, 4355 ZipballURL: String("zball"), 4356 TarballURL: String("tball"), 4357 } 4358 4359 want := `{ 4360 "name": "v0.1", 4361 "commit": { 4362 "sha": "sha", 4363 "url": "url" 4364 }, 4365 "zipball_url": "zball", 4366 "tarball_url": "tball" 4367 }` 4368 4369 testJSONMarshal(t, u, want) 4370 } 4371 4372 func TestRepositoriesService_EnablePrivateReporting(t *testing.T) { 4373 client, mux, _, teardown := setup() 4374 defer teardown() 4375 4376 mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) { 4377 testMethod(t, r, "PUT") 4378 w.WriteHeader(http.StatusNoContent) 4379 }) 4380 4381 ctx := context.Background() 4382 _, err := client.Repositories.EnablePrivateReporting(ctx, "owner", "repo") 4383 if err != nil { 4384 t.Errorf("Repositories.EnablePrivateReporting returned error: %v", err) 4385 } 4386 4387 const methodName = "EnablePrivateReporting" 4388 testBadOptions(t, methodName, func() (err error) { 4389 _, err = client.Repositories.EnablePrivateReporting(ctx, "\n", "\n") 4390 return err 4391 }) 4392 4393 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4394 return client.Repositories.EnablePrivateReporting(ctx, "owner", "repo") 4395 }) 4396 } 4397 4398 func TestRepositoriesService_DisablePrivateReporting(t *testing.T) { 4399 client, mux, _, teardown := setup() 4400 defer teardown() 4401 4402 mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) { 4403 testMethod(t, r, "DELETE") 4404 w.WriteHeader(http.StatusNoContent) 4405 }) 4406 4407 ctx := context.Background() 4408 _, err := client.Repositories.DisablePrivateReporting(ctx, "owner", "repo") 4409 if err != nil { 4410 t.Errorf("Repositories.DisablePrivateReporting returned error: %v", err) 4411 } 4412 4413 const methodName = "DisablePrivateReporting" 4414 testBadOptions(t, methodName, func() (err error) { 4415 _, err = client.Repositories.DisablePrivateReporting(ctx, "\n", "\n") 4416 return err 4417 }) 4418 4419 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4420 return client.Repositories.DisablePrivateReporting(ctx, "owner", "repo") 4421 }) 4422 }