github.com/google/go-github/v70@v70.0.0/github/repos_commits_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 "fmt" 11 "net/http" 12 "net/url" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/google/go-cmp/cmp" 18 ) 19 20 func TestRepositoriesService_ListCommits(t *testing.T) { 21 t.Parallel() 22 client, mux, _ := setup(t) 23 24 // given 25 mux.HandleFunc("/repos/o/r/commits", func(w http.ResponseWriter, r *http.Request) { 26 testMethod(t, r, "GET") 27 testFormValues(t, r, 28 values{ 29 "sha": "s", 30 "path": "p", 31 "author": "a", 32 "since": "2013-08-01T00:00:00Z", 33 "until": "2013-09-03T00:00:00Z", 34 }) 35 fmt.Fprintf(w, `[{"sha": "s"}]`) 36 }) 37 38 opt := &CommitsListOptions{ 39 SHA: "s", 40 Path: "p", 41 Author: "a", 42 Since: time.Date(2013, time.August, 1, 0, 0, 0, 0, time.UTC), 43 Until: time.Date(2013, time.September, 3, 0, 0, 0, 0, time.UTC), 44 } 45 ctx := context.Background() 46 commits, _, err := client.Repositories.ListCommits(ctx, "o", "r", opt) 47 if err != nil { 48 t.Errorf("Repositories.ListCommits returned error: %v", err) 49 } 50 51 want := []*RepositoryCommit{{SHA: Ptr("s")}} 52 if !cmp.Equal(commits, want) { 53 t.Errorf("Repositories.ListCommits returned %+v, want %+v", commits, want) 54 } 55 56 const methodName = "ListCommits" 57 testBadOptions(t, methodName, func() (err error) { 58 _, _, err = client.Repositories.ListCommits(ctx, "\n", "\n", opt) 59 return err 60 }) 61 62 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 63 got, resp, err := client.Repositories.ListCommits(ctx, "o", "r", opt) 64 if got != nil { 65 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 66 } 67 return resp, err 68 }) 69 } 70 71 func TestRepositoriesService_GetCommit(t *testing.T) { 72 t.Parallel() 73 client, mux, _ := setup(t) 74 75 mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) { 76 testMethod(t, r, "GET") 77 testFormValues(t, r, values{"per_page": "2", "page": "2"}) 78 fmt.Fprintf(w, `{ 79 "sha": "s", 80 "commit": { "message": "m" }, 81 "author": { "login": "l" }, 82 "committer": { "login": "l" }, 83 "parents": [ { "sha": "s" } ], 84 "stats": { "additions": 104, "deletions": 4, "total": 108 }, 85 "files": [ 86 { 87 "filename": "f", 88 "additions": 10, 89 "deletions": 2, 90 "changes": 12, 91 "status": "s", 92 "patch": "p", 93 "blob_url": "b", 94 "raw_url": "r", 95 "contents_url": "c" 96 } 97 ] 98 }`) 99 }) 100 101 opts := &ListOptions{Page: 2, PerPage: 2} 102 ctx := context.Background() 103 commit, _, err := client.Repositories.GetCommit(ctx, "o", "r", "s", opts) 104 if err != nil { 105 t.Errorf("Repositories.GetCommit returned error: %v", err) 106 } 107 108 want := &RepositoryCommit{ 109 SHA: Ptr("s"), 110 Commit: &Commit{ 111 Message: Ptr("m"), 112 }, 113 Author: &User{ 114 Login: Ptr("l"), 115 }, 116 Committer: &User{ 117 Login: Ptr("l"), 118 }, 119 Parents: []*Commit{ 120 { 121 SHA: Ptr("s"), 122 }, 123 }, 124 Stats: &CommitStats{ 125 Additions: Ptr(104), 126 Deletions: Ptr(4), 127 Total: Ptr(108), 128 }, 129 Files: []*CommitFile{ 130 { 131 Filename: Ptr("f"), 132 Additions: Ptr(10), 133 Deletions: Ptr(2), 134 Changes: Ptr(12), 135 Status: Ptr("s"), 136 Patch: Ptr("p"), 137 BlobURL: Ptr("b"), 138 RawURL: Ptr("r"), 139 ContentsURL: Ptr("c"), 140 }, 141 }, 142 } 143 if !cmp.Equal(commit, want) { 144 t.Errorf("Repositories.GetCommit returned \n%+v, want \n%+v", commit, want) 145 } 146 147 const methodName = "GetCommit" 148 testBadOptions(t, methodName, func() (err error) { 149 _, _, err = client.Repositories.GetCommit(ctx, "\n", "\n", "\n", opts) 150 return err 151 }) 152 153 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 154 got, resp, err := client.Repositories.GetCommit(ctx, "o", "r", "s", opts) 155 if got != nil { 156 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 157 } 158 return resp, err 159 }) 160 } 161 162 func TestRepositoriesService_GetCommitRaw_diff(t *testing.T) { 163 t.Parallel() 164 client, mux, _ := setup(t) 165 166 const rawStr = "@@diff content" 167 168 mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) { 169 testMethod(t, r, "GET") 170 testHeader(t, r, "Accept", mediaTypeV3Diff) 171 fmt.Fprint(w, rawStr) 172 }) 173 174 ctx := context.Background() 175 got, _, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{Type: Diff}) 176 if err != nil { 177 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 178 } 179 want := rawStr 180 if got != want { 181 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 182 } 183 184 const methodName = "GetCommitRaw" 185 testBadOptions(t, methodName, func() (err error) { 186 _, _, err = client.Repositories.GetCommitRaw(ctx, "\n", "\n", "\n", RawOptions{Type: Diff}) 187 return err 188 }) 189 190 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 191 got, resp, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{Type: Diff}) 192 if got != "" { 193 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 194 } 195 return resp, err 196 }) 197 } 198 199 func TestRepositoriesService_GetCommitRaw_patch(t *testing.T) { 200 t.Parallel() 201 client, mux, _ := setup(t) 202 203 const rawStr = "@@patch content" 204 205 mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) { 206 testMethod(t, r, "GET") 207 testHeader(t, r, "Accept", mediaTypeV3Patch) 208 fmt.Fprint(w, rawStr) 209 }) 210 211 ctx := context.Background() 212 got, _, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{Type: Patch}) 213 if err != nil { 214 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 215 } 216 want := rawStr 217 if got != want { 218 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 219 } 220 } 221 222 func TestRepositoriesService_GetCommitRaw_invalid(t *testing.T) { 223 t.Parallel() 224 client, _, _ := setup(t) 225 226 ctx := context.Background() 227 _, _, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{100}) 228 if err == nil { 229 t.Fatal("Repositories.GetCommitRaw should return error") 230 } 231 if !strings.Contains(err.Error(), "unsupported raw type") { 232 t.Error("Repositories.GetCommitRaw should return unsupported raw type error") 233 } 234 } 235 236 func TestRepositoriesService_GetCommitSHA1(t *testing.T) { 237 t.Parallel() 238 client, mux, _ := setup(t) 239 240 const sha1 = "01234abcde" 241 242 mux.HandleFunc("/repos/o/r/commits/master", func(w http.ResponseWriter, r *http.Request) { 243 testMethod(t, r, "GET") 244 testHeader(t, r, "Accept", mediaTypeV3SHA) 245 246 fmt.Fprint(w, sha1) 247 }) 248 249 ctx := context.Background() 250 got, _, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "master", "") 251 if err != nil { 252 t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) 253 } 254 255 want := sha1 256 if got != want { 257 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 258 } 259 260 mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { 261 testMethod(t, r, "GET") 262 testHeader(t, r, "Accept", mediaTypeV3SHA) 263 testHeader(t, r, "If-None-Match", `"`+sha1+`"`) 264 265 w.WriteHeader(http.StatusNotModified) 266 }) 267 268 got, _, err = client.Repositories.GetCommitSHA1(ctx, "o", "r", "tag", sha1) 269 if err == nil { 270 t.Errorf("Expected HTTP 304 response") 271 } 272 273 want = "" 274 if got != want { 275 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 276 } 277 278 const methodName = "GetCommitSHA1" 279 testBadOptions(t, methodName, func() (err error) { 280 _, _, err = client.Repositories.GetCommitSHA1(ctx, "\n", "\n", "\n", "\n") 281 return err 282 }) 283 284 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 285 got, resp, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "master", "") 286 if got != "" { 287 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 288 } 289 return resp, err 290 }) 291 } 292 293 func TestRepositoriesService_NonAlphabetCharacter_GetCommitSHA1(t *testing.T) { 294 t.Parallel() 295 client, mux, _ := setup(t) 296 297 const sha1 = "01234abcde" 298 299 mux.HandleFunc("/repos/o/r/commits/master%2520hash", func(w http.ResponseWriter, r *http.Request) { 300 testMethod(t, r, "GET") 301 testHeader(t, r, "Accept", mediaTypeV3SHA) 302 303 fmt.Fprint(w, sha1) 304 }) 305 306 ctx := context.Background() 307 got, _, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "master%20hash", "") 308 if err != nil { 309 t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) 310 } 311 312 if want := sha1; got != want { 313 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 314 } 315 316 mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { 317 testMethod(t, r, "GET") 318 testHeader(t, r, "Accept", mediaTypeV3SHA) 319 testHeader(t, r, "If-None-Match", `"`+sha1+`"`) 320 321 w.WriteHeader(http.StatusNotModified) 322 }) 323 324 got, _, err = client.Repositories.GetCommitSHA1(ctx, "o", "r", "tag", sha1) 325 if err == nil { 326 t.Errorf("Expected HTTP 304 response") 327 } 328 329 if want := ""; got != want { 330 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 331 } 332 } 333 334 func TestRepositoriesService_TrailingPercent_GetCommitSHA1(t *testing.T) { 335 t.Parallel() 336 client, mux, _ := setup(t) 337 338 const sha1 = "01234abcde" 339 340 mux.HandleFunc("/repos/o/r/commits/comm%", func(w http.ResponseWriter, r *http.Request) { 341 testMethod(t, r, "GET") 342 testHeader(t, r, "Accept", mediaTypeV3SHA) 343 344 fmt.Fprint(w, sha1) 345 }) 346 347 ctx := context.Background() 348 got, _, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "comm%", "") 349 if err != nil { 350 t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) 351 } 352 353 if want := sha1; got != want { 354 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 355 } 356 357 mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { 358 testMethod(t, r, "GET") 359 testHeader(t, r, "Accept", mediaTypeV3SHA) 360 testHeader(t, r, "If-None-Match", `"`+sha1+`"`) 361 362 w.WriteHeader(http.StatusNotModified) 363 }) 364 365 got, _, err = client.Repositories.GetCommitSHA1(ctx, "o", "r", "tag", sha1) 366 if err == nil { 367 t.Errorf("Expected HTTP 304 response") 368 } 369 370 if want := ""; got != want { 371 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 372 } 373 } 374 375 func TestRepositoriesService_CompareCommits(t *testing.T) { 376 t.Parallel() 377 testCases := []struct { 378 base string 379 head string 380 }{ 381 {base: "b", head: "h"}, 382 {base: "123base", head: "head123"}, 383 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 384 } 385 386 for i, sample := range testCases { 387 sample := sample 388 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 389 t.Parallel() 390 client, mux, _ := setup(t) 391 392 base := sample.base 393 head := sample.head 394 395 encodedBase := url.PathEscape(base) 396 encodedHead := url.PathEscape(head) 397 398 escapedBase := url.QueryEscape(base) 399 escapedHead := url.QueryEscape(head) 400 401 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", encodedBase, encodedHead) 402 403 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 404 testMethod(t, r, "GET") 405 testFormValues(t, r, values{"per_page": "2", "page": "2"}) 406 fmt.Fprintf(w, `{ 407 "base_commit": { 408 "sha": "s", 409 "commit": { 410 "author": { "name": "n" }, 411 "committer": { "name": "n" }, 412 "message": "m", 413 "tree": { "sha": "t" } 414 }, 415 "author": { "login": "l" }, 416 "committer": { "login": "l" }, 417 "parents": [ { "sha": "s" } ] 418 }, 419 "status": "s", 420 "ahead_by": 1, 421 "behind_by": 2, 422 "total_commits": 1, 423 "commits": [ 424 { 425 "sha": "s", 426 "commit": { "author": { "name": "n" } }, 427 "author": { "login": "l" }, 428 "committer": { "login": "l" }, 429 "parents": [ { "sha": "s" } ] 430 } 431 ], 432 "files": [ { "filename": "f" } ], 433 "html_url": "https://github.com/o/r/compare/%[1]v...%[2]v", 434 "permalink_url": "https://github.com/o/r/compare/o:bbcd538c8e72b8c175046e27cc8f907076331401...o:0328041d1152db8ae77652d1618a02e57f745f17", 435 "diff_url": "https://github.com/o/r/compare/%[1]v...%[2]v.diff", 436 "patch_url": "https://github.com/o/r/compare/%[1]v...%[2]v.patch", 437 "url": "https://api.github.com/repos/o/r/compare/%[1]v...%[2]v" 438 }`, escapedBase, escapedHead) 439 }) 440 441 opts := &ListOptions{Page: 2, PerPage: 2} 442 ctx := context.Background() 443 got, _, err := client.Repositories.CompareCommits(ctx, "o", "r", base, head, opts) 444 if err != nil { 445 t.Errorf("Repositories.CompareCommits returned error: %v", err) 446 } 447 448 want := &CommitsComparison{ 449 BaseCommit: &RepositoryCommit{ 450 SHA: Ptr("s"), 451 Commit: &Commit{ 452 Author: &CommitAuthor{Name: Ptr("n")}, 453 Committer: &CommitAuthor{Name: Ptr("n")}, 454 Message: Ptr("m"), 455 Tree: &Tree{SHA: Ptr("t")}, 456 }, 457 Author: &User{Login: Ptr("l")}, 458 Committer: &User{Login: Ptr("l")}, 459 Parents: []*Commit{ 460 { 461 SHA: Ptr("s"), 462 }, 463 }, 464 }, 465 Status: Ptr("s"), 466 AheadBy: Ptr(1), 467 BehindBy: Ptr(2), 468 TotalCommits: Ptr(1), 469 Commits: []*RepositoryCommit{ 470 { 471 SHA: Ptr("s"), 472 Commit: &Commit{ 473 Author: &CommitAuthor{Name: Ptr("n")}, 474 }, 475 Author: &User{Login: Ptr("l")}, 476 Committer: &User{Login: Ptr("l")}, 477 Parents: []*Commit{ 478 { 479 SHA: Ptr("s"), 480 }, 481 }, 482 }, 483 }, 484 Files: []*CommitFile{ 485 { 486 Filename: Ptr("f"), 487 }, 488 }, 489 HTMLURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v", escapedBase, escapedHead)), 490 PermalinkURL: Ptr("https://github.com/o/r/compare/o:bbcd538c8e72b8c175046e27cc8f907076331401...o:0328041d1152db8ae77652d1618a02e57f745f17"), 491 DiffURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v.diff", escapedBase, escapedHead)), 492 PatchURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v.patch", escapedBase, escapedHead)), 493 URL: Ptr(fmt.Sprintf("https://api.github.com/repos/o/r/compare/%v...%v", escapedBase, escapedHead)), 494 } 495 496 if !cmp.Equal(got, want) { 497 t.Errorf("Repositories.CompareCommits returned \n%+v, want \n%+v", got, want) 498 } 499 500 const methodName = "CompareCommits" 501 testBadOptions(t, methodName, func() (err error) { 502 _, _, err = client.Repositories.CompareCommits(ctx, "\n", "\n", "\n", "\n", opts) 503 return err 504 }) 505 506 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 507 got, resp, err := client.Repositories.CompareCommits(ctx, "o", "r", base, head, opts) 508 if got != nil { 509 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 510 } 511 return resp, err 512 }) 513 }) 514 } 515 } 516 517 func TestRepositoriesService_CompareCommitsRaw_diff(t *testing.T) { 518 t.Parallel() 519 testCases := []struct { 520 base string 521 head string 522 }{ 523 {base: "b", head: "h"}, 524 {base: "123base", head: "head123"}, 525 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 526 } 527 528 for i, sample := range testCases { 529 sample := sample 530 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 531 t.Parallel() 532 client, mux, _ := setup(t) 533 534 base := sample.base 535 head := sample.head 536 537 encodedBase := url.PathEscape(base) 538 encodedHead := url.PathEscape(head) 539 540 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", encodedBase, encodedHead) 541 const rawStr = "@@diff content" 542 543 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 544 testMethod(t, r, "GET") 545 testHeader(t, r, "Accept", mediaTypeV3Diff) 546 fmt.Fprint(w, rawStr) 547 }) 548 549 ctx := context.Background() 550 got, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Diff}) 551 if err != nil { 552 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 553 } 554 want := rawStr 555 if got != want { 556 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 557 } 558 559 const methodName = "CompareCommitsRaw" 560 testBadOptions(t, methodName, func() (err error) { 561 _, _, err = client.Repositories.CompareCommitsRaw(ctx, "\n", "\n", "\n", "\n", RawOptions{Type: Diff}) 562 return err 563 }) 564 565 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 566 got, resp, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Diff}) 567 if got != "" { 568 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 569 } 570 return resp, err 571 }) 572 }) 573 } 574 } 575 576 func TestRepositoriesService_CompareCommitsRaw_patch(t *testing.T) { 577 t.Parallel() 578 testCases := []struct { 579 base string 580 head string 581 }{ 582 {base: "b", head: "h"}, 583 {base: "123base", head: "head123"}, 584 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 585 } 586 587 for i, sample := range testCases { 588 sample := sample 589 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 590 t.Parallel() 591 client, mux, _ := setup(t) 592 593 base := sample.base 594 head := sample.head 595 596 encodedBase := url.PathEscape(base) 597 encodedHead := url.PathEscape(head) 598 599 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", encodedBase, encodedHead) 600 const rawStr = "@@patch content" 601 602 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 603 testMethod(t, r, "GET") 604 testHeader(t, r, "Accept", mediaTypeV3Patch) 605 fmt.Fprint(w, rawStr) 606 }) 607 608 ctx := context.Background() 609 got, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Patch}) 610 if err != nil { 611 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 612 } 613 want := rawStr 614 if got != want { 615 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 616 } 617 }) 618 } 619 } 620 621 func TestRepositoriesService_CompareCommitsRaw_invalid(t *testing.T) { 622 t.Parallel() 623 ctx := context.Background() 624 625 testCases := []struct { 626 base string 627 head string 628 }{ 629 {base: "b", head: "h"}, 630 {base: "123base", head: "head123"}, 631 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 632 } 633 634 for i, sample := range testCases { 635 sample := sample 636 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 637 t.Parallel() 638 client, _, _ := setup(t) 639 _, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", sample.base, sample.head, RawOptions{100}) 640 if err == nil { 641 t.Fatal("Repositories.GetCommitRaw should return error") 642 } 643 if !strings.Contains(err.Error(), "unsupported raw type") { 644 t.Error("Repositories.GetCommitRaw should return unsupported raw type error") 645 } 646 }) 647 } 648 } 649 650 func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) { 651 t.Parallel() 652 client, mux, _ := setup(t) 653 654 mux.HandleFunc("/repos/o/r/commits/s/branches-where-head", func(w http.ResponseWriter, r *http.Request) { 655 testMethod(t, r, "GET") 656 fmt.Fprintf(w, `[{"name": "b","commit":{"sha":"2e90302801c870f17b6152327d9b9a03c8eca0e2","url":"https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"},"protected":true}]`) 657 }) 658 659 ctx := context.Background() 660 branches, _, err := client.Repositories.ListBranchesHeadCommit(ctx, "o", "r", "s") 661 if err != nil { 662 t.Errorf("Repositories.ListBranchesHeadCommit returned error: %v", err) 663 } 664 665 want := []*BranchCommit{ 666 { 667 Name: Ptr("b"), 668 Commit: &Commit{ 669 SHA: Ptr("2e90302801c870f17b6152327d9b9a03c8eca0e2"), 670 URL: Ptr("https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"), 671 }, 672 Protected: Ptr(true), 673 }, 674 } 675 if !cmp.Equal(branches, want) { 676 t.Errorf("Repositories.ListBranchesHeadCommit returned %+v, want %+v", branches, want) 677 } 678 679 const methodName = "ListBranchesHeadCommit" 680 testBadOptions(t, methodName, func() (err error) { 681 _, _, err = client.Repositories.ListBranchesHeadCommit(ctx, "\n", "\n", "\n") 682 return err 683 }) 684 685 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 686 got, resp, err := client.Repositories.ListBranchesHeadCommit(ctx, "o", "r", "s") 687 if got != nil { 688 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 689 } 690 return resp, err 691 }) 692 } 693 694 func TestBranchCommit_Marshal(t *testing.T) { 695 t.Parallel() 696 testJSONMarshal(t, &BranchCommit{}, "{}") 697 698 r := &BranchCommit{ 699 Name: Ptr("n"), 700 Commit: &Commit{ 701 SHA: Ptr("s"), 702 Author: &CommitAuthor{ 703 Date: &Timestamp{referenceTime}, 704 Name: Ptr("n"), 705 Email: Ptr("e"), 706 Login: Ptr("u"), 707 }, 708 Committer: &CommitAuthor{ 709 Date: &Timestamp{referenceTime}, 710 Name: Ptr("n"), 711 Email: Ptr("e"), 712 Login: Ptr("u"), 713 }, 714 Message: Ptr("m"), 715 Tree: &Tree{ 716 SHA: Ptr("s"), 717 Entries: []*TreeEntry{{ 718 SHA: Ptr("s"), 719 Path: Ptr("p"), 720 Mode: Ptr("m"), 721 Type: Ptr("t"), 722 Size: Ptr(1), 723 Content: Ptr("c"), 724 URL: Ptr("u"), 725 }}, 726 Truncated: Ptr(false), 727 }, 728 Parents: nil, 729 HTMLURL: Ptr("h"), 730 URL: Ptr("u"), 731 Verification: &SignatureVerification{ 732 Verified: Ptr(false), 733 Reason: Ptr("r"), 734 Signature: Ptr("s"), 735 Payload: Ptr("p"), 736 }, 737 NodeID: Ptr("n"), 738 CommentCount: Ptr(1), 739 }, 740 Protected: Ptr(false), 741 } 742 743 want := `{ 744 "name": "n", 745 "commit": { 746 "sha": "s", 747 "author": { 748 "date": ` + referenceTimeStr + `, 749 "name": "n", 750 "email": "e", 751 "username": "u" 752 }, 753 "committer": { 754 "date": ` + referenceTimeStr + `, 755 "name": "n", 756 "email": "e", 757 "username": "u" 758 }, 759 "message": "m", 760 "tree": { 761 "sha": "s", 762 "tree": [ 763 { 764 "sha": "s", 765 "path": "p", 766 "mode": "m", 767 "type": "t", 768 "size": 1, 769 "content": "c", 770 "url": "u" 771 } 772 ], 773 "truncated": false 774 }, 775 "html_url": "h", 776 "url": "u", 777 "verification": { 778 "verified": false, 779 "reason": "r", 780 "signature": "s", 781 "payload": "p" 782 }, 783 "node_id": "n", 784 "comment_count": 1 785 }, 786 "protected": false 787 }` 788 789 testJSONMarshal(t, r, want) 790 } 791 792 func TestCommitsComparison_Marshal(t *testing.T) { 793 t.Parallel() 794 testJSONMarshal(t, &CommitsComparison{}, "{}") 795 796 r := &CommitsComparison{ 797 BaseCommit: &RepositoryCommit{NodeID: Ptr("nid")}, 798 MergeBaseCommit: &RepositoryCommit{NodeID: Ptr("nid")}, 799 Status: Ptr("status"), 800 AheadBy: Ptr(1), 801 BehindBy: Ptr(1), 802 TotalCommits: Ptr(1), 803 Commits: []*RepositoryCommit{ 804 { 805 NodeID: Ptr("nid"), 806 }, 807 }, 808 Files: []*CommitFile{ 809 { 810 SHA: Ptr("sha"), 811 }, 812 }, 813 HTMLURL: Ptr("hurl"), 814 PermalinkURL: Ptr("purl"), 815 DiffURL: Ptr("durl"), 816 PatchURL: Ptr("purl"), 817 URL: Ptr("url"), 818 } 819 820 want := `{ 821 "base_commit": { 822 "node_id": "nid" 823 }, 824 "merge_base_commit": { 825 "node_id": "nid" 826 }, 827 "status": "status", 828 "ahead_by": 1, 829 "behind_by": 1, 830 "total_commits": 1, 831 "commits": [ 832 { 833 "node_id": "nid" 834 } 835 ], 836 "files": [ 837 { 838 "sha": "sha" 839 } 840 ], 841 "html_url": "hurl", 842 "permalink_url": "purl", 843 "diff_url": "durl", 844 "patch_url": "purl", 845 "url": "url" 846 }` 847 848 testJSONMarshal(t, r, want) 849 } 850 851 func TestCommitFile_Marshal(t *testing.T) { 852 t.Parallel() 853 testJSONMarshal(t, &CommitFile{}, "{}") 854 855 r := &CommitFile{ 856 SHA: Ptr("sha"), 857 Filename: Ptr("fn"), 858 Additions: Ptr(1), 859 Deletions: Ptr(1), 860 Changes: Ptr(1), 861 Status: Ptr("status"), 862 Patch: Ptr("patch"), 863 BlobURL: Ptr("burl"), 864 RawURL: Ptr("rurl"), 865 ContentsURL: Ptr("curl"), 866 PreviousFilename: Ptr("pf"), 867 } 868 869 want := `{ 870 "sha": "sha", 871 "filename": "fn", 872 "additions": 1, 873 "deletions": 1, 874 "changes": 1, 875 "status": "status", 876 "patch": "patch", 877 "blob_url": "burl", 878 "raw_url": "rurl", 879 "contents_url": "curl", 880 "previous_filename": "pf" 881 }` 882 883 testJSONMarshal(t, r, want) 884 } 885 886 func TestCommitStats_Marshal(t *testing.T) { 887 t.Parallel() 888 testJSONMarshal(t, &CommitStats{}, "{}") 889 890 r := &CommitStats{ 891 Additions: Ptr(1), 892 Deletions: Ptr(1), 893 Total: Ptr(1), 894 } 895 896 want := `{ 897 "additions": 1, 898 "deletions": 1, 899 "total": 1 900 }` 901 902 testJSONMarshal(t, r, want) 903 } 904 905 func TestRepositoryCommit_Marshal(t *testing.T) { 906 t.Parallel() 907 testJSONMarshal(t, &RepositoryCommit{}, "{}") 908 909 r := &RepositoryCommit{ 910 NodeID: Ptr("nid"), 911 SHA: Ptr("sha"), 912 Commit: &Commit{ 913 Message: Ptr("m"), 914 }, 915 Author: &User{ 916 Login: Ptr("l"), 917 }, 918 Committer: &User{ 919 Login: Ptr("l"), 920 }, 921 Parents: []*Commit{ 922 { 923 SHA: Ptr("s"), 924 }, 925 }, 926 HTMLURL: Ptr("hurl"), 927 URL: Ptr("url"), 928 CommentsURL: Ptr("curl"), 929 Stats: &CommitStats{ 930 Additions: Ptr(104), 931 Deletions: Ptr(4), 932 Total: Ptr(108), 933 }, 934 Files: []*CommitFile{ 935 { 936 Filename: Ptr("f"), 937 Additions: Ptr(10), 938 Deletions: Ptr(2), 939 Changes: Ptr(12), 940 Status: Ptr("s"), 941 Patch: Ptr("p"), 942 BlobURL: Ptr("b"), 943 RawURL: Ptr("r"), 944 ContentsURL: Ptr("c"), 945 }, 946 }, 947 } 948 949 want := `{ 950 "node_id": "nid", 951 "sha": "sha", 952 "commit": { 953 "message": "m" 954 }, 955 "author": { 956 "login": "l" 957 }, 958 "committer": { 959 "login": "l" 960 }, 961 "parents": [ 962 { 963 "sha": "s" 964 } 965 ], 966 "html_url": "hurl", 967 "url": "url", 968 "comments_url": "curl", 969 "stats": { 970 "additions": 104, 971 "deletions": 4, 972 "total": 108 973 }, 974 "files": [ 975 { 976 "filename": "f", 977 "additions": 10, 978 "deletions": 2, 979 "changes": 12, 980 "status": "s", 981 "patch": "p", 982 "blob_url": "b", 983 "raw_url": "r", 984 "contents_url": "c" 985 } 986 ] 987 }` 988 989 testJSONMarshal(t, r, want) 990 }