github.com/google/go-github/v33@v33.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 "fmt" 12 "net/http" 13 "reflect" 14 "strings" 15 "testing" 16 "time" 17 ) 18 19 func TestRepositoriesService_List_authenticatedUser(t *testing.T) { 20 client, mux, _, teardown := setup() 21 defer teardown() 22 23 wantAcceptHeaders := []string{mediaTypeTopicsPreview} 24 mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { 25 testMethod(t, r, "GET") 26 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 27 fmt.Fprint(w, `[{"id":1},{"id":2}]`) 28 }) 29 30 ctx := context.Background() 31 got, _, err := client.Repositories.List(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 !reflect.DeepEqual(got, want) { 38 t.Errorf("Repositories.List returned %+v, want %+v", got, want) 39 } 40 41 // Test addOptions failure 42 _, _, err = client.Repositories.List(ctx, "\n", &RepositoryListOptions{}) 43 if err == nil { 44 t.Error("bad options List err = nil, want error") 45 } 46 47 // Test s.client.Do failure 48 client.BaseURL.Path = "/api-v3/" 49 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 50 got, resp, err := client.Repositories.List(ctx, "", nil) 51 if got != nil { 52 t.Errorf("rate.Reset.Time > now List = %#v, want nil", got) 53 } 54 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 55 t.Errorf("rate.Reset.Time > now List resp = %#v, want StatusCode=%v", resp.Response, want) 56 } 57 if err == nil { 58 t.Error("rate.Reset.Time > now List err = nil, want error") 59 } 60 } 61 62 func TestRepositoriesService_List_specifiedUser(t *testing.T) { 63 client, mux, _, teardown := setup() 64 defer teardown() 65 66 wantAcceptHeaders := []string{mediaTypeTopicsPreview} 67 mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) { 68 testMethod(t, r, "GET") 69 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 70 testFormValues(t, r, values{ 71 "visibility": "public", 72 "affiliation": "owner,collaborator", 73 "sort": "created", 74 "direction": "asc", 75 "page": "2", 76 }) 77 fmt.Fprint(w, `[{"id":1}]`) 78 }) 79 80 opt := &RepositoryListOptions{ 81 Visibility: "public", 82 Affiliation: "owner,collaborator", 83 Sort: "created", 84 Direction: "asc", 85 ListOptions: ListOptions{Page: 2}, 86 } 87 repos, _, err := client.Repositories.List(context.Background(), "u", opt) 88 if err != nil { 89 t.Errorf("Repositories.List returned error: %v", err) 90 } 91 92 want := []*Repository{{ID: Int64(1)}} 93 if !reflect.DeepEqual(repos, want) { 94 t.Errorf("Repositories.List returned %+v, want %+v", repos, want) 95 } 96 } 97 98 func TestRepositoriesService_List_specifiedUser_type(t *testing.T) { 99 client, mux, _, teardown := setup() 100 defer teardown() 101 102 wantAcceptHeaders := []string{mediaTypeTopicsPreview} 103 mux.HandleFunc("/users/u/repos", func(w http.ResponseWriter, r *http.Request) { 104 testMethod(t, r, "GET") 105 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 106 testFormValues(t, r, values{ 107 "type": "owner", 108 }) 109 fmt.Fprint(w, `[{"id":1}]`) 110 }) 111 112 opt := &RepositoryListOptions{ 113 Type: "owner", 114 } 115 repos, _, err := client.Repositories.List(context.Background(), "u", opt) 116 if err != nil { 117 t.Errorf("Repositories.List returned error: %v", err) 118 } 119 120 want := []*Repository{{ID: Int64(1)}} 121 if !reflect.DeepEqual(repos, want) { 122 t.Errorf("Repositories.List returned %+v, want %+v", repos, want) 123 } 124 } 125 126 func TestRepositoriesService_List_invalidUser(t *testing.T) { 127 client, _, _, teardown := setup() 128 defer teardown() 129 130 _, _, err := client.Repositories.List(context.Background(), "%", nil) 131 testURLParseError(t, err) 132 } 133 134 func TestRepositoriesService_ListByOrg(t *testing.T) { 135 client, mux, _, teardown := setup() 136 defer teardown() 137 138 wantAcceptHeaders := []string{mediaTypeTopicsPreview} 139 mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) { 140 testMethod(t, r, "GET") 141 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 142 testFormValues(t, r, values{ 143 "type": "forks", 144 "page": "2", 145 }) 146 fmt.Fprint(w, `[{"id":1}]`) 147 }) 148 149 ctx := context.Background() 150 opt := &RepositoryListByOrgOptions{ 151 Type: "forks", 152 ListOptions: ListOptions{Page: 2}, 153 } 154 got, _, err := client.Repositories.ListByOrg(ctx, "o", opt) 155 if err != nil { 156 t.Errorf("Repositories.ListByOrg returned error: %v", err) 157 } 158 159 want := []*Repository{{ID: Int64(1)}} 160 if !reflect.DeepEqual(got, want) { 161 t.Errorf("Repositories.ListByOrg returned %+v, want %+v", got, want) 162 } 163 164 // Test addOptions failure 165 _, _, err = client.Repositories.ListByOrg(ctx, "\n", opt) 166 if err == nil { 167 t.Error("bad options ListByOrg err = nil, want error") 168 } 169 170 // Test s.client.Do failure 171 client.BaseURL.Path = "/api-v3/" 172 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 173 got, resp, err := client.Repositories.ListByOrg(ctx, "o", opt) 174 if got != nil { 175 t.Errorf("rate.Reset.Time > now ListByOrg = %#v, want nil", got) 176 } 177 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 178 t.Errorf("rate.Reset.Time > now ListByOrg resp = %#v, want StatusCode=%v", resp.Response, want) 179 } 180 if err == nil { 181 t.Error("rate.Reset.Time > now ListByOrg err = nil, want error") 182 } 183 } 184 185 func TestRepositoriesService_ListByOrg_invalidOrg(t *testing.T) { 186 client, _, _, teardown := setup() 187 defer teardown() 188 189 _, _, err := client.Repositories.ListByOrg(context.Background(), "%", nil) 190 testURLParseError(t, err) 191 } 192 193 func TestRepositoriesService_ListAll(t *testing.T) { 194 client, mux, _, teardown := setup() 195 defer teardown() 196 197 mux.HandleFunc("/repositories", func(w http.ResponseWriter, r *http.Request) { 198 testMethod(t, r, "GET") 199 testFormValues(t, r, values{ 200 "since": "1", 201 }) 202 fmt.Fprint(w, `[{"id":1}]`) 203 }) 204 205 ctx := context.Background() 206 opt := &RepositoryListAllOptions{1} 207 got, _, err := client.Repositories.ListAll(ctx, opt) 208 if err != nil { 209 t.Errorf("Repositories.ListAll returned error: %v", err) 210 } 211 212 want := []*Repository{{ID: Int64(1)}} 213 if !reflect.DeepEqual(got, want) { 214 t.Errorf("Repositories.ListAll returned %+v, want %+v", got, want) 215 } 216 217 // Test s.client.NewRequest failure 218 client.BaseURL.Path = "" 219 got, resp, err := client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) 220 if got != nil { 221 t.Errorf("client.BaseURL.Path='' ListAll = %#v, want nil", got) 222 } 223 if resp != nil { 224 t.Errorf("client.BaseURL.Path='' ListAll resp = %#v, want nil", resp) 225 } 226 if err == nil { 227 t.Error("client.BaseURL.Path='' ListAll err = nil, want error") 228 } 229 230 // Test s.client.Do failure 231 client.BaseURL.Path = "/api-v3/" 232 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 233 got, resp, err = client.Repositories.ListAll(ctx, &RepositoryListAllOptions{1}) 234 if got != nil { 235 t.Errorf("rate.Reset.Time > now ListAll = %#v, want nil", got) 236 } 237 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 238 t.Errorf("rate.Reset.Time > now ListAll resp = %#v, want StatusCode=%v", resp.Response, want) 239 } 240 if err == nil { 241 t.Error("rate.Reset.Time > now ListAll err = nil, want error") 242 } 243 } 244 245 func TestRepositoriesService_Create_user(t *testing.T) { 246 client, mux, _, teardown := setup() 247 defer teardown() 248 249 input := &Repository{ 250 Name: String("n"), 251 Archived: Bool(true), // not passed along. 252 } 253 254 wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 255 mux.HandleFunc("/user/repos", func(w http.ResponseWriter, r *http.Request) { 256 v := new(createRepoRequest) 257 json.NewDecoder(r.Body).Decode(v) 258 259 testMethod(t, r, "POST") 260 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 261 want := &createRepoRequest{Name: String("n")} 262 if !reflect.DeepEqual(v, want) { 263 t.Errorf("Request body = %+v, want %+v", v, want) 264 } 265 266 fmt.Fprint(w, `{"id":1}`) 267 }) 268 269 ctx := context.Background() 270 got, _, err := client.Repositories.Create(ctx, "", input) 271 if err != nil { 272 t.Errorf("Repositories.Create returned error: %v", err) 273 } 274 275 want := &Repository{ID: Int64(1)} 276 if !reflect.DeepEqual(got, want) { 277 t.Errorf("Repositories.Create returned %+v, want %+v", got, want) 278 } 279 280 // Test s.client.NewRequest failure 281 client.BaseURL.Path = "" 282 got, resp, err := client.Repositories.Create(ctx, "", input) 283 if got != nil { 284 t.Errorf("client.BaseURL.Path='' Create = %#v, want nil", got) 285 } 286 if resp != nil { 287 t.Errorf("client.BaseURL.Path='' Create resp = %#v, want nil", resp) 288 } 289 if err == nil { 290 t.Error("client.BaseURL.Path='' Create err = nil, want error") 291 } 292 293 // Test s.client.Do failure 294 client.BaseURL.Path = "/api-v3/" 295 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 296 got, resp, err = client.Repositories.Create(ctx, "", input) 297 if got != nil { 298 t.Errorf("rate.Reset.Time > now Create = %#v, want nil", got) 299 } 300 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 301 t.Errorf("rate.Reset.Time > now Create resp = %#v, want StatusCode=%v", resp.Response, want) 302 } 303 if err == nil { 304 t.Error("rate.Reset.Time > now Create err = nil, want error") 305 } 306 } 307 308 func TestRepositoriesService_Create_org(t *testing.T) { 309 client, mux, _, teardown := setup() 310 defer teardown() 311 312 input := &Repository{ 313 Name: String("n"), 314 Archived: Bool(true), // not passed along. 315 } 316 317 wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 318 mux.HandleFunc("/orgs/o/repos", func(w http.ResponseWriter, r *http.Request) { 319 v := new(createRepoRequest) 320 json.NewDecoder(r.Body).Decode(v) 321 322 testMethod(t, r, "POST") 323 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 324 want := &createRepoRequest{Name: String("n")} 325 if !reflect.DeepEqual(v, want) { 326 t.Errorf("Request body = %+v, want %+v", v, want) 327 } 328 329 fmt.Fprint(w, `{"id":1}`) 330 }) 331 332 repo, _, err := client.Repositories.Create(context.Background(), "o", input) 333 if err != nil { 334 t.Errorf("Repositories.Create returned error: %v", err) 335 } 336 337 want := &Repository{ID: Int64(1)} 338 if !reflect.DeepEqual(repo, want) { 339 t.Errorf("Repositories.Create returned %+v, want %+v", repo, want) 340 } 341 } 342 343 func TestRepositoriesService_CreateFromTemplate(t *testing.T) { 344 client, mux, _, teardown := setup() 345 defer teardown() 346 347 templateRepoReq := &TemplateRepoRequest{ 348 Name: String("n"), 349 } 350 351 mux.HandleFunc("/repos/to/tr/generate", func(w http.ResponseWriter, r *http.Request) { 352 v := new(TemplateRepoRequest) 353 json.NewDecoder(r.Body).Decode(v) 354 355 testMethod(t, r, "POST") 356 testHeader(t, r, "Accept", mediaTypeRepositoryTemplatePreview) 357 want := &TemplateRepoRequest{Name: String("n")} 358 if !reflect.DeepEqual(v, want) { 359 t.Errorf("Request body = %+v, want %+v", v, want) 360 } 361 362 fmt.Fprint(w, `{"id":1,"name":"n"}`) 363 }) 364 365 ctx := context.Background() 366 got, _, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) 367 if err != nil { 368 t.Errorf("Repositories.CreateFromTemplate returned error: %v", err) 369 } 370 371 want := &Repository{ID: Int64(1), Name: String("n")} 372 if !reflect.DeepEqual(got, want) { 373 t.Errorf("Repositories.CreateFromTemplate returned %+v, want %+v", got, want) 374 } 375 376 // Test s.client.NewRequest failure 377 client.BaseURL.Path = "" 378 got, resp, err := client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) 379 if got != nil { 380 t.Errorf("client.BaseURL.Path='' CreateFromTemplate = %#v, want nil", got) 381 } 382 if resp != nil { 383 t.Errorf("client.BaseURL.Path='' CreateFromTemplate resp = %#v, want nil", resp) 384 } 385 if err == nil { 386 t.Error("client.BaseURL.Path='' CreateFromTemplate err = nil, want error") 387 } 388 389 // Test s.client.Do failure 390 client.BaseURL.Path = "/api-v3/" 391 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 392 got, resp, err = client.Repositories.CreateFromTemplate(ctx, "to", "tr", templateRepoReq) 393 if got != nil { 394 t.Errorf("rate.Reset.Time > now CreateFromTemplate = %#v, want nil", got) 395 } 396 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 397 t.Errorf("rate.Reset.Time > now CreateFromTemplate resp = %#v, want StatusCode=%v", resp.Response, want) 398 } 399 if err == nil { 400 t.Error("rate.Reset.Time > now CreateFromTemplate err = nil, want error") 401 } 402 } 403 404 func TestRepositoriesService_Get(t *testing.T) { 405 client, mux, _, teardown := setup() 406 defer teardown() 407 408 wantAcceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview, mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 409 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 410 testMethod(t, r, "GET") 411 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 412 fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`) 413 }) 414 415 ctx := context.Background() 416 got, _, err := client.Repositories.Get(ctx, "o", "r") 417 if err != nil { 418 t.Errorf("Repositories.Get returned error: %v", err) 419 } 420 421 want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}} 422 if !reflect.DeepEqual(got, want) { 423 t.Errorf("Repositories.Get returned %+v, want %+v", got, want) 424 } 425 426 // Test s.client.Do failure 427 client.BaseURL.Path = "/api-v3/" 428 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 429 got, resp, err := client.Repositories.Get(ctx, "o", "r") 430 if got != nil { 431 t.Errorf("rate.Reset.Time > now Get = %#v, want nil", got) 432 } 433 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 434 t.Errorf("rate.Reset.Time > now Get resp = %#v, want StatusCode=%v", resp.Response, want) 435 } 436 if err == nil { 437 t.Error("rate.Reset.Time > now Get err = nil, want error") 438 } 439 } 440 441 func TestRepositoriesService_GetCodeOfConduct(t *testing.T) { 442 client, mux, _, teardown := setup() 443 defer teardown() 444 445 mux.HandleFunc("/repos/o/r/community/code_of_conduct", func(w http.ResponseWriter, r *http.Request) { 446 testMethod(t, r, "GET") 447 testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview) 448 fmt.Fprint(w, `{ 449 "key": "key", 450 "name": "name", 451 "url": "url", 452 "body": "body"}`, 453 ) 454 }) 455 456 ctx := context.Background() 457 got, _, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") 458 if err != nil { 459 t.Errorf("Repositories.GetCodeOfConduct returned error: %v", err) 460 } 461 462 want := &CodeOfConduct{ 463 Key: String("key"), 464 Name: String("name"), 465 URL: String("url"), 466 Body: String("body"), 467 } 468 469 if !reflect.DeepEqual(got, want) { 470 t.Errorf("Repositories.GetCodeOfConduct returned %+v, want %+v", got, want) 471 } 472 473 // Test s.client.NewRequest failure 474 client.BaseURL.Path = "" 475 got, resp, err := client.Repositories.GetCodeOfConduct(ctx, "o", "r") 476 if got != nil { 477 t.Errorf("client.BaseURL.Path='' GetCodeOfConduct = %#v, want nil", got) 478 } 479 if resp != nil { 480 t.Errorf("client.BaseURL.Path='' GetCodeOfConduct resp = %#v, want nil", resp) 481 } 482 if err == nil { 483 t.Error("client.BaseURL.Path='' GetCodeOfConduct err = nil, want error") 484 } 485 486 // Test s.client.Do failure 487 client.BaseURL.Path = "/api-v3/" 488 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 489 got, resp, err = client.Repositories.GetCodeOfConduct(ctx, "o", "r") 490 if got != nil { 491 t.Errorf("rate.Reset.Time > now GetCodeOfConduct = %#v, want nil", got) 492 } 493 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 494 t.Errorf("rate.Reset.Time > now GetCodeOfConduct resp = %#v, want StatusCode=%v", resp.Response, want) 495 } 496 if err == nil { 497 t.Error("rate.Reset.Time > now GetCodeOfConduct err = nil, want error") 498 } 499 } 500 501 func TestRepositoriesService_GetByID(t *testing.T) { 502 client, mux, _, teardown := setup() 503 defer teardown() 504 505 mux.HandleFunc("/repositories/1", func(w http.ResponseWriter, r *http.Request) { 506 testMethod(t, r, "GET") 507 fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`) 508 }) 509 510 ctx := context.Background() 511 got, _, err := client.Repositories.GetByID(ctx, 1) 512 if err != nil { 513 t.Fatalf("Repositories.GetByID returned error: %v", err) 514 } 515 516 want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}} 517 if !reflect.DeepEqual(got, want) { 518 t.Errorf("Repositories.GetByID returned %+v, want %+v", got, want) 519 } 520 521 // Test s.client.NewRequest failure 522 client.BaseURL.Path = "" 523 got, resp, err := client.Repositories.GetByID(ctx, 1) 524 if got != nil { 525 t.Errorf("client.BaseURL.Path='' GetByID = %#v, want nil", got) 526 } 527 if resp != nil { 528 t.Errorf("client.BaseURL.Path='' GetByID resp = %#v, want nil", resp) 529 } 530 if err == nil { 531 t.Error("client.BaseURL.Path='' GetByID err = nil, want error") 532 } 533 534 // Test s.client.Do failure 535 client.BaseURL.Path = "/api-v3/" 536 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 537 got, resp, err = client.Repositories.GetByID(ctx, 1) 538 if got != nil { 539 t.Errorf("rate.Reset.Time > now GetByID = %#v, want nil", got) 540 } 541 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 542 t.Errorf("rate.Reset.Time > now GetByID resp = %#v, want StatusCode=%v", resp.Response, want) 543 } 544 if err == nil { 545 t.Error("rate.Reset.Time > now GetByID err = nil, want error") 546 } 547 } 548 549 func TestRepositoriesService_Edit(t *testing.T) { 550 client, mux, _, teardown := setup() 551 defer teardown() 552 553 i := true 554 input := &Repository{HasIssues: &i} 555 556 wantAcceptHeaders := []string{mediaTypeRepositoryTemplatePreview, mediaTypeRepositoryVisibilityPreview} 557 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 558 v := new(Repository) 559 json.NewDecoder(r.Body).Decode(v) 560 561 testMethod(t, r, "PATCH") 562 testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) 563 if !reflect.DeepEqual(v, input) { 564 t.Errorf("Request body = %+v, want %+v", v, input) 565 } 566 fmt.Fprint(w, `{"id":1}`) 567 }) 568 569 ctx := context.Background() 570 got, _, err := client.Repositories.Edit(ctx, "o", "r", input) 571 if err != nil { 572 t.Errorf("Repositories.Edit returned error: %v", err) 573 } 574 575 want := &Repository{ID: Int64(1)} 576 if !reflect.DeepEqual(got, want) { 577 t.Errorf("Repositories.Edit returned %+v, want %+v", got, want) 578 } 579 580 // Test s.client.Do failure 581 client.BaseURL.Path = "/api-v3/" 582 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 583 got, resp, err := client.Repositories.Edit(ctx, "o", "r", input) 584 if got != nil { 585 t.Errorf("rate.Reset.Time > now Edit = %#v, want nil", got) 586 } 587 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 588 t.Errorf("rate.Reset.Time > now Edit resp = %#v, want StatusCode=%v", resp.Response, want) 589 } 590 if err == nil { 591 t.Error("rate.Reset.Time > now Edit err = nil, want error") 592 } 593 } 594 595 func TestRepositoriesService_Delete(t *testing.T) { 596 client, mux, _, teardown := setup() 597 defer teardown() 598 599 mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { 600 testMethod(t, r, "DELETE") 601 }) 602 603 ctx := context.Background() 604 _, err := client.Repositories.Delete(ctx, "o", "r") 605 if err != nil { 606 t.Errorf("Repositories.Delete returned error: %v", err) 607 } 608 609 // Test s.client.NewRequest failure 610 client.BaseURL.Path = "" 611 resp, err := client.Repositories.Delete(ctx, "o", "r") 612 if resp != nil { 613 t.Errorf("client.BaseURL.Path='' Delete resp = %#v, want nil", resp) 614 } 615 if err == nil { 616 t.Error("client.BaseURL.Path='' Delete err = nil, want error") 617 } 618 } 619 620 func TestRepositoriesService_Get_invalidOwner(t *testing.T) { 621 client, _, _, teardown := setup() 622 defer teardown() 623 624 _, _, err := client.Repositories.Get(context.Background(), "%", "r") 625 testURLParseError(t, err) 626 } 627 628 func TestRepositoriesService_Edit_invalidOwner(t *testing.T) { 629 client, _, _, teardown := setup() 630 defer teardown() 631 632 _, _, err := client.Repositories.Edit(context.Background(), "%", "r", nil) 633 testURLParseError(t, err) 634 } 635 636 func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) { 637 client, mux, _, teardown := setup() 638 defer teardown() 639 640 mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { 641 testMethod(t, r, "GET") 642 testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 643 644 w.WriteHeader(http.StatusNoContent) 645 }) 646 647 vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(context.Background(), "o", "r") 648 if err != nil { 649 t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err) 650 } 651 652 if want := true; vulnerabilityAlertsEnabled != want { 653 t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want) 654 } 655 } 656 657 func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) { 658 client, mux, _, teardown := setup() 659 defer teardown() 660 661 mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { 662 testMethod(t, r, "PUT") 663 testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 664 665 w.WriteHeader(http.StatusNoContent) 666 }) 667 668 if _, err := client.Repositories.EnableVulnerabilityAlerts(context.Background(), "o", "r"); err != nil { 669 t.Errorf("Repositories.EnableVulnerabilityAlerts returned error: %v", err) 670 } 671 } 672 673 func TestRepositoriesService_DisableVulnerabilityAlerts(t *testing.T) { 674 client, mux, _, teardown := setup() 675 defer teardown() 676 677 mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) { 678 testMethod(t, r, "DELETE") 679 testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview) 680 681 w.WriteHeader(http.StatusNoContent) 682 }) 683 684 if _, err := client.Repositories.DisableVulnerabilityAlerts(context.Background(), "o", "r"); err != nil { 685 t.Errorf("Repositories.DisableVulnerabilityAlerts returned error: %v", err) 686 } 687 } 688 689 func TestRepositoriesService_EnableAutomatedSecurityFixes(t *testing.T) { 690 client, mux, _, teardown := setup() 691 defer teardown() 692 693 mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { 694 testMethod(t, r, "PUT") 695 testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 696 697 w.WriteHeader(http.StatusNoContent) 698 }) 699 700 if _, err := client.Repositories.EnableAutomatedSecurityFixes(context.Background(), "o", "r"); err != nil { 701 t.Errorf("Repositories.EnableAutomatedSecurityFixes returned error: %v", err) 702 } 703 } 704 705 func TestRepositoriesService_DisableAutomatedSecurityFixes(t *testing.T) { 706 client, mux, _, teardown := setup() 707 defer teardown() 708 709 mux.HandleFunc("/repos/o/r/automated-security-fixes", func(w http.ResponseWriter, r *http.Request) { 710 testMethod(t, r, "DELETE") 711 testHeader(t, r, "Accept", mediaTypeRequiredAutomatedSecurityFixesPreview) 712 713 w.WriteHeader(http.StatusNoContent) 714 }) 715 716 if _, err := client.Repositories.DisableAutomatedSecurityFixes(context.Background(), "o", "r"); err != nil { 717 t.Errorf("Repositories.DisableAutomatedSecurityFixes returned error: %v", err) 718 } 719 } 720 721 func TestRepositoriesService_ListContributors(t *testing.T) { 722 client, mux, _, teardown := setup() 723 defer teardown() 724 725 mux.HandleFunc("/repos/o/r/contributors", func(w http.ResponseWriter, r *http.Request) { 726 testMethod(t, r, "GET") 727 testFormValues(t, r, values{ 728 "anon": "true", 729 "page": "2", 730 }) 731 fmt.Fprint(w, `[{"contributions":42}]`) 732 }) 733 734 opts := &ListContributorsOptions{Anon: "true", ListOptions: ListOptions{Page: 2}} 735 contributors, _, err := client.Repositories.ListContributors(context.Background(), "o", "r", opts) 736 if err != nil { 737 t.Errorf("Repositories.ListContributors returned error: %v", err) 738 } 739 740 want := []*Contributor{{Contributions: Int(42)}} 741 if !reflect.DeepEqual(contributors, want) { 742 t.Errorf("Repositories.ListContributors returned %+v, want %+v", contributors, want) 743 } 744 } 745 746 func TestRepositoriesService_ListLanguages(t *testing.T) { 747 client, mux, _, teardown := setup() 748 defer teardown() 749 750 mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) { 751 testMethod(t, r, "GET") 752 fmt.Fprint(w, `{"go":1}`) 753 }) 754 755 languages, _, err := client.Repositories.ListLanguages(context.Background(), "o", "r") 756 if err != nil { 757 t.Errorf("Repositories.ListLanguages returned error: %v", err) 758 } 759 760 want := map[string]int{"go": 1} 761 if !reflect.DeepEqual(languages, want) { 762 t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want) 763 } 764 } 765 766 func TestRepositoriesService_ListTeams(t *testing.T) { 767 client, mux, _, teardown := setup() 768 defer teardown() 769 770 mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) { 771 testMethod(t, r, "GET") 772 testFormValues(t, r, values{"page": "2"}) 773 fmt.Fprint(w, `[{"id":1}]`) 774 }) 775 776 opt := &ListOptions{Page: 2} 777 teams, _, err := client.Repositories.ListTeams(context.Background(), "o", "r", opt) 778 if err != nil { 779 t.Errorf("Repositories.ListTeams returned error: %v", err) 780 } 781 782 want := []*Team{{ID: Int64(1)}} 783 if !reflect.DeepEqual(teams, want) { 784 t.Errorf("Repositories.ListTeams returned %+v, want %+v", teams, want) 785 } 786 } 787 788 func TestRepositoriesService_ListTags(t *testing.T) { 789 client, mux, _, teardown := setup() 790 defer teardown() 791 792 mux.HandleFunc("/repos/o/r/tags", func(w http.ResponseWriter, r *http.Request) { 793 testMethod(t, r, "GET") 794 testFormValues(t, r, values{"page": "2"}) 795 fmt.Fprint(w, `[{"name":"n", "commit" : {"sha" : "s", "url" : "u"}, "zipball_url": "z", "tarball_url": "t"}]`) 796 }) 797 798 opt := &ListOptions{Page: 2} 799 tags, _, err := client.Repositories.ListTags(context.Background(), "o", "r", opt) 800 if err != nil { 801 t.Errorf("Repositories.ListTags returned error: %v", err) 802 } 803 804 want := []*RepositoryTag{ 805 { 806 Name: String("n"), 807 Commit: &Commit{ 808 SHA: String("s"), 809 URL: String("u"), 810 }, 811 ZipballURL: String("z"), 812 TarballURL: String("t"), 813 }, 814 } 815 if !reflect.DeepEqual(tags, want) { 816 t.Errorf("Repositories.ListTags returned %+v, want %+v", tags, want) 817 } 818 } 819 820 func TestRepositoriesService_ListBranches(t *testing.T) { 821 client, mux, _, teardown := setup() 822 defer teardown() 823 824 mux.HandleFunc("/repos/o/r/branches", func(w http.ResponseWriter, r *http.Request) { 825 testMethod(t, r, "GET") 826 // TODO: remove custom Accept header when this API fully launches 827 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 828 testFormValues(t, r, values{"page": "2"}) 829 fmt.Fprint(w, `[{"name":"master", "commit" : {"sha" : "a57781", "url" : "https://api.github.com/repos/o/r/commits/a57781"}}]`) 830 }) 831 832 opt := &BranchListOptions{ 833 Protected: nil, 834 ListOptions: ListOptions{Page: 2}, 835 } 836 branches, _, err := client.Repositories.ListBranches(context.Background(), "o", "r", opt) 837 if err != nil { 838 t.Errorf("Repositories.ListBranches returned error: %v", err) 839 } 840 841 want := []*Branch{{Name: String("master"), Commit: &RepositoryCommit{SHA: String("a57781"), URL: String("https://api.github.com/repos/o/r/commits/a57781")}}} 842 if !reflect.DeepEqual(branches, want) { 843 t.Errorf("Repositories.ListBranches returned %+v, want %+v", branches, want) 844 } 845 } 846 847 func TestRepositoriesService_GetBranch(t *testing.T) { 848 client, mux, _, teardown := setup() 849 defer teardown() 850 851 mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) { 852 testMethod(t, r, "GET") 853 // TODO: remove custom Accept header when this API fully launches 854 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 855 fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`) 856 }) 857 858 branch, _, err := client.Repositories.GetBranch(context.Background(), "o", "r", "b") 859 if err != nil { 860 t.Errorf("Repositories.GetBranch returned error: %v", err) 861 } 862 863 want := &Branch{ 864 Name: String("n"), 865 Commit: &RepositoryCommit{ 866 SHA: String("s"), 867 Commit: &Commit{ 868 Message: String("m"), 869 }, 870 }, 871 Protected: Bool(true), 872 } 873 874 if !reflect.DeepEqual(branch, want) { 875 t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want) 876 } 877 } 878 879 func TestRepositoriesService_GetBranchProtection(t *testing.T) { 880 client, mux, _, teardown := setup() 881 defer teardown() 882 883 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 884 v := new(ProtectionRequest) 885 json.NewDecoder(r.Body).Decode(v) 886 887 testMethod(t, r, "GET") 888 // TODO: remove custom Accept header when this API fully launches 889 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 890 fmt.Fprintf(w, `{ 891 "required_status_checks":{ 892 "strict":true, 893 "contexts":["continuous-integration"] 894 }, 895 "required_pull_request_reviews":{ 896 "dismissal_restrictions":{ 897 "users":[{ 898 "id":3, 899 "login":"u" 900 }], 901 "teams":[{ 902 "id":4, 903 "slug":"t" 904 }] 905 }, 906 "dismiss_stale_reviews":true, 907 "require_code_owner_reviews":true, 908 "required_approving_review_count":1 909 }, 910 "enforce_admins":{ 911 "url":"/repos/o/r/branches/b/protection/enforce_admins", 912 "enabled":true 913 }, 914 "restrictions":{ 915 "users":[{"id":1,"login":"u"}], 916 "teams":[{"id":2,"slug":"t"}] 917 } 918 }`) 919 }) 920 921 protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b") 922 if err != nil { 923 t.Errorf("Repositories.GetBranchProtection returned error: %v", err) 924 } 925 926 want := &Protection{ 927 RequiredStatusChecks: &RequiredStatusChecks{ 928 Strict: true, 929 Contexts: []string{"continuous-integration"}, 930 }, 931 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 932 DismissStaleReviews: true, 933 DismissalRestrictions: &DismissalRestrictions{ 934 Users: []*User{ 935 {Login: String("u"), ID: Int64(3)}, 936 }, 937 Teams: []*Team{ 938 {Slug: String("t"), ID: Int64(4)}, 939 }, 940 }, 941 RequireCodeOwnerReviews: true, 942 RequiredApprovingReviewCount: 1, 943 }, 944 EnforceAdmins: &AdminEnforcement{ 945 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 946 Enabled: true, 947 }, 948 Restrictions: &BranchRestrictions{ 949 Users: []*User{ 950 {Login: String("u"), ID: Int64(1)}, 951 }, 952 Teams: []*Team{ 953 {Slug: String("t"), ID: Int64(2)}, 954 }, 955 }, 956 } 957 if !reflect.DeepEqual(protection, want) { 958 t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) 959 } 960 } 961 962 func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) { 963 client, mux, _, teardown := setup() 964 defer teardown() 965 966 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 967 968 testMethod(t, r, "GET") 969 // TODO: remove custom Accept header when this API fully launches 970 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 971 fmt.Fprintf(w, `{ 972 "required_status_checks":{ 973 "strict":true, 974 "contexts":["continuous-integration"] 975 }, 976 "required_pull_request_reviews":{ 977 "dismiss_stale_reviews":true, 978 "require_code_owner_reviews":true, 979 "required_approving_review_count":1 980 }, 981 "enforce_admins":{ 982 "url":"/repos/o/r/branches/b/protection/enforce_admins", 983 "enabled":true 984 }, 985 "restrictions":{ 986 "users":[{"id":1,"login":"u"}], 987 "teams":[{"id":2,"slug":"t"}] 988 } 989 }`) 990 }) 991 992 protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b") 993 if err != nil { 994 t.Errorf("Repositories.GetBranchProtection returned error: %v", err) 995 } 996 997 want := &Protection{ 998 RequiredStatusChecks: &RequiredStatusChecks{ 999 Strict: true, 1000 Contexts: []string{"continuous-integration"}, 1001 }, 1002 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1003 DismissStaleReviews: true, 1004 DismissalRestrictions: nil, 1005 RequireCodeOwnerReviews: true, 1006 RequiredApprovingReviewCount: 1, 1007 }, 1008 EnforceAdmins: &AdminEnforcement{ 1009 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 1010 Enabled: true, 1011 }, 1012 Restrictions: &BranchRestrictions{ 1013 Users: []*User{ 1014 {Login: String("u"), ID: Int64(1)}, 1015 }, 1016 Teams: []*Team{ 1017 {Slug: String("t"), ID: Int64(2)}, 1018 }, 1019 }, 1020 } 1021 if !reflect.DeepEqual(protection, want) { 1022 t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want) 1023 } 1024 } 1025 1026 func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { 1027 client, mux, _, teardown := setup() 1028 defer teardown() 1029 1030 input := &ProtectionRequest{ 1031 RequiredStatusChecks: &RequiredStatusChecks{ 1032 Strict: true, 1033 Contexts: []string{"continuous-integration"}, 1034 }, 1035 RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ 1036 DismissStaleReviews: true, 1037 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1038 Users: &[]string{"uu"}, 1039 Teams: &[]string{"tt"}, 1040 }, 1041 }, 1042 Restrictions: &BranchRestrictionsRequest{ 1043 Users: []string{"u"}, 1044 Teams: []string{"t"}, 1045 Apps: []string{"a"}, 1046 }, 1047 } 1048 1049 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1050 v := new(ProtectionRequest) 1051 json.NewDecoder(r.Body).Decode(v) 1052 1053 testMethod(t, r, "PUT") 1054 if !reflect.DeepEqual(v, input) { 1055 t.Errorf("Request body = %+v, want %+v", v, input) 1056 } 1057 1058 // TODO: remove custom Accept header when this API fully launches 1059 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1060 fmt.Fprintf(w, `{ 1061 "required_status_checks":{ 1062 "strict":true, 1063 "contexts":["continuous-integration"] 1064 }, 1065 "required_pull_request_reviews":{ 1066 "dismissal_restrictions":{ 1067 "users":[{ 1068 "id":3, 1069 "login":"uu" 1070 }], 1071 "teams":[{ 1072 "id":4, 1073 "slug":"tt" 1074 }] 1075 }, 1076 "dismiss_stale_reviews":true, 1077 "require_code_owner_reviews":true 1078 }, 1079 "restrictions":{ 1080 "users":[{"id":1,"login":"u"}], 1081 "teams":[{"id":2,"slug":"t"}], 1082 "apps":[{"id":3,"slug":"a"}] 1083 } 1084 }`) 1085 }) 1086 1087 protection, _, err := client.Repositories.UpdateBranchProtection(context.Background(), "o", "r", "b", input) 1088 if err != nil { 1089 t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err) 1090 } 1091 1092 want := &Protection{ 1093 RequiredStatusChecks: &RequiredStatusChecks{ 1094 Strict: true, 1095 Contexts: []string{"continuous-integration"}, 1096 }, 1097 RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ 1098 DismissStaleReviews: true, 1099 DismissalRestrictions: &DismissalRestrictions{ 1100 Users: []*User{ 1101 {Login: String("uu"), ID: Int64(3)}, 1102 }, 1103 Teams: []*Team{ 1104 {Slug: String("tt"), ID: Int64(4)}, 1105 }, 1106 }, 1107 RequireCodeOwnerReviews: true, 1108 }, 1109 Restrictions: &BranchRestrictions{ 1110 Users: []*User{ 1111 {Login: String("u"), ID: Int64(1)}, 1112 }, 1113 Teams: []*Team{ 1114 {Slug: String("t"), ID: Int64(2)}, 1115 }, 1116 Apps: []*App{ 1117 {Slug: String("a"), ID: Int64(3)}, 1118 }, 1119 }, 1120 } 1121 if !reflect.DeepEqual(protection, want) { 1122 t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want) 1123 } 1124 } 1125 1126 func TestRepositoriesService_RemoveBranchProtection(t *testing.T) { 1127 client, mux, _, teardown := setup() 1128 defer teardown() 1129 1130 mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) { 1131 testMethod(t, r, "DELETE") 1132 // TODO: remove custom Accept header when this API fully launches 1133 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1134 w.WriteHeader(http.StatusNoContent) 1135 }) 1136 1137 _, err := client.Repositories.RemoveBranchProtection(context.Background(), "o", "r", "b") 1138 if err != nil { 1139 t.Errorf("Repositories.RemoveBranchProtection returned error: %v", err) 1140 } 1141 } 1142 1143 func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) { 1144 client, _, _, teardown := setup() 1145 defer teardown() 1146 1147 _, _, err := client.Repositories.ListLanguages(context.Background(), "%", "%") 1148 testURLParseError(t, err) 1149 } 1150 1151 func TestRepositoriesService_License(t *testing.T) { 1152 client, mux, _, teardown := setup() 1153 defer teardown() 1154 1155 mux.HandleFunc("/repos/o/r/license", func(w http.ResponseWriter, r *http.Request) { 1156 testMethod(t, r, "GET") 1157 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}}`) 1158 }) 1159 1160 got, _, err := client.Repositories.License(context.Background(), "o", "r") 1161 if err != nil { 1162 t.Errorf("Repositories.License returned error: %v", err) 1163 } 1164 1165 want := &RepositoryLicense{ 1166 Name: String("LICENSE"), 1167 Path: String("LICENSE"), 1168 License: &License{ 1169 Name: String("MIT License"), 1170 Key: String("mit"), 1171 SPDXID: String("MIT"), 1172 URL: String("https://api.github.com/licenses/mit"), 1173 Featured: Bool(true), 1174 }, 1175 } 1176 1177 if !reflect.DeepEqual(got, want) { 1178 t.Errorf("Repositories.License returned %+v, want %+v", got, want) 1179 } 1180 } 1181 1182 func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) { 1183 client, mux, _, teardown := setup() 1184 defer teardown() 1185 1186 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 1187 v := new(ProtectionRequest) 1188 json.NewDecoder(r.Body).Decode(v) 1189 1190 testMethod(t, r, "GET") 1191 // TODO: remove custom Accept header when this API fully launches 1192 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1193 fmt.Fprint(w, `{"strict": true,"contexts": ["x","y","z"]}`) 1194 }) 1195 1196 checks, _, err := client.Repositories.GetRequiredStatusChecks(context.Background(), "o", "r", "b") 1197 if err != nil { 1198 t.Errorf("Repositories.GetRequiredStatusChecks returned error: %v", err) 1199 } 1200 1201 want := &RequiredStatusChecks{ 1202 Strict: true, 1203 Contexts: []string{"x", "y", "z"}, 1204 } 1205 if !reflect.DeepEqual(checks, want) { 1206 t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want) 1207 } 1208 } 1209 1210 func TestRepositoriesService_UpdateRequiredStatusChecks(t *testing.T) { 1211 client, mux, _, teardown := setup() 1212 defer teardown() 1213 1214 input := &RequiredStatusChecksRequest{ 1215 Strict: Bool(true), 1216 Contexts: []string{"continuous-integration"}, 1217 } 1218 1219 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks", func(w http.ResponseWriter, r *http.Request) { 1220 v := new(RequiredStatusChecksRequest) 1221 json.NewDecoder(r.Body).Decode(v) 1222 1223 testMethod(t, r, "PATCH") 1224 if !reflect.DeepEqual(v, input) { 1225 t.Errorf("Request body = %+v, want %+v", v, input) 1226 } 1227 testHeader(t, r, "Accept", mediaTypeV3) 1228 fmt.Fprintf(w, `{"strict":true,"contexts":["continuous-integration"]}`) 1229 }) 1230 1231 statusChecks, _, err := client.Repositories.UpdateRequiredStatusChecks(context.Background(), "o", "r", "b", input) 1232 if err != nil { 1233 t.Errorf("Repositories.UpdateRequiredStatusChecks returned error: %v", err) 1234 } 1235 1236 want := &RequiredStatusChecks{ 1237 Strict: true, 1238 Contexts: []string{"continuous-integration"}, 1239 } 1240 if !reflect.DeepEqual(statusChecks, want) { 1241 t.Errorf("Repositories.UpdateRequiredStatusChecks returned %+v, want %+v", statusChecks, want) 1242 } 1243 } 1244 1245 func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) { 1246 client, mux, _, teardown := setup() 1247 defer teardown() 1248 1249 mux.HandleFunc("/repos/o/r/branches/b/protection/required_status_checks/contexts", func(w http.ResponseWriter, r *http.Request) { 1250 v := new(ProtectionRequest) 1251 json.NewDecoder(r.Body).Decode(v) 1252 1253 testMethod(t, r, "GET") 1254 // TODO: remove custom Accept header when this API fully launches 1255 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1256 fmt.Fprint(w, `["x", "y", "z"]`) 1257 }) 1258 1259 contexts, _, err := client.Repositories.ListRequiredStatusChecksContexts(context.Background(), "o", "r", "b") 1260 if err != nil { 1261 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned error: %v", err) 1262 } 1263 1264 want := []string{"x", "y", "z"} 1265 if !reflect.DeepEqual(contexts, want) { 1266 t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want) 1267 } 1268 } 1269 1270 func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { 1271 client, mux, _, teardown := setup() 1272 defer teardown() 1273 1274 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 1275 testMethod(t, r, "GET") 1276 // TODO: remove custom Accept header when this API fully launches 1277 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1278 fmt.Fprintf(w, `{ 1279 "dismissal_restrictions":{ 1280 "users":[{"id":1,"login":"u"}], 1281 "teams":[{"id":2,"slug":"t"}] 1282 }, 1283 "dismiss_stale_reviews":true, 1284 "require_code_owner_reviews":true, 1285 "required_approving_review_count":1 1286 }`) 1287 }) 1288 1289 enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(context.Background(), "o", "r", "b") 1290 if err != nil { 1291 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err) 1292 } 1293 1294 want := &PullRequestReviewsEnforcement{ 1295 DismissStaleReviews: true, 1296 DismissalRestrictions: &DismissalRestrictions{ 1297 Users: []*User{ 1298 {Login: String("u"), ID: Int64(1)}, 1299 }, 1300 Teams: []*Team{ 1301 {Slug: String("t"), ID: Int64(2)}, 1302 }, 1303 }, 1304 RequireCodeOwnerReviews: true, 1305 RequiredApprovingReviewCount: 1, 1306 } 1307 1308 if !reflect.DeepEqual(enforcement, want) { 1309 t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 1310 } 1311 } 1312 1313 func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { 1314 client, mux, _, teardown := setup() 1315 defer teardown() 1316 1317 input := &PullRequestReviewsEnforcementUpdate{ 1318 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1319 Users: &[]string{"u"}, 1320 Teams: &[]string{"t"}, 1321 }, 1322 } 1323 1324 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 1325 v := new(PullRequestReviewsEnforcementUpdate) 1326 json.NewDecoder(r.Body).Decode(v) 1327 1328 testMethod(t, r, "PATCH") 1329 if !reflect.DeepEqual(v, input) { 1330 t.Errorf("Request body = %+v, want %+v", v, input) 1331 } 1332 // TODO: remove custom Accept header when this API fully launches 1333 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1334 fmt.Fprintf(w, `{ 1335 "dismissal_restrictions":{ 1336 "users":[{"id":1,"login":"u"}], 1337 "teams":[{"id":2,"slug":"t"}] 1338 }, 1339 "dismiss_stale_reviews":true, 1340 "require_code_owner_reviews":true, 1341 "required_approving_review_count":3 1342 }`) 1343 }) 1344 1345 enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(context.Background(), "o", "r", "b", input) 1346 if err != nil { 1347 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err) 1348 } 1349 1350 want := &PullRequestReviewsEnforcement{ 1351 DismissStaleReviews: true, 1352 DismissalRestrictions: &DismissalRestrictions{ 1353 Users: []*User{ 1354 {Login: String("u"), ID: Int64(1)}, 1355 }, 1356 Teams: []*Team{ 1357 {Slug: String("t"), ID: Int64(2)}, 1358 }, 1359 }, 1360 RequireCodeOwnerReviews: true, 1361 RequiredApprovingReviewCount: 3, 1362 } 1363 if !reflect.DeepEqual(enforcement, want) { 1364 t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) 1365 } 1366 } 1367 1368 func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { 1369 client, mux, _, teardown := setup() 1370 defer teardown() 1371 1372 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 1373 testMethod(t, r, "PATCH") 1374 // TODO: remove custom Accept header when this API fully launches 1375 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1376 testBody(t, r, `{"dismissal_restrictions":{}}`+"\n") 1377 fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`) 1378 }) 1379 1380 enforcement, _, err := client.Repositories.DisableDismissalRestrictions(context.Background(), "o", "r", "b") 1381 if err != nil { 1382 t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err) 1383 } 1384 1385 want := &PullRequestReviewsEnforcement{ 1386 DismissStaleReviews: true, 1387 DismissalRestrictions: nil, 1388 RequireCodeOwnerReviews: true, 1389 RequiredApprovingReviewCount: 1, 1390 } 1391 if !reflect.DeepEqual(enforcement, want) { 1392 t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want) 1393 } 1394 } 1395 1396 func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { 1397 client, mux, _, teardown := setup() 1398 defer teardown() 1399 1400 mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { 1401 testMethod(t, r, "DELETE") 1402 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1403 w.WriteHeader(http.StatusNoContent) 1404 }) 1405 1406 _, err := client.Repositories.RemovePullRequestReviewEnforcement(context.Background(), "o", "r", "b") 1407 if err != nil { 1408 t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err) 1409 } 1410 } 1411 1412 func TestRepositoriesService_GetAdminEnforcement(t *testing.T) { 1413 client, mux, _, teardown := setup() 1414 defer teardown() 1415 1416 mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { 1417 testMethod(t, r, "GET") 1418 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1419 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 1420 }) 1421 1422 enforcement, _, err := client.Repositories.GetAdminEnforcement(context.Background(), "o", "r", "b") 1423 if err != nil { 1424 t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err) 1425 } 1426 1427 want := &AdminEnforcement{ 1428 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 1429 Enabled: true, 1430 } 1431 1432 if !reflect.DeepEqual(enforcement, want) { 1433 t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want) 1434 } 1435 } 1436 1437 func TestRepositoriesService_AddAdminEnforcement(t *testing.T) { 1438 client, mux, _, teardown := setup() 1439 defer teardown() 1440 1441 mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { 1442 testMethod(t, r, "POST") 1443 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1444 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) 1445 }) 1446 1447 enforcement, _, err := client.Repositories.AddAdminEnforcement(context.Background(), "o", "r", "b") 1448 if err != nil { 1449 t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err) 1450 } 1451 1452 want := &AdminEnforcement{ 1453 URL: String("/repos/o/r/branches/b/protection/enforce_admins"), 1454 Enabled: true, 1455 } 1456 if !reflect.DeepEqual(enforcement, want) { 1457 t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want) 1458 } 1459 } 1460 1461 func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) { 1462 client, mux, _, teardown := setup() 1463 defer teardown() 1464 1465 mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { 1466 testMethod(t, r, "DELETE") 1467 testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview) 1468 w.WriteHeader(http.StatusNoContent) 1469 }) 1470 1471 _, err := client.Repositories.RemoveAdminEnforcement(context.Background(), "o", "r", "b") 1472 if err != nil { 1473 t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err) 1474 } 1475 } 1476 1477 func TestRepositoriesService_GetSignaturesProtectedBranch(t *testing.T) { 1478 client, mux, _, teardown := setup() 1479 defer teardown() 1480 1481 mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) { 1482 testMethod(t, r, "GET") 1483 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 1484 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":false}`) 1485 }) 1486 1487 signature, _, err := client.Repositories.GetSignaturesProtectedBranch(context.Background(), "o", "r", "b") 1488 if err != nil { 1489 t.Errorf("Repositories.GetSignaturesProtectedBranch returned error: %v", err) 1490 } 1491 1492 want := &SignaturesProtectedBranch{ 1493 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 1494 Enabled: Bool(false), 1495 } 1496 1497 if !reflect.DeepEqual(signature, want) { 1498 t.Errorf("Repositories.GetSignaturesProtectedBranch returned %+v, want %+v", signature, want) 1499 } 1500 } 1501 1502 func TestRepositoriesService_RequireSignaturesOnProtectedBranch(t *testing.T) { 1503 client, mux, _, teardown := setup() 1504 defer teardown() 1505 1506 mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) { 1507 testMethod(t, r, "POST") 1508 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 1509 fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/required_signatures","enabled":true}`) 1510 }) 1511 1512 signature, _, err := client.Repositories.RequireSignaturesOnProtectedBranch(context.Background(), "o", "r", "b") 1513 if err != nil { 1514 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned error: %v", err) 1515 } 1516 1517 want := &SignaturesProtectedBranch{ 1518 URL: String("/repos/o/r/branches/b/protection/required_signatures"), 1519 Enabled: Bool(true), 1520 } 1521 1522 if !reflect.DeepEqual(signature, want) { 1523 t.Errorf("Repositories.RequireSignaturesOnProtectedBranch returned %+v, want %+v", signature, want) 1524 } 1525 } 1526 1527 func TestRepositoriesService_OptionalSignaturesOnProtectedBranch(t *testing.T) { 1528 client, mux, _, teardown := setup() 1529 defer teardown() 1530 1531 mux.HandleFunc("/repos/o/r/branches/b/protection/required_signatures", func(w http.ResponseWriter, r *http.Request) { 1532 testMethod(t, r, "DELETE") 1533 testHeader(t, r, "Accept", mediaTypeSignaturePreview) 1534 w.WriteHeader(http.StatusNoContent) 1535 }) 1536 1537 _, err := client.Repositories.OptionalSignaturesOnProtectedBranch(context.Background(), "o", "r", "b") 1538 if err != nil { 1539 t.Errorf("Repositories.OptionalSignaturesOnProtectedBranch returned error: %v", err) 1540 } 1541 } 1542 1543 func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) { 1544 req := PullRequestReviewsEnforcementRequest{} 1545 1546 got, err := json.Marshal(req) 1547 if err != nil { 1548 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 1549 } 1550 1551 want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 1552 if want != string(got) { 1553 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 1554 } 1555 1556 req = PullRequestReviewsEnforcementRequest{ 1557 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{}, 1558 } 1559 1560 got, err = json.Marshal(req) 1561 if err != nil { 1562 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 1563 } 1564 1565 want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 1566 if want != string(got) { 1567 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 1568 } 1569 1570 req = PullRequestReviewsEnforcementRequest{ 1571 DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ 1572 Users: &[]string{}, 1573 Teams: &[]string{}, 1574 }, 1575 } 1576 1577 got, err = json.Marshal(req) 1578 if err != nil { 1579 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) 1580 } 1581 1582 want = `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}` 1583 if want != string(got) { 1584 t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want) 1585 } 1586 } 1587 1588 func TestRepositoriesService_ListAllTopics(t *testing.T) { 1589 client, mux, _, teardown := setup() 1590 defer teardown() 1591 1592 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 1593 testMethod(t, r, "GET") 1594 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 1595 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 1596 }) 1597 1598 got, _, err := client.Repositories.ListAllTopics(context.Background(), "o", "r") 1599 if err != nil { 1600 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 1601 } 1602 1603 want := []string{"go", "go-github", "github"} 1604 if !reflect.DeepEqual(got, want) { 1605 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 1606 } 1607 } 1608 1609 func TestRepositoriesService_ListAllTopics_emptyTopics(t *testing.T) { 1610 client, mux, _, teardown := setup() 1611 defer teardown() 1612 1613 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 1614 testMethod(t, r, "GET") 1615 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 1616 fmt.Fprint(w, `{"names":[]}`) 1617 }) 1618 1619 got, _, err := client.Repositories.ListAllTopics(context.Background(), "o", "r") 1620 if err != nil { 1621 t.Fatalf("Repositories.ListAllTopics returned error: %v", err) 1622 } 1623 1624 want := []string{} 1625 if !reflect.DeepEqual(got, want) { 1626 t.Errorf("Repositories.ListAllTopics returned %+v, want %+v", got, want) 1627 } 1628 } 1629 1630 func TestRepositoriesService_ReplaceAllTopics(t *testing.T) { 1631 client, mux, _, teardown := setup() 1632 defer teardown() 1633 1634 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 1635 testMethod(t, r, "PUT") 1636 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 1637 fmt.Fprint(w, `{"names":["go", "go-github", "github"]}`) 1638 }) 1639 1640 got, _, err := client.Repositories.ReplaceAllTopics(context.Background(), "o", "r", []string{"go", "go-github", "github"}) 1641 if err != nil { 1642 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 1643 } 1644 1645 want := []string{"go", "go-github", "github"} 1646 if !reflect.DeepEqual(got, want) { 1647 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 1648 } 1649 } 1650 1651 func TestRepositoriesService_ReplaceAllTopics_nilSlice(t *testing.T) { 1652 client, mux, _, teardown := setup() 1653 defer teardown() 1654 1655 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 1656 testMethod(t, r, "PUT") 1657 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 1658 testBody(t, r, `{"names":[]}`+"\n") 1659 fmt.Fprint(w, `{"names":[]}`) 1660 }) 1661 1662 got, _, err := client.Repositories.ReplaceAllTopics(context.Background(), "o", "r", nil) 1663 if err != nil { 1664 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 1665 } 1666 1667 want := []string{} 1668 if !reflect.DeepEqual(got, want) { 1669 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 1670 } 1671 } 1672 1673 func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) { 1674 client, mux, _, teardown := setup() 1675 defer teardown() 1676 1677 mux.HandleFunc("/repos/o/r/topics", func(w http.ResponseWriter, r *http.Request) { 1678 testMethod(t, r, "PUT") 1679 testHeader(t, r, "Accept", mediaTypeTopicsPreview) 1680 testBody(t, r, `{"names":[]}`+"\n") 1681 fmt.Fprint(w, `{"names":[]}`) 1682 }) 1683 1684 got, _, err := client.Repositories.ReplaceAllTopics(context.Background(), "o", "r", []string{}) 1685 if err != nil { 1686 t.Fatalf("Repositories.ReplaceAllTopics returned error: %v", err) 1687 } 1688 1689 want := []string{} 1690 if !reflect.DeepEqual(got, want) { 1691 t.Errorf("Repositories.ReplaceAllTopics returned %+v, want %+v", got, want) 1692 } 1693 } 1694 1695 func TestRepositoriesService_ListApps(t *testing.T) { 1696 client, mux, _, teardown := setup() 1697 defer teardown() 1698 1699 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 1700 testMethod(t, r, "GET") 1701 }) 1702 1703 _, _, err := client.Repositories.ListApps(context.Background(), "o", "r", "b") 1704 if err != nil { 1705 t.Errorf("Repositories.ListApps returned error: %v", err) 1706 } 1707 } 1708 1709 func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) { 1710 client, mux, _, teardown := setup() 1711 defer teardown() 1712 1713 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 1714 testMethod(t, r, "PUT") 1715 fmt.Fprint(w, `[{ 1716 "name": "octocat" 1717 }]`) 1718 }) 1719 input := []string{"octocat"} 1720 got, _, err := client.Repositories.ReplaceAppRestrictions(context.Background(), "o", "r", "b", input) 1721 if err != nil { 1722 t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err) 1723 } 1724 want := []*App{ 1725 {Name: String("octocat")}, 1726 } 1727 if !reflect.DeepEqual(got, want) { 1728 t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want) 1729 } 1730 } 1731 1732 func TestRepositoriesService_AddAppRestrictions(t *testing.T) { 1733 client, mux, _, teardown := setup() 1734 defer teardown() 1735 1736 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 1737 testMethod(t, r, "POST") 1738 fmt.Fprint(w, `[{ 1739 "name": "octocat" 1740 }]`) 1741 }) 1742 input := []string{"octocat"} 1743 got, _, err := client.Repositories.AddAppRestrictions(context.Background(), "o", "r", "b", input) 1744 if err != nil { 1745 t.Errorf("Repositories.AddAppRestrictions returned error: %v", err) 1746 } 1747 want := []*App{ 1748 {Name: String("octocat")}, 1749 } 1750 if !reflect.DeepEqual(got, want) { 1751 t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want) 1752 } 1753 } 1754 1755 func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) { 1756 client, mux, _, teardown := setup() 1757 defer teardown() 1758 1759 mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) { 1760 testMethod(t, r, "DELETE") 1761 fmt.Fprint(w, `[]`) 1762 }) 1763 input := []string{"octocat"} 1764 got, _, err := client.Repositories.RemoveAppRestrictions(context.Background(), "o", "r", "b", input) 1765 if err != nil { 1766 t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err) 1767 } 1768 want := []*App{} 1769 if !reflect.DeepEqual(got, want) { 1770 t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want) 1771 } 1772 } 1773 1774 func TestRepositoriesService_Transfer(t *testing.T) { 1775 client, mux, _, teardown := setup() 1776 defer teardown() 1777 1778 input := TransferRequest{NewOwner: "a", TeamID: []int64{123}} 1779 1780 mux.HandleFunc("/repos/o/r/transfer", func(w http.ResponseWriter, r *http.Request) { 1781 var v TransferRequest 1782 json.NewDecoder(r.Body).Decode(&v) 1783 1784 testMethod(t, r, "POST") 1785 if !reflect.DeepEqual(v, input) { 1786 t.Errorf("Request body = %+v, want %+v", v, input) 1787 } 1788 1789 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 1790 }) 1791 1792 got, _, err := client.Repositories.Transfer(context.Background(), "o", "r", input) 1793 if err != nil { 1794 t.Errorf("Repositories.Transfer returned error: %v", err) 1795 } 1796 1797 want := &Repository{Owner: &User{Login: String("a")}} 1798 if !reflect.DeepEqual(got, want) { 1799 t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want) 1800 } 1801 } 1802 1803 func TestRepositoriesService_Dispatch(t *testing.T) { 1804 client, mux, _, teardown := setup() 1805 defer teardown() 1806 1807 var input DispatchRequestOptions 1808 1809 mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) { 1810 var v DispatchRequestOptions 1811 json.NewDecoder(r.Body).Decode(&v) 1812 1813 testMethod(t, r, "POST") 1814 if !reflect.DeepEqual(v, input) { 1815 t.Errorf("Request body = %+v, want %+v", v, input) 1816 } 1817 1818 fmt.Fprint(w, `{"owner":{"login":"a"}}`) 1819 }) 1820 1821 ctx := context.Background() 1822 1823 testCases := []interface{}{ 1824 nil, 1825 struct { 1826 Foo string 1827 }{ 1828 Foo: "test", 1829 }, 1830 struct { 1831 Bar int 1832 }{ 1833 Bar: 42, 1834 }, 1835 struct { 1836 Foo string 1837 Bar int 1838 Baz bool 1839 }{ 1840 Foo: "test", 1841 Bar: 42, 1842 Baz: false, 1843 }, 1844 } 1845 for _, tc := range testCases { 1846 1847 if tc == nil { 1848 input = DispatchRequestOptions{EventType: "go"} 1849 } else { 1850 bytes, _ := json.Marshal(tc) 1851 payload := json.RawMessage(bytes) 1852 input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload} 1853 } 1854 1855 got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input) 1856 if err != nil { 1857 t.Errorf("Repositories.Dispatch returned error: %v", err) 1858 } 1859 1860 want := &Repository{Owner: &User{Login: String("a")}} 1861 if !reflect.DeepEqual(got, want) { 1862 t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want) 1863 } 1864 } 1865 1866 // Test s.client.NewRequest failure 1867 client.BaseURL.Path = "" 1868 got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input) 1869 if got != nil { 1870 t.Errorf("client.BaseURL.Path='' Dispatch = %#v, want nil", got) 1871 } 1872 if resp != nil { 1873 t.Errorf("client.BaseURL.Path='' Dispatch resp = %#v, want nil", resp) 1874 } 1875 if err == nil { 1876 t.Error("client.BaseURL.Path='' Dispatch err = nil, want error") 1877 } 1878 1879 // Test s.client.Do failure 1880 client.BaseURL.Path = "/api-v3/" 1881 client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute) 1882 got, resp, err = client.Repositories.Dispatch(ctx, "o", "r", input) 1883 if got != nil { 1884 t.Errorf("rate.Reset.Time > now Dispatch = %#v, want nil", got) 1885 } 1886 if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want { 1887 t.Errorf("rate.Reset.Time > now Dispatch resp = %#v, want StatusCode=%v", resp.Response, want) 1888 } 1889 if err == nil { 1890 t.Error("rate.Reset.Time > now Dispatch err = nil, want error") 1891 } 1892 }