github.com/google/go-github/v57@v57.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"}}}`) 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")}}} 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_Checks(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 Checks: []*RequiredStatusCheck{ 1613 { 1614 Context: "continuous-integration", 1615 }, 1616 }, 1617 }, 1618 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1619 DismissStaleReviews: true, 1620 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1621 Users: &[]string{"uu"}, 1622 Teams: &[]string{"tt"}, 1623 Apps: &[]string{"aa"}, 1624 }, 1625 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1626 Users: []string{"uuu"}, 1627 Teams: []string{"ttt"}, 1628 Apps: []string{"aaa"}, 1629 }, 1630 }, 1631 Restrictions: &BranchRestrictionsRequest{ 1632 Users: []string{"u"}, 1633 Teams: []string{"t"}, 1634 Apps: []string{"a"}, 1635 }, 1636 } 1637 1638 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1639 v := new(ProtectionRequest) 1640 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1641 1642 testMethod(t, r, "PUT") 1643 if !cmp.Equal(v, input) { 1644 t.Errorf("Request body = %+v, want %+v", v, input) 1645 } 1646 1647 // TODO: remove custom Accept header when this API fully launches 1648 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1649 fmt.Fprintf(w, `{ 1650 "required_status_checks":{ 1651 "strict":true, 1652 "contexts":["continuous-integration"], 1653 "checks": [ 1654 { 1655 "context": "continuous-integration", 1656 "app_id": null 1657 } 1658 ] 1659 }, 1660 "required_pull_request_reviews":{ 1661 "dismissal_restrictions":{ 1662 "users":[{ 1663 "id":3, 1664 "login":"uu" 1665 }], 1666 "teams":[{ 1667 "id":4, 1668 "slug":"tt" 1669 }], 1670 "apps":[{ 1671 "id":5, 1672 "slug":"aa" 1673 }] 1674 }, 1675 "dismiss_stale_reviews":true, 1676 "require_code_owner_reviews":true, 1677 "bypass_pull_request_allowances": { 1678 "users":[{"id":10,"login":"uuu"}], 1679 "teams":[{"id":20,"slug":"ttt"}], 1680 "apps":[{"id":30,"slug":"aaa"}] 1681 } 1682 }, 1683 "restrictions":{ 1684 "users":[{"id":1,"login":"u"}], 1685 "teams":[{"id":2,"slug":"t"}], 1686 "apps":[{"id":3,"slug":"a"}] 1687 } 1688 }`) 1689 }) 1690 1691 ctx := context.Background() 1692 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1693 if err != nil { 1694 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1695 } 1696 1697 want := &Protection{ 1698 RequiredStatusChecks: &RequiredStatusChecks{ 1699 Strict: true, 1700 Contexts: []string{"continuous-integration"}, 1701 Checks: []*RequiredStatusCheck{ 1702 { 1703 Context: "continuous-integration", 1704 }, 1705 }, 1706 }, 1707 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1708 DismissStaleReviews: true, 1709 DismissalRestrictions: &DismissalRestrictions{ 1710 Users: []*User{ 1711 {Login: String("uu"), ID: Int64(3)}, 1712 }, 1713 Teams: []*Team{ 1714 {Slug: String("tt"), ID: Int64(4)}, 1715 }, 1716 Apps: []*App{ 1717 {Slug: String("aa"), ID: Int64(5)}, 1718 }, 1719 }, 1720 RequireCodeOwnerReviews: true, 1721 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1722 Users: []*User{ 1723 {Login: String("uuu"), ID: Int64(10)}, 1724 }, 1725 Teams: []*Team{ 1726 {Slug: String("ttt"), ID: Int64(20)}, 1727 }, 1728 Apps: []*App{ 1729 {Slug: String("aaa"), ID: Int64(30)}, 1730 }, 1731 }, 1732 }, 1733 Restrictions: &BranchRestrictions{ 1734 Users: []*User{ 1735 {Login: String("u"), ID: Int64(1)}, 1736 }, 1737 Teams: []*Team{ 1738 {Slug: String("t"), ID: Int64(2)}, 1739 }, 1740 Apps: []*App{ 1741 {Slug: String("a"), ID: Int64(3)}, 1742 }, 1743 }, 1744 } 1745 if !cmp.Equal(protection, want) { 1746 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1747 } 1748 }) 1749 } 1750 } 1751 1752 func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T) { 1753 tests := []struct { 1754 branch string 1755 urlPath string 1756 }{ 1757 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1758 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1759 } 1760 1761 for _, test := range tests { 1762 t.Run(test.branch, func(t *testing.T) { 1763 client, mux, _, teardown := setup() 1764 defer teardown() 1765 1766 input := &ProtectionRequest{ 1767 RequiredStatusChecks: &RequiredStatusChecks{ 1768 Strict: true, 1769 }, 1770 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1771 DismissStaleReviews: true, 1772 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1773 Users: &[]string{"uu"}, 1774 Teams: &[]string{"tt"}, 1775 Apps: &[]string{"aa"}, 1776 }, 1777 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 1778 Users: []string{"uuu"}, 1779 Teams: []string{"ttt"}, 1780 Apps: []string{"aaa"}, 1781 }, 1782 }, 1783 Restrictions: &BranchRestrictionsRequest{ 1784 Users: []string{"u"}, 1785 Teams: []string{"t"}, 1786 Apps: []string{"a"}, 1787 }, 1788 } 1789 1790 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1791 v := new(ProtectionRequest) 1792 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1793 1794 testMethod(t, r, "PUT") 1795 if !cmp.Equal(v, input) { 1796 t.Errorf("Request body = %+v, want %+v", v, input) 1797 } 1798 1799 // TODO: remove custom Accept header when this API fully launches 1800 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1801 fmt.Fprintf(w, `{ 1802 "required_status_checks":{ 1803 "strict":true, 1804 "contexts":[] 1805 }, 1806 "required_pull_request_reviews":{ 1807 "dismissal_restrictions":{ 1808 "users":[{ 1809 "id":3, 1810 "login":"uu" 1811 }], 1812 "teams":[{ 1813 "id":4, 1814 "slug":"tt" 1815 }], 1816 "apps":[{ 1817 "id":5, 1818 "slug":"aa" 1819 }] 1820 }, 1821 "dismiss_stale_reviews":true, 1822 "require_code_owner_reviews":true, 1823 "require_last_push_approval":false, 1824 "bypass_pull_request_allowances": { 1825 "users":[{"id":10,"login":"uuu"}], 1826 "teams":[{"id":20,"slug":"ttt"}], 1827 "apps":[{"id":30,"slug":"aaa"}] 1828 } 1829 }, 1830 "restrictions":{ 1831 "users":[{"id":1,"login":"u"}], 1832 "teams":[{"id":2,"slug":"t"}], 1833 "apps":[{"id":3,"slug":"a"}] 1834 } 1835 }`) 1836 }) 1837 1838 ctx := context.Background() 1839 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1840 if err != nil { 1841 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1842 } 1843 1844 want := &Protection{ 1845 RequiredStatusChecks: &RequiredStatusChecks{ 1846 Strict: true, 1847 Contexts: []string{}, 1848 }, 1849 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1850 DismissStaleReviews: true, 1851 DismissalRestrictions: &DismissalRestrictions{ 1852 Users: []*User{ 1853 {Login: String("uu"), ID: Int64(3)}, 1854 }, 1855 Teams: []*Team{ 1856 {Slug: String("tt"), ID: Int64(4)}, 1857 }, 1858 Apps: []*App{ 1859 {Slug: String("aa"), ID: Int64(5)}, 1860 }, 1861 }, 1862 RequireCodeOwnerReviews: true, 1863 BypassPullRequestAllowances: &BypassPullRequestAllowances{ 1864 Users: []*User{ 1865 {Login: String("uuu"), ID: Int64(10)}, 1866 }, 1867 Teams: []*Team{ 1868 {Slug: String("ttt"), ID: Int64(20)}, 1869 }, 1870 Apps: []*App{ 1871 {Slug: String("aaa"), ID: Int64(30)}, 1872 }, 1873 }, 1874 }, 1875 Restrictions: &BranchRestrictions{ 1876 Users: []*User{ 1877 {Login: String("u"), ID: Int64(1)}, 1878 }, 1879 Teams: []*Team{ 1880 {Slug: String("t"), ID: Int64(2)}, 1881 }, 1882 Apps: []*App{ 1883 {Slug: String("a"), ID: Int64(3)}, 1884 }, 1885 }, 1886 } 1887 if !cmp.Equal(protection, want) { 1888 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1889 } 1890 }) 1891 } 1892 } 1893 1894 func TestRepositoriesService_UpdateBranchProtection_RequireLastPushApproval(t *testing.T) { 1895 tests := []struct { 1896 branch string 1897 urlPath string 1898 }{ 1899 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1900 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1901 } 1902 1903 for _, test := range tests { 1904 t.Run(test.branch, func(t *testing.T) { 1905 client, mux, _, teardown := setup() 1906 defer teardown() 1907 1908 input := &ProtectionRequest{ 1909 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1910 RequireLastPushApproval: Bool(true), 1911 }, 1912 } 1913 1914 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1915 v := new(ProtectionRequest) 1916 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 1917 1918 testMethod(t, r, "PUT") 1919 if !cmp.Equal(v, input) { 1920 t.Errorf("Request body = %+v, want %+v", v, input) 1921 } 1922 1923 fmt.Fprintf(w, `{ 1924 "required_pull_request_reviews":{ 1925 "require_last_push_approval":true 1926 } 1927 }`) 1928 }) 1929 1930 ctx := context.Background() 1931 protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", test.branch, input) 1932 if err != nil { 1933 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1934 } 1935 1936 want := &Protection{ 1937 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1938 RequireLastPushApproval: true, 1939 }, 1940 } 1941 if !cmp.Equal(protection, want) { 1942 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1943 } 1944 }) 1945 } 1946 } 1947 1948 func TestRepositoriesService_RemoveBranchProtection(t *testing.T) { 1949 tests := []struct { 1950 branch string 1951 urlPath string 1952 }{ 1953 {branch: "b", urlPath: "/repos/o/r/branches/b/protection"}, 1954 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection"}, 1955 } 1956 1957 for _, test := range tests { 1958 t.Run(test.branch, func(t *testing.T) { 1959 client, mux, _, teardown := setup() 1960 defer teardown() 1961 1962 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 1963 testMethod(t, r, "DELETE") 1964 w.WriteHeader(http.StatusNoContent) 1965 }) 1966 1967 ctx := context.Background() 1968 _, err := client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch) 1969 if err != nil { 1970 t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err) 1971 } 1972 1973 const methodName = "RemoveBranchProtection" 1974 testBadOptions(t, methodName, func() (err error) { 1975 _, err = client.Repositories.RemoveBranchProtection(ctx, "\n", "\n", "\n") 1976 return err 1977 }) 1978 1979 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1980 return client.Repositories.RemoveBranchProtection(ctx, "o", "r", test.branch) 1981 }) 1982 }) 1983 } 1984 } 1985 1986 func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) { 1987 client, _, _, teardown := setup() 1988 defer teardown() 1989 1990 ctx := context.Background() 1991 _, _, err := client.Repositories.ListLanguages(ctx, "%", "%") 1992 testURLParseError(t, err) 1993 } 1994 1995 func TestRepositoriesService_License(t *testing.T) { 1996 client, mux, _, teardown := setup() 1997 defer teardown() 1998 1999 mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) { 2000 testMethod(t, r, "GET") 2001 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}}`) 2002 }) 2003 2004 ctx := context.Background() 2005 got, _, err := client.Repositories.License(ctx, "o", "r") 2006 if err != nil { 2007 t.Errorf("Repositories.License returned error: %v", err) 2008 } 2009 2010 want := &RepositoryLicense{ 2011 Name: String("LICENSE"), 2012 Path: String("LICENSE"), 2013 License: &License{ 2014 Name: String("MIT License"), 2015 Key: String("mit"), 2016 SPDXID: String("MIT"), 2017 URL: String("https://api.github.com/licenses/mit"), 2018 Featured: Bool(true), 2019 }, 2020 } 2021 2022 if !cmp.Equal(got, want) { 2023 t.Errorf("Repositories.License returned %+v, want %+v", got, want) 2024 } 2025 2026 const methodName = "License" 2027 testBadOptions(t, methodName, func() (err error) { 2028 _, _, err = client.Repositories.License(ctx, "\n", "\n") 2029 return err 2030 }) 2031 2032 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2033 got, resp, err := client.Repositories.License(ctx, "o", "r") 2034 if got != nil { 2035 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2036 } 2037 return resp, err 2038 }) 2039 } 2040 2041 func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) { 2042 tests := []struct { 2043 branch string 2044 urlPath string 2045 }{ 2046 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2047 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2048 } 2049 2050 for _, test := range tests { 2051 t.Run(test.branch, func(t *testing.T) { 2052 client, mux, _, teardown := setup() 2053 defer teardown() 2054 2055 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2056 testMethod(t, r, "GET") 2057 fmt.Fprint(w, `{ 2058 "strict": true, 2059 "contexts": ["x","y","z"], 2060 "checks": [ 2061 { 2062 "context": "x", 2063 "app_id": null 2064 }, 2065 { 2066 "context": "y", 2067 "app_id": null 2068 }, 2069 { 2070 "context": "z", 2071 "app_id": null 2072 } 2073 ] 2074 }`) 2075 }) 2076 2077 ctx := context.Background() 2078 checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch) 2079 if err != nil { 2080 t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err) 2081 } 2082 2083 want := &RequiredStatusChecks{ 2084 Strict: true, 2085 Contexts: []string{"x", "y", "z"}, 2086 Checks: []*RequiredStatusCheck{ 2087 { 2088 Context: "x", 2089 }, 2090 { 2091 Context: "y", 2092 }, 2093 { 2094 Context: "z", 2095 }, 2096 }, 2097 } 2098 if !cmp.Equal(checks, want) { 2099 t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want) 2100 } 2101 2102 const methodName = "GetRequiredStatusChecks" 2103 testBadOptions(t, methodName, func() (err error) { 2104 _, _, err = client.Repositories.GetRequiredStatusChecks(ctx, "\n", "\n", "\n") 2105 return err 2106 }) 2107 2108 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2109 got, resp, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch) 2110 if got != nil { 2111 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2112 } 2113 return resp, err 2114 }) 2115 }) 2116 } 2117 } 2118 2119 func TestRepositoriesService_GetRequiredStatusChecks_branchNotProtected(t *testing.T) { 2120 tests := []struct { 2121 branch string 2122 urlPath string 2123 }{ 2124 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2125 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2126 } 2127 2128 for _, test := range tests { 2129 t.Run(test.branch, func(t *testing.T) { 2130 client, mux, _, teardown := setup() 2131 defer teardown() 2132 2133 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2134 testMethod(t, r, "GET") 2135 2136 w.WriteHeader(http.StatusBadRequest) 2137 fmt.Fprintf(w, `{ 2138 "message": %q, 2139 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 2140 }`, githubBranchNotProtected) 2141 }) 2142 2143 ctx := context.Background() 2144 checks, _, err := client.Repositories.GetRequiredStatusChecks(ctx, "o", "r", test.branch) 2145 2146 if checks != nil { 2147 t.Errorf("Repositories.GetRequiredStatusChecks returned non-nil status-checks data") 2148 } 2149 2150 if err != ErrBranchNotProtected { 2151 t.Errorf("Repositories.GetRequiredStatusChecks returned an invalid error: %v", err) 2152 } 2153 }) 2154 } 2155 } 2156 2157 func TestRepositoriesService_UpdateRequiredStatusChecks_Contexts(t *testing.T) { 2158 tests := []struct { 2159 branch string 2160 urlPath string 2161 }{ 2162 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2163 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2164 } 2165 2166 for _, test := range tests { 2167 t.Run(test.branch, func(t *testing.T) { 2168 client, mux, _, teardown := setup() 2169 defer teardown() 2170 2171 input := &RequiredStatusChecksRequest{ 2172 Strict: Bool(true), 2173 Contexts: []string{"continuous-integration"}, 2174 } 2175 2176 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2177 v := new(RequiredStatusChecksRequest) 2178 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2179 2180 testMethod(t, r, "PATCH") 2181 if !cmp.Equal(v, input) { 2182 t.Errorf("Request body = %+v, want %+v", v, input) 2183 } 2184 testHeader(t, r, "Accept", mediaTypeV3) 2185 fmt.Fprintf(w, `{ 2186 "strict":true, 2187 "contexts":["continuous-integration"], 2188 "checks": [ 2189 { 2190 "context": "continuous-integration", 2191 "app_id": null 2192 } 2193 ] 2194 }`) 2195 }) 2196 2197 ctx := context.Background() 2198 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input) 2199 if err != nil { 2200 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 2201 } 2202 2203 want := &RequiredStatusChecks{ 2204 Strict: true, 2205 Contexts: []string{"continuous-integration"}, 2206 Checks: []*RequiredStatusCheck{ 2207 { 2208 Context: "continuous-integration", 2209 }, 2210 }, 2211 } 2212 if !cmp.Equal(statusChecks, want) { 2213 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 2214 } 2215 2216 const methodName = "UpdateRequiredStatusChecks" 2217 testBadOptions(t, methodName, func() (err error) { 2218 _, _, err = client.Repositories.UpdateRequiredStatusChecks(ctx, "\n", "\n", "\n", input) 2219 return err 2220 }) 2221 2222 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2223 got, resp, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input) 2224 if got != nil { 2225 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2226 } 2227 return resp, err 2228 }) 2229 }) 2230 } 2231 } 2232 2233 func TestRepositoriesService_UpdateRequiredStatusChecks_Checks(t *testing.T) { 2234 tests := []struct { 2235 branch string 2236 urlPath string 2237 }{ 2238 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2239 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2240 } 2241 2242 for _, test := range tests { 2243 t.Run(test.branch, func(t *testing.T) { 2244 client, mux, _, teardown := setup() 2245 defer teardown() 2246 2247 appID := int64(123) 2248 noAppID := int64(-1) 2249 input := &RequiredStatusChecksRequest{ 2250 Strict: Bool(true), 2251 Checks: []*RequiredStatusCheck{ 2252 { 2253 Context: "continuous-integration", 2254 }, 2255 { 2256 Context: "continuous-integration2", 2257 AppID: &appID, 2258 }, 2259 { 2260 Context: "continuous-integration3", 2261 AppID: &noAppID, 2262 }, 2263 }, 2264 } 2265 2266 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2267 v := new(RequiredStatusChecksRequest) 2268 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2269 2270 testMethod(t, r, "PATCH") 2271 if !cmp.Equal(v, input) { 2272 t.Errorf("Request body = %+v, want %+v", v, input) 2273 } 2274 testHeader(t, r, "Accept", mediaTypeV3) 2275 fmt.Fprintf(w, `{ 2276 "strict":true, 2277 "contexts":["continuous-integration"], 2278 "checks": [ 2279 { 2280 "context": "continuous-integration", 2281 "app_id": null 2282 }, 2283 { 2284 "context": "continuous-integration2", 2285 "app_id": 123 2286 }, 2287 { 2288 "context": "continuous-integration3", 2289 "app_id": null 2290 } 2291 ] 2292 }`) 2293 }) 2294 2295 ctx := context.Background() 2296 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(ctx, "o", "r", test.branch, input) 2297 if err != nil { 2298 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 2299 } 2300 2301 want := &RequiredStatusChecks{ 2302 Strict: true, 2303 Contexts: []string{"continuous-integration"}, 2304 Checks: []*RequiredStatusCheck{ 2305 { 2306 Context: "continuous-integration", 2307 }, 2308 { 2309 Context: "continuous-integration2", 2310 AppID: &appID, 2311 }, 2312 { 2313 Context: "continuous-integration3", 2314 }, 2315 }, 2316 } 2317 if !cmp.Equal(statusChecks, want) { 2318 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 2319 } 2320 }) 2321 } 2322 } 2323 2324 func TestRepositoriesService_RemoveRequiredStatusChecks(t *testing.T) { 2325 tests := []struct { 2326 branch string 2327 urlPath string 2328 }{ 2329 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks"}, 2330 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks"}, 2331 } 2332 2333 for _, test := range tests { 2334 t.Run(test.branch, func(t *testing.T) { 2335 client, mux, _, teardown := setup() 2336 defer teardown() 2337 2338 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2339 testMethod(t, r, "DELETE") 2340 testHeader(t, r, "Accept", mediaTypeV3) 2341 w.WriteHeader(http.StatusNoContent) 2342 }) 2343 2344 ctx := context.Background() 2345 _, err := client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch) 2346 if err != nil { 2347 t.Errorf("Repositories.RemoveRequiredStatusChecks returned error: %v", err) 2348 } 2349 2350 const methodName = "RemoveRequiredStatusChecks" 2351 testBadOptions(t, methodName, func() (err error) { 2352 _, err = client.Repositories.RemoveRequiredStatusChecks(ctx, "\n", "\n", "\n") 2353 return err 2354 }) 2355 2356 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2357 return client.Repositories.RemoveRequiredStatusChecks(ctx, "o", "r", test.branch) 2358 }) 2359 }) 2360 } 2361 } 2362 2363 func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) { 2364 tests := []struct { 2365 branch string 2366 urlPath string 2367 }{ 2368 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"}, 2369 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks/contexts"}, 2370 } 2371 2372 for _, test := range tests { 2373 t.Run(test.branch, func(t *testing.T) { 2374 client, mux, _, teardown := setup() 2375 defer teardown() 2376 2377 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2378 testMethod(t, r, "GET") 2379 fmt.Fprint(w, `["x", "y", "z"]`) 2380 }) 2381 2382 ctx := context.Background() 2383 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch) 2384 if err != nil { 2385 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err) 2386 } 2387 2388 want := []string{"x", "y", "z"} 2389 if !cmp.Equal(contexts, want) { 2390 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want) 2391 } 2392 2393 const methodName = "ListRequiredStatusChecksContexts" 2394 testBadOptions(t, methodName, func() (err error) { 2395 _, _, err = client.Repositories.ListRequiredStatusChecksContexts(ctx, "\n", "\n", "\n") 2396 return err 2397 }) 2398 2399 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2400 got, resp, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch) 2401 if got != nil { 2402 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2403 } 2404 return resp, err 2405 }) 2406 }) 2407 } 2408 } 2409 2410 func TestRepositoriesService_ListRequiredStatusChecksContexts_branchNotProtected(t *testing.T) { 2411 tests := []struct { 2412 branch string 2413 urlPath string 2414 }{ 2415 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_status_checks/contexts"}, 2416 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_status_checks/contexts"}, 2417 } 2418 2419 for _, test := range tests { 2420 t.Run(test.branch, func(t *testing.T) { 2421 client, mux, _, teardown := setup() 2422 defer teardown() 2423 2424 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2425 testMethod(t, r, "GET") 2426 2427 w.WriteHeader(http.StatusBadRequest) 2428 fmt.Fprintf(w, `{ 2429 "message": %q, 2430 "documentation_url": "https://docs.github.com/rest/repos#get-branch-protection" 2431 }`, githubBranchNotProtected) 2432 }) 2433 2434 ctx := context.Background() 2435 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(ctx, "o", "r", test.branch) 2436 2437 if contexts != nil { 2438 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned non-nil contexts data") 2439 } 2440 2441 if err != ErrBranchNotProtected { 2442 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned an invalid error: %v", err) 2443 } 2444 }) 2445 } 2446 } 2447 2448 func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { 2449 tests := []struct { 2450 branch string 2451 urlPath string 2452 }{ 2453 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2454 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2455 } 2456 2457 for _, test := range tests { 2458 t.Run(test.branch, func(t *testing.T) { 2459 client, mux, _, teardown := setup() 2460 defer teardown() 2461 2462 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2463 testMethod(t, r, "GET") 2464 // TODO: remove custom Accept header when this API fully launches 2465 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2466 fmt.Fprintf(w, `{ 2467 "dismissal_restrictions":{ 2468 "users":[{"id":1,"login":"u"}], 2469 "teams":[{"id":2,"slug":"t"}], 2470 "apps":[{"id":3,"slug":"a"}] 2471 }, 2472 "dismiss_stale_reviews":true, 2473 "require_code_owner_reviews":true, 2474 "required_approving_review_count":1 2475 }`) 2476 }) 2477 2478 ctx := context.Background() 2479 enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch) 2480 if err != nil { 2481 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err) 2482 } 2483 2484 want := &PullRequestReviewsEnforcement{ 2485 DismissStaleReviews: true, 2486 DismissalRestrictions: &DismissalRestrictions{ 2487 Users: []*User{ 2488 {Login: String("u"), ID: Int64(1)}, 2489 }, 2490 Teams: []*Team{ 2491 {Slug: String("t"), ID: Int64(2)}, 2492 }, 2493 Apps: []*App{ 2494 {Slug: String("a"), ID: Int64(3)}, 2495 }, 2496 }, 2497 RequireCodeOwnerReviews: true, 2498 RequiredApprovingReviewCount: 1, 2499 } 2500 2501 if !cmp.Equal(enforcement, want) { 2502 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 2503 } 2504 2505 const methodName = "GetPullRequestReviewEnforcement" 2506 testBadOptions(t, methodName, func() (err error) { 2507 _, _, err = client.Repositories.GetPullRequestReviewEnforcement(ctx, "\n", "\n", "\n") 2508 return err 2509 }) 2510 2511 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2512 got, resp, err := client.Repositories.GetPullRequestReviewEnforcement(ctx, "o", "r", test.branch) 2513 if got != nil { 2514 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2515 } 2516 return resp, err 2517 }) 2518 }) 2519 } 2520 } 2521 2522 func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { 2523 tests := []struct { 2524 branch string 2525 urlPath string 2526 }{ 2527 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2528 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2529 } 2530 2531 for _, test := range tests { 2532 t.Run(test.branch, func(t *testing.T) { 2533 client, mux, _, teardown := setup() 2534 defer teardown() 2535 2536 input := &PullRequestReviewsEnforcementUpdate{ 2537 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 2538 Users: &[]string{"u"}, 2539 Teams: &[]string{"t"}, 2540 Apps: &[]string{"a"}, 2541 }, 2542 } 2543 2544 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2545 v := new(PullRequestReviewsEnforcementUpdate) 2546 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 2547 2548 testMethod(t, r, "PATCH") 2549 if !cmp.Equal(v, input) { 2550 t.Errorf("Request body = %+v, want %+v", v, input) 2551 } 2552 // TODO: remove custom Accept header when this API fully launches 2553 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2554 fmt.Fprintf(w, `{ 2555 "dismissal_restrictions":{ 2556 "users":[{"id":1,"login":"u"}], 2557 "teams":[{"id":2,"slug":"t"}], 2558 "apps":[{"id":3,"slug":"a"}] 2559 }, 2560 "dismiss_stale_reviews":true, 2561 "require_code_owner_reviews":true, 2562 "required_approving_review_count":3 2563 }`) 2564 }) 2565 2566 ctx := context.Background() 2567 enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input) 2568 if err != nil { 2569 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err) 2570 } 2571 2572 want := &PullRequestReviewsEnforcement{ 2573 DismissStaleReviews: true, 2574 DismissalRestrictions: &DismissalRestrictions{ 2575 Users: []*User{ 2576 {Login: String("u"), ID: Int64(1)}, 2577 }, 2578 Teams: []*Team{ 2579 {Slug: String("t"), ID: Int64(2)}, 2580 }, 2581 Apps: []*App{ 2582 {Slug: String("a"), ID: Int64(3)}, 2583 }, 2584 }, 2585 RequireCodeOwnerReviews: true, 2586 RequiredApprovingReviewCount: 3, 2587 } 2588 if !cmp.Equal(enforcement, want) { 2589 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 2590 } 2591 2592 const methodName = "UpdatePullRequestReviewEnforcement" 2593 testBadOptions(t, methodName, func() (err error) { 2594 _, _, err = client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "\n", "\n", "\n", input) 2595 return err 2596 }) 2597 2598 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2599 got, resp, err := client.Repositories.UpdatePullRequestReviewEnforcement(ctx, "o", "r", test.branch, input) 2600 if got != nil { 2601 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2602 } 2603 return resp, err 2604 }) 2605 }) 2606 } 2607 } 2608 2609 func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { 2610 tests := []struct { 2611 branch string 2612 urlPath string 2613 }{ 2614 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2615 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2616 } 2617 2618 for _, test := range tests { 2619 t.Run(test.branch, func(t *testing.T) { 2620 client, mux, _, teardown := setup() 2621 defer teardown() 2622 2623 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2624 testMethod(t, r, "PATCH") 2625 // TODO: remove custom Accept header when this API fully launches 2626 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 2627 testBody(t, r, `{"dismissal_restrictions":{}}`+"\n") 2628 fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`) 2629 }) 2630 2631 ctx := context.Background() 2632 enforcement, _, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch) 2633 if err != nil { 2634 t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err) 2635 } 2636 2637 want := &PullRequestReviewsEnforcement{ 2638 DismissStaleReviews: true, 2639 DismissalRestrictions: nil, 2640 RequireCodeOwnerReviews: true, 2641 RequiredApprovingReviewCount: 1, 2642 } 2643 if !cmp.Equal(enforcement, want) { 2644 t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want) 2645 } 2646 2647 const methodName = "DisableDismissalRestrictions" 2648 testBadOptions(t, methodName, func() (err error) { 2649 _, _, err = client.Repositories.DisableDismissalRestrictions(ctx, "\n", "\n", "\n") 2650 return err 2651 }) 2652 2653 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2654 got, resp, err := client.Repositories.DisableDismissalRestrictions(ctx, "o", "r", test.branch) 2655 if got != nil { 2656 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2657 } 2658 return resp, err 2659 }) 2660 }) 2661 } 2662 } 2663 2664 func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { 2665 tests := []struct { 2666 branch string 2667 urlPath string 2668 }{ 2669 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_pull_request_reviews"}, 2670 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_pull_request_reviews"}, 2671 } 2672 2673 for _, test := range tests { 2674 t.Run(test.branch, func(t *testing.T) { 2675 client, mux, _, teardown := setup() 2676 defer teardown() 2677 2678 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2679 testMethod(t, r, "DELETE") 2680 w.WriteHeader(http.StatusNoContent) 2681 }) 2682 2683 ctx := context.Background() 2684 _, err := client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch) 2685 if err != nil { 2686 t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err) 2687 } 2688 2689 const methodName = "RemovePullRequestReviewEnforcement" 2690 testBadOptions(t, methodName, func() (err error) { 2691 _, err = client.Repositories.RemovePullRequestReviewEnforcement(ctx, "\n", "\n", "\n") 2692 return err 2693 }) 2694 2695 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2696 return client.Repositories.RemovePullRequestReviewEnforcement(ctx, "o", "r", test.branch) 2697 }) 2698 }) 2699 } 2700 } 2701 2702 func TestRepositoriesService_GetAdminEnforcement(t *testing.T) { 2703 tests := []struct { 2704 branch string 2705 urlPath string 2706 }{ 2707 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 2708 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 2709 } 2710 2711 for _, test := range tests { 2712 t.Run(test.branch, func(t *testing.T) { 2713 client, mux, _, teardown := setup() 2714 defer teardown() 2715 2716 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2717 testMethod(t, r, "GET") 2718 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 2719 }) 2720 2721 ctx := context.Background() 2722 enforcement, _, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch) 2723 if err != nil { 2724 t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err) 2725 } 2726 2727 want := &AdminEnforcement{ 2728 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 2729 Enabled: true, 2730 } 2731 2732 if !cmp.Equal(enforcement, want) { 2733 t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want) 2734 } 2735 2736 const methodName = "GetAdminEnforcement" 2737 testBadOptions(t, methodName, func() (err error) { 2738 _, _, err = client.Repositories.GetAdminEnforcement(ctx, "\n", "\n", "\n") 2739 return err 2740 }) 2741 2742 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2743 got, resp, err := client.Repositories.GetAdminEnforcement(ctx, "o", "r", test.branch) 2744 if got != nil { 2745 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2746 } 2747 return resp, err 2748 }) 2749 }) 2750 } 2751 } 2752 2753 func TestRepositoriesService_AddAdminEnforcement(t *testing.T) { 2754 tests := []struct { 2755 branch string 2756 urlPath string 2757 }{ 2758 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 2759 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 2760 } 2761 2762 for _, test := range tests { 2763 t.Run(test.branch, func(t *testing.T) { 2764 client, mux, _, teardown := setup() 2765 defer teardown() 2766 2767 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2768 testMethod(t, r, "POST") 2769 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 2770 }) 2771 2772 ctx := context.Background() 2773 enforcement, _, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch) 2774 if err != nil { 2775 t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err) 2776 } 2777 2778 want := &AdminEnforcement{ 2779 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 2780 Enabled: true, 2781 } 2782 if !cmp.Equal(enforcement, want) { 2783 t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want) 2784 } 2785 2786 const methodName = "AddAdminEnforcement" 2787 testBadOptions(t, methodName, func() (err error) { 2788 _, _, err = client.Repositories.AddAdminEnforcement(ctx, "\n", "\n", "\n") 2789 return err 2790 }) 2791 2792 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2793 got, resp, err := client.Repositories.AddAdminEnforcement(ctx, "o", "r", test.branch) 2794 if got != nil { 2795 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2796 } 2797 return resp, err 2798 }) 2799 }) 2800 } 2801 } 2802 2803 func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) { 2804 tests := []struct { 2805 branch string 2806 urlPath string 2807 }{ 2808 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/enforce_admins"}, 2809 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/enforce_admins"}, 2810 } 2811 2812 for _, test := range tests { 2813 t.Run(test.branch, func(t *testing.T) { 2814 client, mux, _, teardown := setup() 2815 defer teardown() 2816 2817 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2818 testMethod(t, r, "DELETE") 2819 w.WriteHeader(http.StatusNoContent) 2820 }) 2821 2822 ctx := context.Background() 2823 _, err := client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch) 2824 if err != nil { 2825 t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err) 2826 } 2827 2828 const methodName = "RemoveAdminEnforcement" 2829 testBadOptions(t, methodName, func() (err error) { 2830 _, err = client.Repositories.RemoveAdminEnforcement(ctx, "\n", "\n", "\n") 2831 return err 2832 }) 2833 2834 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2835 return client.Repositories.RemoveAdminEnforcement(ctx, "o", "r", test.branch) 2836 }) 2837 }) 2838 } 2839 } 2840 2841 func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) { 2842 tests := []struct { 2843 branch string 2844 urlPath string 2845 }{ 2846 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"}, 2847 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"}, 2848 } 2849 2850 for _, test := range tests { 2851 t.Run(test.branch, func(t *testing.T) { 2852 client, mux, _, teardown := setup() 2853 defer teardown() 2854 2855 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2856 testMethod(t, r, "GET") 2857 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 2858 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`) 2859 }) 2860 2861 ctx := context.Background() 2862 signature, _, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch) 2863 if err != nil { 2864 t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err) 2865 } 2866 2867 want := &SignaturesProtectedBranch{ 2868 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 2869 Enabled: Bool(false), 2870 } 2871 2872 if !cmp.Equal(signature, want) { 2873 t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want) 2874 } 2875 2876 const methodName = "GetSignaturesProtectedBranch" 2877 testBadOptions(t, methodName, func() (err error) { 2878 _, _, err = client.Repositories.GetSignaturesProtectedBranch(ctx, "\n", "\n", "\n") 2879 return err 2880 }) 2881 2882 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2883 got, resp, err := client.Repositories.GetSignaturesProtectedBranch(ctx, "o", "r", test.branch) 2884 if got != nil { 2885 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2886 } 2887 return resp, err 2888 }) 2889 }) 2890 } 2891 } 2892 2893 func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) { 2894 tests := []struct { 2895 branch string 2896 urlPath string 2897 }{ 2898 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"}, 2899 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"}, 2900 } 2901 2902 for _, test := range tests { 2903 t.Run(test.branch, func(t *testing.T) { 2904 client, mux, _, teardown := setup() 2905 defer teardown() 2906 2907 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2908 testMethod(t, r, "POST") 2909 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 2910 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`) 2911 }) 2912 2913 ctx := context.Background() 2914 signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 2915 if err != nil { 2916 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err) 2917 } 2918 2919 want := &SignaturesProtectedBranch{ 2920 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 2921 Enabled: Bool(true), 2922 } 2923 2924 if !cmp.Equal(signature, want) { 2925 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want) 2926 } 2927 2928 const methodName = "RequireSignaturesOnProtectedBranch" 2929 testBadOptions(t, methodName, func() (err error) { 2930 _, _, err = client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n") 2931 return err 2932 }) 2933 2934 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2935 got, resp, err := client.Repositories.RequireSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 2936 if got != nil { 2937 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 2938 } 2939 return resp, err 2940 }) 2941 }) 2942 } 2943 } 2944 2945 func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) { 2946 tests := []struct { 2947 branch string 2948 urlPath string 2949 }{ 2950 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/required_signatures"}, 2951 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/required_signatures"}, 2952 } 2953 2954 for _, test := range tests { 2955 t.Run(test.branch, func(t *testing.T) { 2956 client, mux, _, teardown := setup() 2957 defer teardown() 2958 2959 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 2960 testMethod(t, r, "DELETE") 2961 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 2962 w.WriteHeader(http.StatusNoContent) 2963 }) 2964 2965 ctx := context.Background() 2966 _, err := client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 2967 if err != nil { 2968 t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err) 2969 } 2970 2971 const methodName = "OptionalSignaturesOnProtectedBranch" 2972 testBadOptions(t, methodName, func() (err error) { 2973 _, err = client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "\n", "\n", "\n") 2974 return err 2975 }) 2976 2977 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 2978 return client.Repositories.OptionalSignaturesOnProtectedBranch(ctx, "o", "r", test.branch) 2979 }) 2980 }) 2981 } 2982 } 2983 2984 func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) { 2985 req := PullRequestReviewsEnforcementRequest{} 2986 2987 got, err := json.Marshal(req) 2988 if err != nil { 2989 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 2990 } 2991 2992 want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 2993 if want != string(got) { 2994 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 2995 } 2996 2997 req = PullRequestReviewsEnforcementRequest{ 2998 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{}, 2999 } 3000 3001 got, err = json.Marshal(req) 3002 if err != nil { 3003 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 3004 } 3005 3006 want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 3007 if want != string(got) { 3008 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 3009 } 3010 3011 req = PullRequestReviewsEnforcementRequest{ 3012 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 3013 Users: &[]string{}, 3014 Teams: &[]string{}, 3015 Apps: &[]string{}, 3016 }, 3017 RequireLastPushApproval: Bool(true), 3018 } 3019 3020 got, err = json.Marshal(req) 3021 if err != nil { 3022 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 3023 } 3024 3025 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}` 3026 if want != string(got) { 3027 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 3028 } 3029 } 3030 3031 func TestRepositoriesService_ListAllTopics(t *testing.T) { 3032 client, mux, _, teardown := setup() 3033 defer teardown() 3034 3035 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3036 testMethod(t, r, "GET") 3037 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3038 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 3039 }) 3040 3041 ctx := context.Background() 3042 got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r") 3043 if err != nil { 3044 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 3045 } 3046 3047 want := []string{"go", "go-github", "github"} 3048 if !cmp.Equal(got, want) { 3049 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 3050 } 3051 3052 const methodName = "ListAllTopics" 3053 testBadOptions(t, methodName, func() (err error) { 3054 _, _, err = client.Repositories.ListAllTopics(ctx, "\n", "\n") 3055 return err 3056 }) 3057 3058 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3059 got, resp, err := client.Repositories.ListAllTopics(ctx, "o", "r") 3060 if got != nil { 3061 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3062 } 3063 return resp, err 3064 }) 3065 } 3066 3067 func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) { 3068 client, mux, _, teardown := setup() 3069 defer teardown() 3070 3071 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3072 testMethod(t, r, "GET") 3073 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3074 fmt.Fprint(w, `{"names":[]}`) 3075 }) 3076 3077 ctx := context.Background() 3078 got, _, err := client.Repositories.ListAllTopics(ctx, "o", "r") 3079 if err != nil { 3080 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 3081 } 3082 3083 want := []string{} 3084 if !cmp.Equal(got, want) { 3085 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 3086 } 3087 } 3088 3089 func TestRepositoriesService_ReplaceAllTopics(t *testing.T) { 3090 client, mux, _, teardown := setup() 3091 defer teardown() 3092 3093 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3094 testMethod(t, r, "PUT") 3095 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3096 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 3097 }) 3098 3099 ctx := context.Background() 3100 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"}) 3101 if err != nil { 3102 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 3103 } 3104 3105 want := []string{"go", "go-github", "github"} 3106 if !cmp.Equal(got, want) { 3107 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 3108 } 3109 3110 const methodName = "ReplaceAllTopics" 3111 testBadOptions(t, methodName, func() (err error) { 3112 _, _, err = client.Repositories.ReplaceAllTopics(ctx, "\n", "\n", []string{"\n", "\n", "\n"}) 3113 return err 3114 }) 3115 3116 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3117 got, resp, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{"go", "go-github", "github"}) 3118 if got != nil { 3119 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3120 } 3121 return resp, err 3122 }) 3123 } 3124 3125 func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) { 3126 client, mux, _, teardown := setup() 3127 defer teardown() 3128 3129 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3130 testMethod(t, r, "PUT") 3131 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3132 testBody(t, r, `{"names":[]}`+"\n") 3133 fmt.Fprint(w, `{"names":[]}`) 3134 }) 3135 3136 ctx := context.Background() 3137 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", nil) 3138 if err != nil { 3139 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 3140 } 3141 3142 want := []string{} 3143 if !cmp.Equal(got, want) { 3144 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 3145 } 3146 } 3147 3148 func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) { 3149 client, mux, _, teardown := setup() 3150 defer teardown() 3151 3152 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 3153 testMethod(t, r, "PUT") 3154 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 3155 testBody(t, r, `{"names":[]}`+"\n") 3156 fmt.Fprint(w, `{"names":[]}`) 3157 }) 3158 3159 ctx := context.Background() 3160 got, _, err := client.Repositories.ReplaceAllTopics(ctx, "o", "r", []string{}) 3161 if err != nil { 3162 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 3163 } 3164 3165 want := []string{} 3166 if !cmp.Equal(got, want) { 3167 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 3168 } 3169 } 3170 3171 func TestRepositoriesService_ListAppRestrictions(t *testing.T) { 3172 tests := []struct { 3173 branch string 3174 urlPath string 3175 }{ 3176 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3177 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3178 } 3179 3180 for _, test := range tests { 3181 t.Run(test.branch, func(t *testing.T) { 3182 client, mux, _, teardown := setup() 3183 defer teardown() 3184 3185 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3186 testMethod(t, r, "GET") 3187 }) 3188 3189 ctx := context.Background() 3190 _, _, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch) 3191 if err != nil { 3192 t.Errorf("Repositories.ListAppRestrictions returned error: %v", err) 3193 } 3194 3195 const methodName = "ListAppRestrictions" 3196 testBadOptions(t, methodName, func() (err error) { 3197 _, _, err = client.Repositories.ListAppRestrictions(ctx, "\n", "\n", "\n") 3198 return err 3199 }) 3200 3201 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3202 got, resp, err := client.Repositories.ListAppRestrictions(ctx, "o", "r", test.branch) 3203 if got != nil { 3204 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3205 } 3206 return resp, err 3207 }) 3208 }) 3209 } 3210 } 3211 3212 func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) { 3213 tests := []struct { 3214 branch string 3215 urlPath string 3216 }{ 3217 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3218 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3219 } 3220 3221 for _, test := range tests { 3222 t.Run(test.branch, func(t *testing.T) { 3223 client, mux, _, teardown := setup() 3224 defer teardown() 3225 3226 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3227 testMethod(t, r, "PUT") 3228 fmt.Fprint(w, `[{ 3229 "name": "octocat" 3230 }]`) 3231 }) 3232 input := []string{"octocat"} 3233 ctx := context.Background() 3234 got, _, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input) 3235 if err != nil { 3236 t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err) 3237 } 3238 want := []*App{ 3239 {Name: String("octocat")}, 3240 } 3241 if !cmp.Equal(got, want) { 3242 t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want) 3243 } 3244 3245 const methodName = "ReplaceAppRestrictions" 3246 testBadOptions(t, methodName, func() (err error) { 3247 _, _, err = client.Repositories.ReplaceAppRestrictions(ctx, "\n", "\n", "\n", input) 3248 return err 3249 }) 3250 3251 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3252 got, resp, err := client.Repositories.ReplaceAppRestrictions(ctx, "o", "r", test.branch, input) 3253 if got != nil { 3254 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3255 } 3256 return resp, err 3257 }) 3258 }) 3259 } 3260 } 3261 3262 func TestRepositoriesService_AddAppRestrictions(t *testing.T) { 3263 tests := []struct { 3264 branch string 3265 urlPath string 3266 }{ 3267 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3268 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3269 } 3270 3271 for _, test := range tests { 3272 t.Run(test.branch, func(t *testing.T) { 3273 client, mux, _, teardown := setup() 3274 defer teardown() 3275 3276 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3277 testMethod(t, r, "POST") 3278 fmt.Fprint(w, `[{ 3279 "name": "octocat" 3280 }]`) 3281 }) 3282 input := []string{"octocat"} 3283 ctx := context.Background() 3284 got, _, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input) 3285 if err != nil { 3286 t.Errorf("Repositories.AddAppRestrictions returned error: %v", err) 3287 } 3288 want := []*App{ 3289 {Name: String("octocat")}, 3290 } 3291 if !cmp.Equal(got, want) { 3292 t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want) 3293 } 3294 3295 const methodName = "AddAppRestrictions" 3296 testBadOptions(t, methodName, func() (err error) { 3297 _, _, err = client.Repositories.AddAppRestrictions(ctx, "\n", "\n", "\n", input) 3298 return err 3299 }) 3300 3301 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3302 got, resp, err := client.Repositories.AddAppRestrictions(ctx, "o", "r", test.branch, input) 3303 if got != nil { 3304 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3305 } 3306 return resp, err 3307 }) 3308 }) 3309 } 3310 } 3311 3312 func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) { 3313 tests := []struct { 3314 branch string 3315 urlPath string 3316 }{ 3317 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/apps"}, 3318 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/apps"}, 3319 } 3320 3321 for _, test := range tests { 3322 t.Run(test.branch, func(t *testing.T) { 3323 client, mux, _, teardown := setup() 3324 defer teardown() 3325 3326 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3327 testMethod(t, r, "DELETE") 3328 fmt.Fprint(w, `[]`) 3329 }) 3330 input := []string{"octocat"} 3331 ctx := context.Background() 3332 got, _, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input) 3333 if err != nil { 3334 t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err) 3335 } 3336 want := []*App{} 3337 if !cmp.Equal(got, want) { 3338 t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want) 3339 } 3340 3341 const methodName = "RemoveAppRestrictions" 3342 testBadOptions(t, methodName, func() (err error) { 3343 _, _, err = client.Repositories.RemoveAppRestrictions(ctx, "\n", "\n", "\n", input) 3344 return err 3345 }) 3346 3347 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3348 got, resp, err := client.Repositories.RemoveAppRestrictions(ctx, "o", "r", test.branch, input) 3349 if got != nil { 3350 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3351 } 3352 return resp, err 3353 }) 3354 }) 3355 } 3356 } 3357 3358 func TestRepositoriesService_ListTeamRestrictions(t *testing.T) { 3359 tests := []struct { 3360 branch string 3361 urlPath string 3362 }{ 3363 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3364 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3365 } 3366 3367 for _, test := range tests { 3368 t.Run(test.branch, func(t *testing.T) { 3369 client, mux, _, teardown := setup() 3370 defer teardown() 3371 3372 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3373 testMethod(t, r, "GET") 3374 }) 3375 3376 ctx := context.Background() 3377 _, _, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch) 3378 if err != nil { 3379 t.Errorf("Repositories.ListTeamRestrictions returned error: %v", err) 3380 } 3381 3382 const methodName = "ListTeamRestrictions" 3383 testBadOptions(t, methodName, func() (err error) { 3384 _, _, err = client.Repositories.ListTeamRestrictions(ctx, "\n", "\n", "\n") 3385 return err 3386 }) 3387 3388 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3389 got, resp, err := client.Repositories.ListTeamRestrictions(ctx, "o", "r", test.branch) 3390 if got != nil { 3391 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3392 } 3393 return resp, err 3394 }) 3395 }) 3396 } 3397 } 3398 3399 func TestRepositoriesService_ReplaceTeamRestrictions(t *testing.T) { 3400 tests := []struct { 3401 branch string 3402 urlPath string 3403 }{ 3404 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3405 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3406 } 3407 3408 for _, test := range tests { 3409 t.Run(test.branch, func(t *testing.T) { 3410 client, mux, _, teardown := setup() 3411 defer teardown() 3412 3413 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3414 testMethod(t, r, "PUT") 3415 fmt.Fprint(w, `[{ 3416 "name": "octocat" 3417 }]`) 3418 }) 3419 input := []string{"octocat"} 3420 ctx := context.Background() 3421 got, _, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input) 3422 if err != nil { 3423 t.Errorf("Repositories.ReplaceTeamRestrictions returned error: %v", err) 3424 } 3425 want := []*Team{ 3426 {Name: String("octocat")}, 3427 } 3428 if !cmp.Equal(got, want) { 3429 t.Errorf("Repositories.ReplaceTeamRestrictions returned %+v, want %+v", got, want) 3430 } 3431 3432 const methodName = "ReplaceTeamRestrictions" 3433 testBadOptions(t, methodName, func() (err error) { 3434 _, _, err = client.Repositories.ReplaceTeamRestrictions(ctx, "\n", "\n", "\n", input) 3435 return err 3436 }) 3437 3438 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3439 got, resp, err := client.Repositories.ReplaceTeamRestrictions(ctx, "o", "r", test.branch, input) 3440 if got != nil { 3441 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3442 } 3443 return resp, err 3444 }) 3445 }) 3446 } 3447 } 3448 3449 func TestRepositoriesService_AddTeamRestrictions(t *testing.T) { 3450 tests := []struct { 3451 branch string 3452 urlPath string 3453 }{ 3454 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3455 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3456 } 3457 3458 for _, test := range tests { 3459 t.Run(test.branch, func(t *testing.T) { 3460 client, mux, _, teardown := setup() 3461 defer teardown() 3462 3463 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3464 testMethod(t, r, "POST") 3465 fmt.Fprint(w, `[{ 3466 "name": "octocat" 3467 }]`) 3468 }) 3469 input := []string{"octocat"} 3470 ctx := context.Background() 3471 got, _, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input) 3472 if err != nil { 3473 t.Errorf("Repositories.AddTeamRestrictions returned error: %v", err) 3474 } 3475 want := []*Team{ 3476 {Name: String("octocat")}, 3477 } 3478 if !cmp.Equal(got, want) { 3479 t.Errorf("Repositories.AddTeamRestrictions returned %+v, want %+v", got, want) 3480 } 3481 3482 const methodName = "AddTeamRestrictions" 3483 testBadOptions(t, methodName, func() (err error) { 3484 _, _, err = client.Repositories.AddTeamRestrictions(ctx, "\n", "\n", "\n", input) 3485 return err 3486 }) 3487 3488 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3489 got, resp, err := client.Repositories.AddTeamRestrictions(ctx, "o", "r", test.branch, input) 3490 if got != nil { 3491 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3492 } 3493 return resp, err 3494 }) 3495 }) 3496 } 3497 } 3498 3499 func TestRepositoriesService_RemoveTeamRestrictions(t *testing.T) { 3500 tests := []struct { 3501 branch string 3502 urlPath string 3503 }{ 3504 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/teams"}, 3505 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/teams"}, 3506 } 3507 3508 for _, test := range tests { 3509 t.Run(test.branch, func(t *testing.T) { 3510 client, mux, _, teardown := setup() 3511 defer teardown() 3512 3513 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3514 testMethod(t, r, "DELETE") 3515 fmt.Fprint(w, `[]`) 3516 }) 3517 input := []string{"octocat"} 3518 ctx := context.Background() 3519 got, _, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input) 3520 if err != nil { 3521 t.Errorf("Repositories.RemoveTeamRestrictions returned error: %v", err) 3522 } 3523 want := []*Team{} 3524 if !cmp.Equal(got, want) { 3525 t.Errorf("Repositories.RemoveTeamRestrictions returned %+v, want %+v", got, want) 3526 } 3527 3528 const methodName = "RemoveTeamRestrictions" 3529 testBadOptions(t, methodName, func() (err error) { 3530 _, _, err = client.Repositories.RemoveTeamRestrictions(ctx, "\n", "\n", "\n", input) 3531 return err 3532 }) 3533 3534 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3535 got, resp, err := client.Repositories.RemoveTeamRestrictions(ctx, "o", "r", test.branch, input) 3536 if got != nil { 3537 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3538 } 3539 return resp, err 3540 }) 3541 }) 3542 } 3543 } 3544 3545 func TestRepositoriesService_ListUserRestrictions(t *testing.T) { 3546 tests := []struct { 3547 branch string 3548 urlPath string 3549 }{ 3550 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3551 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3552 } 3553 3554 for _, test := range tests { 3555 t.Run(test.branch, func(t *testing.T) { 3556 client, mux, _, teardown := setup() 3557 defer teardown() 3558 3559 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3560 testMethod(t, r, "GET") 3561 }) 3562 3563 ctx := context.Background() 3564 _, _, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch) 3565 if err != nil { 3566 t.Errorf("Repositories.ListUserRestrictions returned error: %v", err) 3567 } 3568 3569 const methodName = "ListUserRestrictions" 3570 testBadOptions(t, methodName, func() (err error) { 3571 _, _, err = client.Repositories.ListUserRestrictions(ctx, "\n", "\n", "\n") 3572 return err 3573 }) 3574 3575 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3576 got, resp, err := client.Repositories.ListUserRestrictions(ctx, "o", "r", test.branch) 3577 if got != nil { 3578 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3579 } 3580 return resp, err 3581 }) 3582 }) 3583 } 3584 } 3585 3586 func TestRepositoriesService_ReplaceUserRestrictions(t *testing.T) { 3587 tests := []struct { 3588 branch string 3589 urlPath string 3590 }{ 3591 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3592 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3593 } 3594 3595 for _, test := range tests { 3596 t.Run(test.branch, func(t *testing.T) { 3597 client, mux, _, teardown := setup() 3598 defer teardown() 3599 3600 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3601 testMethod(t, r, "PUT") 3602 fmt.Fprint(w, `[{ 3603 "name": "octocat" 3604 }]`) 3605 }) 3606 input := []string{"octocat"} 3607 ctx := context.Background() 3608 got, _, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input) 3609 if err != nil { 3610 t.Errorf("Repositories.ReplaceUserRestrictions returned error: %v", err) 3611 } 3612 want := []*User{ 3613 {Name: String("octocat")}, 3614 } 3615 if !cmp.Equal(got, want) { 3616 t.Errorf("Repositories.ReplaceUserRestrictions returned %+v, want %+v", got, want) 3617 } 3618 3619 const methodName = "ReplaceUserRestrictions" 3620 testBadOptions(t, methodName, func() (err error) { 3621 _, _, err = client.Repositories.ReplaceUserRestrictions(ctx, "\n", "\n", "\n", input) 3622 return err 3623 }) 3624 3625 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3626 got, resp, err := client.Repositories.ReplaceUserRestrictions(ctx, "o", "r", test.branch, input) 3627 if got != nil { 3628 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3629 } 3630 return resp, err 3631 }) 3632 }) 3633 } 3634 } 3635 3636 func TestRepositoriesService_AddUserRestrictions(t *testing.T) { 3637 tests := []struct { 3638 branch string 3639 urlPath string 3640 }{ 3641 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3642 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3643 } 3644 3645 for _, test := range tests { 3646 t.Run(test.branch, func(t *testing.T) { 3647 client, mux, _, teardown := setup() 3648 defer teardown() 3649 3650 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3651 testMethod(t, r, "POST") 3652 fmt.Fprint(w, `[{ 3653 "name": "octocat" 3654 }]`) 3655 }) 3656 input := []string{"octocat"} 3657 ctx := context.Background() 3658 got, _, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input) 3659 if err != nil { 3660 t.Errorf("Repositories.AddUserRestrictions returned error: %v", err) 3661 } 3662 want := []*User{ 3663 {Name: String("octocat")}, 3664 } 3665 if !cmp.Equal(got, want) { 3666 t.Errorf("Repositories.AddUserRestrictions returned %+v, want %+v", got, want) 3667 } 3668 3669 const methodName = "AddUserRestrictions" 3670 testBadOptions(t, methodName, func() (err error) { 3671 _, _, err = client.Repositories.AddUserRestrictions(ctx, "\n", "\n", "\n", input) 3672 return err 3673 }) 3674 3675 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3676 got, resp, err := client.Repositories.AddUserRestrictions(ctx, "o", "r", test.branch, input) 3677 if got != nil { 3678 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3679 } 3680 return resp, err 3681 }) 3682 }) 3683 } 3684 } 3685 3686 func TestRepositoriesService_RemoveUserRestrictions(t *testing.T) { 3687 tests := []struct { 3688 branch string 3689 urlPath string 3690 }{ 3691 {branch: "b", urlPath: "/repos/o/r/branches/b/protection/restrictions/users"}, 3692 {branch: "feat/branch-50%", urlPath: "/repos/o/r/branches/feat/branch-50%/protection/restrictions/users"}, 3693 } 3694 3695 for _, test := range tests { 3696 t.Run(test.branch, func(t *testing.T) { 3697 client, mux, _, teardown := setup() 3698 defer teardown() 3699 3700 mux.HandleFunc(test.urlPath, func(w http.ResponseWriter, r *http.Request) { 3701 testMethod(t, r, "DELETE") 3702 fmt.Fprint(w, `[]`) 3703 }) 3704 input := []string{"octocat"} 3705 ctx := context.Background() 3706 got, _, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input) 3707 if err != nil { 3708 t.Errorf("Repositories.RemoveUserRestrictions returned error: %v", err) 3709 } 3710 want := []*User{} 3711 if !cmp.Equal(got, want) { 3712 t.Errorf("Repositories.RemoveUserRestrictions returned %+v, want %+v", got, want) 3713 } 3714 3715 const methodName = "RemoveUserRestrictions" 3716 testBadOptions(t, methodName, func() (err error) { 3717 _, _, err = client.Repositories.RemoveUserRestrictions(ctx, "\n", "\n", "\n", input) 3718 return err 3719 }) 3720 3721 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3722 got, resp, err := client.Repositories.RemoveUserRestrictions(ctx, "o", "r", test.branch, input) 3723 if got != nil { 3724 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3725 } 3726 return resp, err 3727 }) 3728 }) 3729 } 3730 } 3731 3732 func TestRepositoriesService_Transfer(t *testing.T) { 3733 client, mux, _, teardown := setup() 3734 defer teardown() 3735 3736 input := TransferRequest{NewOwner: "a", NewName: String("b"), TeamID: []int64{123}} 3737 3738 mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) { 3739 var v TransferRequest 3740 assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) 3741 3742 testMethod(t, r, "POST") 3743 if !cmp.Equal(v, input) { 3744 t.Errorf("Request body = %+v, want %+v", v, input) 3745 } 3746 3747 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 3748 }) 3749 3750 ctx := context.Background() 3751 got, _, err := client.Repositories.Transfer(ctx, "o", "r", input) 3752 if err != nil { 3753 t.Errorf("Repositories.Transfer returned error: %v", err) 3754 } 3755 3756 want := &Repository{Owner: &User{Login: String("a")}} 3757 if !cmp.Equal(got, want) { 3758 t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want) 3759 } 3760 3761 const methodName = "Transfer" 3762 testBadOptions(t, methodName, func() (err error) { 3763 _, _, err = client.Repositories.Transfer(ctx, "\n", "\n", input) 3764 return err 3765 }) 3766 3767 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3768 got, resp, err := client.Repositories.Transfer(ctx, "o", "r", input) 3769 if got != nil { 3770 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3771 } 3772 return resp, err 3773 }) 3774 } 3775 3776 func TestRepositoriesService_Dispatch(t *testing.T) { 3777 client, mux, _, teardown := setup() 3778 defer teardown() 3779 3780 var input DispatchRequestOptions 3781 3782 mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) { 3783 var v DispatchRequestOptions 3784 assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) 3785 3786 testMethod(t, r, "POST") 3787 if !cmp.Equal(v, input) { 3788 t.Errorf("Request body = %+v, want %+v", v, input) 3789 } 3790 3791 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 3792 }) 3793 3794 ctx := context.Background() 3795 3796 testCases := []interface{}{ 3797 nil, 3798 struct { 3799 Foo string 3800 }{ 3801 Foo: "test", 3802 }, 3803 struct { 3804 Bar int 3805 }{ 3806 Bar: 42, 3807 }, 3808 struct { 3809 Foo string 3810 Bar int 3811 Baz bool 3812 }{ 3813 Foo: "test", 3814 Bar: 42, 3815 Baz: false, 3816 }, 3817 } 3818 3819 for _, tc := range testCases { 3820 if tc == nil { 3821 input = DispatchRequestOptions{EventType: "go"} 3822 } else { 3823 bytes, _ := json.Marshal(tc) 3824 payload := json.RawMessage(bytes) 3825 input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload} 3826 } 3827 3828 got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input) 3829 if err != nil { 3830 t.Errorf("Repositories.Dispatch returned error: %v", err) 3831 } 3832 3833 want := &Repository{Owner: &User{Login: String("a")}} 3834 if !cmp.Equal(got, want) { 3835 t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want) 3836 } 3837 } 3838 3839 const methodName = "Dispatch" 3840 testBadOptions(t, methodName, func() (err error) { 3841 _, _, err = client.Repositories.Dispatch(ctx, "\n", "\n", input) 3842 return err 3843 }) 3844 3845 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 3846 got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input) 3847 if got != nil { 3848 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 3849 } 3850 return resp, err 3851 }) 3852 } 3853 3854 func TestAdvancedSecurity_Marshal(t *testing.T) { 3855 testJSONMarshal(t, &AdvancedSecurity{}, "{}") 3856 3857 u := &AdvancedSecurity{ 3858 Status: String("status"), 3859 } 3860 3861 want := `{ 3862 "status": "status" 3863 }` 3864 3865 testJSONMarshal(t, u, want) 3866 } 3867 3868 func TestAuthorizedActorsOnly_Marshal(t *testing.T) { 3869 testJSONMarshal(t, &AuthorizedActorsOnly{}, "{}") 3870 3871 u := &AuthorizedActorsOnly{ 3872 From: Bool(true), 3873 } 3874 3875 want := `{ 3876 "from" : true 3877 }` 3878 3879 testJSONMarshal(t, u, want) 3880 } 3881 3882 func TestDispatchRequestOptions_Marshal(t *testing.T) { 3883 testJSONMarshal(t, &DispatchRequestOptions{}, "{}") 3884 3885 cp := json.RawMessage(`{"testKey":"testValue"}`) 3886 u := &DispatchRequestOptions{ 3887 EventType: "test_event_type", 3888 ClientPayload: &cp, 3889 } 3890 3891 want := `{ 3892 "event_type": "test_event_type", 3893 "client_payload": { 3894 "testKey": "testValue" 3895 } 3896 }` 3897 3898 testJSONMarshal(t, u, want) 3899 } 3900 3901 func TestTransferRequest_Marshal(t *testing.T) { 3902 testJSONMarshal(t, &TransferRequest{}, "{}") 3903 3904 u := &TransferRequest{ 3905 NewOwner: "testOwner", 3906 NewName: String("testName"), 3907 TeamID: []int64{1, 2}, 3908 } 3909 3910 want := `{ 3911 "new_owner": "testOwner", 3912 "new_name": "testName", 3913 "team_ids": [1,2] 3914 }` 3915 3916 testJSONMarshal(t, u, want) 3917 } 3918 3919 func TestSignaturesProtectedBranch_Marshal(t *testing.T) { 3920 testJSONMarshal(t, &SignaturesProtectedBranch{}, "{}") 3921 3922 u := &SignaturesProtectedBranch{ 3923 URL: String("https://www.testURL.in"), 3924 Enabled: Bool(false), 3925 } 3926 3927 want := `{ 3928 "url": "https://www.testURL.in", 3929 "enabled": false 3930 }` 3931 3932 testJSONMarshal(t, u, want) 3933 3934 u2 := &SignaturesProtectedBranch{ 3935 URL: String("testURL"), 3936 Enabled: Bool(true), 3937 } 3938 3939 want2 := `{ 3940 "url": "testURL", 3941 "enabled": true 3942 }` 3943 3944 testJSONMarshal(t, u2, want2) 3945 } 3946 3947 func TestDismissalRestrictionsRequest_Marshal(t *testing.T) { 3948 testJSONMarshal(t, &DismissalRestrictionsRequest{}, "{}") 3949 3950 u := &DismissalRestrictionsRequest{ 3951 Users: &[]string{"user1", "user2"}, 3952 Teams: &[]string{"team1", "team2"}, 3953 Apps: &[]string{"app1", "app2"}, 3954 } 3955 3956 want := `{ 3957 "users": ["user1","user2"], 3958 "teams": ["team1","team2"], 3959 "apps": ["app1","app2"] 3960 }` 3961 3962 testJSONMarshal(t, u, want) 3963 } 3964 3965 func TestAdminEnforcement_Marshal(t *testing.T) { 3966 testJSONMarshal(t, &AdminEnforcement{}, "{}") 3967 3968 u := &AdminEnforcement{ 3969 URL: String("https://www.test-url.in"), 3970 Enabled: false, 3971 } 3972 3973 want := `{ 3974 "url": "https://www.test-url.in", 3975 "enabled": false 3976 }` 3977 3978 testJSONMarshal(t, u, want) 3979 } 3980 3981 func TestPullRequestReviewsEnforcementUpdate_Marshal(t *testing.T) { 3982 testJSONMarshal(t, &PullRequestReviewsEnforcementUpdate{}, "{}") 3983 3984 u := &PullRequestReviewsEnforcementUpdate{ 3985 BypassPullRequestAllowancesRequest: &BypassPullRequestAllowancesRequest{ 3986 Users: []string{"user1", "user2"}, 3987 Teams: []string{"team1", "team2"}, 3988 Apps: []string{"app1", "app2"}, 3989 }, 3990 DismissStaleReviews: Bool(false), 3991 RequireCodeOwnerReviews: Bool(true), 3992 RequiredApprovingReviewCount: 2, 3993 } 3994 3995 want := `{ 3996 "bypass_pull_request_allowances": { 3997 "users": ["user1","user2"], 3998 "teams": ["team1","team2"], 3999 "apps": ["app1","app2"] 4000 }, 4001 "dismiss_stale_reviews": false, 4002 "require_code_owner_reviews": true, 4003 "required_approving_review_count": 2 4004 }` 4005 4006 testJSONMarshal(t, u, want) 4007 } 4008 4009 func TestRequiredStatusCheck_Marshal(t *testing.T) { 4010 testJSONMarshal(t, &RequiredStatusCheck{}, "{}") 4011 4012 u := &RequiredStatusCheck{ 4013 Context: "ctx", 4014 AppID: Int64(1), 4015 } 4016 4017 want := `{ 4018 "context": "ctx", 4019 "app_id": 1 4020 }` 4021 4022 testJSONMarshal(t, u, want) 4023 } 4024 4025 func TestRepositoryTag_Marshal(t *testing.T) { 4026 testJSONMarshal(t, &RepositoryTag{}, "{}") 4027 4028 u := &RepositoryTag{ 4029 Name: String("v0.1"), 4030 Commit: &Commit{ 4031 SHA: String("sha"), 4032 URL: String("url"), 4033 }, 4034 ZipballURL: String("zball"), 4035 TarballURL: String("tball"), 4036 } 4037 4038 want := `{ 4039 "name": "v0.1", 4040 "commit": { 4041 "sha": "sha", 4042 "url": "url" 4043 }, 4044 "zipball_url": "zball", 4045 "tarball_url": "tball" 4046 }` 4047 4048 testJSONMarshal(t, u, want) 4049 } 4050 4051 func TestRepositoriesService_EnablePrivateReporting(t *testing.T) { 4052 client, mux, _, teardown := setup() 4053 defer teardown() 4054 4055 mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) { 4056 testMethod(t, r, "PUT") 4057 w.WriteHeader(http.StatusNoContent) 4058 }) 4059 4060 ctx := context.Background() 4061 _, err := client.Repositories.EnablePrivateReporting(ctx, "owner", "repo") 4062 if err != nil { 4063 t.Errorf("Repositories.EnablePrivateReporting returned error: %v", err) 4064 } 4065 4066 const methodName = "EnablePrivateReporting" 4067 testBadOptions(t, methodName, func() (err error) { 4068 _, err = client.Repositories.EnablePrivateReporting(ctx, "\n", "\n") 4069 return err 4070 }) 4071 4072 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4073 return client.Repositories.EnablePrivateReporting(ctx, "owner", "repo") 4074 }) 4075 } 4076 4077 func TestRepositoriesService_DisablePrivateReporting(t *testing.T) { 4078 client, mux, _, teardown := setup() 4079 defer teardown() 4080 4081 mux.HandleFunc("/repos/owner/repo/private-vulnerability-reporting", func(w http.ResponseWriter, r *http.Request) { 4082 testMethod(t, r, "DELETE") 4083 w.WriteHeader(http.StatusNoContent) 4084 }) 4085 4086 ctx := context.Background() 4087 _, err := client.Repositories.DisablePrivateReporting(ctx, "owner", "repo") 4088 if err != nil { 4089 t.Errorf("Repositories.DisablePrivateReporting returned error: %v", err) 4090 } 4091 4092 const methodName = "DisablePrivateReporting" 4093 testBadOptions(t, methodName, func() (err error) { 4094 _, err = client.Repositories.DisablePrivateReporting(ctx, "\n", "\n") 4095 return err 4096 }) 4097 4098 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 4099 return client.Repositories.DisablePrivateReporting(ctx, "owner", "repo") 4100 }) 4101 }