github.com/decred/politeia@v1.4.0/politeiawww/legacy/codetracker/github/database/cockroachdb/cockroachdb_test.go (about) 1 // Copyright (c) 2020 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package cockroachdb 6 7 import ( 8 "regexp" 9 "strconv" 10 "testing" 11 "time" 12 13 "github.com/DATA-DOG/go-sqlmock" 14 "github.com/decred/politeia/politeiawww/legacy/codetracker/github/database" 15 "github.com/jinzhu/gorm" 16 _ "github.com/jinzhu/gorm/dialects/postgres" 17 ) 18 19 func setupTestDB(t *testing.T) (*cockroachdb, sqlmock.Sqlmock, func()) { 20 t.Helper() 21 22 db, mock, err := sqlmock.New() 23 if err != nil { 24 t.Fatalf("error %s while creating stub db conn", err) 25 } 26 27 gdb, err := gorm.Open("postgres", db) 28 if err != nil { 29 t.Fatalf("error %s while opening db with gorm", err) 30 } 31 32 c := &cockroachdb{ 33 recordsdb: gdb, 34 } 35 36 return c, mock, func() { 37 db.Close() 38 } 39 } 40 41 // Tests 42 func TestNewPullRequests(t *testing.T) { 43 cdb, mock, close := setupTestDB(t) 44 defer close() 45 46 now := time.Now() 47 // Arguments 48 id := "https://github.com/decred/github/pull/1" + 49 strconv.Itoa(int(now.Unix())) 50 pr := &database.PullRequest{ 51 ID: id, 52 Repo: "github", 53 Organization: "decred", 54 URL: "https://github.com/decred/github/pull/1", 55 Number: 1, 56 User: "stakey", 57 UpdatedAt: now.Unix(), 58 ClosedAt: now.Unix(), 59 MergedAt: now.Unix(), 60 Merged: true, 61 State: "MERGED", 62 Additions: 100, 63 Deletions: 99, 64 MergedBy: "davec", 65 } 66 67 // Queries 68 sqlInsertPullRequests := `INSERT INTO "pullrequests" ` + 69 `("id","repo","organization","url","number","author","updated_at",` + 70 `"closed_at","merged_at","merged","state","additions","deletions",` + 71 `"merged_by") ` + 72 `VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14) ` + 73 `RETURNING "pullrequests"."id"` 74 75 // Success Expectations 76 mock.ExpectBegin() 77 // Insert user to db 78 mock.ExpectQuery(regexp.QuoteMeta(sqlInsertPullRequests)). 79 WithArgs( 80 pr.ID, 81 pr.Repo, 82 pr.Organization, 83 pr.URL, 84 pr.Number, 85 pr.User, 86 pr.UpdatedAt, 87 pr.ClosedAt, 88 pr.MergedAt, 89 pr.Merged, 90 pr.State, 91 pr.Additions, 92 pr.Deletions, 93 pr.MergedBy). 94 WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(pr.ID)) 95 mock.ExpectCommit() 96 97 // Execute method 98 err := cdb.NewPullRequest(pr) 99 if err != nil { 100 t.Errorf("UserNew unwanted error: %s", err) 101 } 102 103 // Make sure expectations were met for both success and failure 104 // conditions 105 err = mock.ExpectationsWereMet() 106 if err != nil { 107 t.Errorf("unfulfilled expectations: %s", err) 108 } 109 } 110 111 func TestUpdatePullRequests(t *testing.T) { 112 cdb, mock, close := setupTestDB(t) 113 defer close() 114 115 now := time.Now() 116 // Arguments 117 id := "https://github.com/decred/github/pull/1" + 118 strconv.Itoa(int(now.Unix())) 119 pr := &database.PullRequest{ 120 ID: id, 121 Repo: "github", 122 Organization: "decred", 123 URL: "https://github.com/decred/github/pull/1", 124 Number: 1, 125 User: "stakey", 126 UpdatedAt: now.Unix(), 127 ClosedAt: now.Unix(), 128 MergedAt: now.Unix(), 129 Merged: true, 130 State: "MERGED", 131 Additions: 100, 132 Deletions: 99, 133 MergedBy: "davec", 134 } 135 // Arguments 136 sqlUpdatePullRequests := `UPDATE "pullrequests" ` + 137 `SET "repo" = $1, "organization" = $2, "url" = $3, "number" = $4, ` + 138 `"author" = $5, "updated_at" = $6, "closed_at" = $7, ` + 139 `"merged_at" = $8, "merged" = $9, "state" = $10, "additions" = $11, ` + 140 `"deletions" = $12, "merged_by" = $13 ` + 141 `WHERE "pullrequests"."id" = $14` 142 143 // Success Expectations 144 mock.ExpectBegin() 145 mock.ExpectExec(regexp.QuoteMeta(sqlUpdatePullRequests)). 146 WithArgs( 147 pr.Repo, 148 pr.Organization, 149 pr.URL, 150 pr.Number, 151 pr.User, 152 pr.UpdatedAt, 153 pr.ClosedAt, 154 pr.MergedAt, 155 pr.Merged, 156 pr.State, 157 pr.Additions, 158 pr.Deletions, 159 pr.MergedBy, 160 pr.ID). 161 WillReturnResult(sqlmock.NewResult(1, 1)) 162 mock.ExpectCommit() 163 164 // Execute method 165 err := cdb.UpdatePullRequest(pr) 166 if err != nil { 167 t.Errorf("UpdatePullRequest unwanted error: %s", err) 168 } 169 170 // Make sure expectations were met 171 err = mock.ExpectationsWereMet() 172 if err != nil { 173 t.Errorf("unfulfilled expectations: %s", err) 174 } 175 } 176 177 func TestNewPullRequestsReview(t *testing.T) { 178 cdb, mock, close := setupTestDB(t) 179 defer close() 180 181 now := time.Now() 182 // Arguments 183 review := &database.PullRequestReview{ 184 PullRequestURL: "https://github.com/decred/github/pull/1", 185 Author: "stakey", 186 State: "APPROVED", 187 SubmittedAt: now.Unix(), 188 Repo: "github", 189 Number: 1, 190 ID: 4934324, 191 } 192 193 // Queries 194 sqlInsertPullRequests := `INSERT INTO "reviews" ` + 195 `("pull_request_url","id","author","state","submitted_at",` + 196 `"commit_id","repo","number") ` + 197 `VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ` + 198 `RETURNING "reviews"."id"` 199 200 // Success Expectations 201 mock.ExpectBegin() 202 // Insert user to db 203 mock.ExpectQuery(regexp.QuoteMeta(sqlInsertPullRequests)). 204 WithArgs( 205 review.PullRequestURL, 206 review.ID, 207 review.Author, 208 review.State, 209 review.SubmittedAt, 210 sqlmock.AnyArg(), 211 review.Repo, 212 review.Number, 213 ). 214 WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(review.ID)) 215 mock.ExpectCommit() 216 217 // Execute method 218 err := cdb.NewPullRequestReview(review) 219 if err != nil { 220 t.Errorf("UserNew unwanted error: %s", err) 221 } 222 223 // Make sure expectations were met for both success and failure 224 // conditions 225 err = mock.ExpectationsWereMet() 226 if err != nil { 227 t.Errorf("unfulfilled expectations: %s", err) 228 } 229 } 230 231 func TestUpdatePullRequestsReview(t *testing.T) { 232 cdb, mock, close := setupTestDB(t) 233 defer close() 234 235 now := time.Now() 236 // Arguments 237 review := &database.PullRequestReview{ 238 PullRequestURL: "https://github.com/decred/github/pull/1", 239 Author: "stakey", 240 State: "APPROVED", 241 SubmittedAt: now.Unix(), 242 Repo: "github", 243 Number: 1, 244 ID: 4934324, 245 } 246 // Queries 247 sqlUpdatePullRequests := `UPDATE "reviews" ` + 248 `SET "pull_request_url" = $1, "author" = $2, "state" = $3, ` + 249 `"submitted_at" = $4, "commit_id" = $5, "repo" = $6, "number" = $7 ` + 250 `WHERE "reviews"."id" = $8` 251 252 // Success Expectations 253 mock.ExpectBegin() 254 mock.ExpectExec(regexp.QuoteMeta(sqlUpdatePullRequests)). 255 WithArgs( 256 review.PullRequestURL, 257 review.Author, 258 review.State, 259 review.SubmittedAt, 260 sqlmock.AnyArg(), 261 review.Repo, 262 review.Number, 263 review.ID). 264 WillReturnResult(sqlmock.NewResult(1, 1)) 265 mock.ExpectCommit() 266 267 // Execute method 268 err := cdb.UpdatePullRequestReview(review) 269 if err != nil { 270 t.Errorf("UpdatePullRequestReview unwanted error: %s", err) 271 } 272 273 // Make sure expectations were met 274 err = mock.ExpectationsWereMet() 275 if err != nil { 276 t.Errorf("unfulfilled expectations: %s", err) 277 } 278 } 279 280 func TestPullRequestByID(t *testing.T) { 281 cdb, mock, close := setupTestDB(t) 282 defer close() 283 284 // Arguments 285 now := time.Now() 286 url := "https://github.com/decred/pr/pull/1" 287 288 id := url + 289 strconv.Itoa(int(now.Unix())) 290 idNotFound := url + "123456" 291 pr := &database.PullRequest{ 292 ID: id, 293 Repo: "github", 294 Organization: "decred", 295 URL: url, 296 Number: 1, 297 User: "stakey", 298 UpdatedAt: now.Unix(), 299 ClosedAt: now.Unix(), 300 MergedAt: now.Unix(), 301 Merged: true, 302 State: "MERGED", 303 Additions: 100, 304 Deletions: 99, 305 MergedBy: "davec", 306 } 307 308 // Mock rows data 309 rows := sqlmock.NewRows([]string{ 310 "id", 311 "repo", 312 "organization", 313 "url", 314 "number", 315 "author", 316 "updated_at", 317 "closed_at", 318 "merged_at", 319 "merged", 320 "state", 321 "additions", 322 "deletions", 323 "merged_by", 324 }).AddRow( 325 pr.ID, 326 pr.Repo, 327 pr.Organization, 328 pr.URL, 329 pr.Number, 330 pr.User, 331 pr.UpdatedAt, 332 pr.ClosedAt, 333 pr.MergedAt, 334 pr.Merged, 335 pr.State, 336 pr.Additions, 337 pr.Deletions, 338 pr.MergedBy, 339 ) 340 341 // Query 342 sql := `SELECT * FROM "pullrequests" WHERE "pullrequests"."id" = $1` 343 344 // Success Expectations 345 mock.ExpectQuery(regexp.QuoteMeta(sql)). 346 WithArgs(id). 347 WillReturnRows(rows) 348 349 // Execute method 350 _, err := cdb.PullRequestByID(id) 351 if err != nil { 352 t.Errorf("PullRequestByURL unwanted error: %s", err) 353 } 354 355 expectedError := database.ErrNoPullRequestFound 356 mock.ExpectQuery(regexp.QuoteMeta(sql)). 357 WithArgs(idNotFound). 358 WillReturnError(expectedError) 359 360 foundPr, err := cdb.PullRequestByID(idNotFound) 361 if err == nil { 362 t.Errorf("expecting error but there was none") 363 } 364 365 if foundPr != nil { 366 t.Errorf("expecting nil pr to be returned, but got non-nil pr") 367 } 368 369 // Make sure we got the expected error 370 if err != expectedError { 371 t.Errorf("expecting error %s but got %s", expectedError, err) 372 } 373 374 // Make sure expectations were met 375 err = mock.ExpectationsWereMet() 376 if err != nil { 377 t.Errorf("unfulfilled expectations: %s", err) 378 } 379 } 380 381 func TestMergedPullRequestsByUserDates(t *testing.T) { 382 cdb, mock, close := setupTestDB(t) 383 defer close() 384 385 now := time.Now() 386 prURLFirst := "https://github.com/decred/github/pull/1" 387 prURLSecond := "https://github.com/decred/github/pull/2" 388 prURLThird := "https://github.com/decred/github/pull/3" 389 390 prFirst := &database.PullRequest{ 391 Repo: "github", 392 Organization: "decred", 393 URL: prURLFirst, 394 Number: 1, 395 User: "stakey_author", 396 UpdatedAt: now.Unix(), 397 ClosedAt: now.Unix(), 398 MergedAt: now.Unix(), 399 Merged: true, 400 State: "MERGED", 401 Additions: 11, 402 Deletions: 11, 403 MergedBy: "davec", 404 } 405 406 prSecond := &database.PullRequest{ 407 Repo: "github", 408 Organization: "decred", 409 URL: prURLSecond, 410 Number: 2, 411 User: "stakey_author", 412 UpdatedAt: now.Unix(), 413 ClosedAt: now.Unix(), 414 MergedAt: now.Unix(), 415 Merged: true, 416 State: "MERGED", 417 Additions: 22, 418 Deletions: 22, 419 MergedBy: "davec", 420 } 421 422 prThird := &database.PullRequest{ 423 Repo: "github", 424 Organization: "decred", 425 URL: prURLThird, 426 Number: 3, 427 User: "stakey_author", 428 UpdatedAt: now.Unix(), 429 ClosedAt: now.Unix(), 430 MergedAt: now.Unix(), 431 Merged: true, 432 State: "MERGED", 433 Additions: 33, 434 Deletions: 33, 435 MergedBy: "davec", 436 } 437 438 // Mock rows data 439 rows := sqlmock.NewRows([]string{ 440 "repo", 441 "organization", 442 "url", 443 "number", 444 "author", 445 "updated_at", 446 "closed_at", 447 "merged_at", 448 "merged", 449 "state", 450 "additions", 451 "deletions", 452 "merged_by", 453 }).AddRow( 454 prFirst.Repo, 455 prFirst.Organization, 456 prFirst.URL, 457 prFirst.Number, 458 prFirst.User, 459 prFirst.UpdatedAt, 460 prFirst.ClosedAt, 461 prFirst.MergedAt, 462 prFirst.Merged, 463 prFirst.State, 464 prFirst.Additions, 465 prFirst.Deletions, 466 prFirst.MergedBy, 467 ).AddRow( 468 prSecond.Repo, 469 prSecond.Organization, 470 prSecond.URL, 471 prSecond.Number, 472 prSecond.User, 473 prSecond.UpdatedAt, 474 prSecond.ClosedAt, 475 prSecond.MergedAt, 476 prSecond.Merged, 477 prSecond.State, 478 prSecond.Additions, 479 prSecond.Deletions, 480 prSecond.MergedBy, 481 ).AddRow( 482 prThird.Repo, 483 prThird.Organization, 484 prThird.URL, 485 prThird.Number, 486 prThird.User, 487 prThird.UpdatedAt, 488 prThird.ClosedAt, 489 prThird.MergedAt, 490 prThird.Merged, 491 prThird.State, 492 prThird.Additions, 493 prThird.Deletions, 494 prThird.MergedBy, 495 ) 496 497 bothRangeStart := now.Add(-2 * time.Hour).Unix() 498 bothRangeEnd := now.Add(time.Minute).Unix() 499 500 // Query 501 sql := ` 502 SELECT * ` + 503 `FROM "pullrequests" ` + 504 `WHERE (author = $1 AND merged_at BETWEEN $2 AND $3)` 505 506 // Success Expectations 507 mock.ExpectQuery(regexp.QuoteMeta(sql)). 508 WithArgs(prFirst.User, bothRangeStart, bothRangeEnd). 509 WillReturnRows(rows) 510 511 // Execute method 512 _, err := cdb.MergedPullRequestsByUserDates(prFirst.User, bothRangeStart, 513 bothRangeEnd) 514 if err != nil { 515 t.Errorf("MergedPullRequestsByUserDates unwanted error: %s", err) 516 } 517 // Make sure expectations were met 518 err = mock.ExpectationsWereMet() 519 if err != nil { 520 t.Errorf("unfulfilled expectations: %s", err) 521 } 522 } 523 524 func TestUpdatedPullRequestsByUserDates(t *testing.T) { 525 cdb, mock, close := setupTestDB(t) 526 defer close() 527 528 now := time.Now() 529 prURLFirst := "https://github.com/decred/github/pull/1" 530 prURLSecond := "https://github.com/decred/github/pull/2" 531 prURLThird := "https://github.com/decred/github/pull/3" 532 533 prFirst := &database.PullRequest{ 534 Repo: "github", 535 Organization: "decred", 536 URL: prURLFirst, 537 Number: 1, 538 User: "stakey_author", 539 UpdatedAt: now.Unix(), 540 ClosedAt: now.Unix(), 541 MergedAt: now.Unix(), 542 Merged: false, 543 State: "UPDATED", 544 Additions: 11, 545 Deletions: 11, 546 MergedBy: "davec", 547 } 548 549 prSecond := &database.PullRequest{ 550 Repo: "github", 551 Organization: "decred", 552 URL: prURLSecond, 553 Number: 2, 554 User: "stakey_author", 555 UpdatedAt: now.Unix(), 556 ClosedAt: now.Unix(), 557 MergedAt: now.Unix(), 558 Merged: false, 559 State: "UPDATED", 560 Additions: 22, 561 Deletions: 22, 562 MergedBy: "davec", 563 } 564 565 prThird := &database.PullRequest{ 566 Repo: "github", 567 Organization: "decred", 568 URL: prURLThird, 569 Number: 3, 570 User: "stakey_author", 571 UpdatedAt: now.Unix(), 572 ClosedAt: now.Unix(), 573 MergedAt: now.Unix(), 574 Merged: false, 575 State: "UPDATED", 576 Additions: 33, 577 Deletions: 33, 578 MergedBy: "davec", 579 } 580 581 // Mock rows data 582 rows := sqlmock.NewRows([]string{ 583 "repo", 584 "organization", 585 "url", 586 "number", 587 "author", 588 "updated_at", 589 "closed_at", 590 "merged_at", 591 "merged", 592 "state", 593 "additions", 594 "deletions", 595 "merged_by", 596 }).AddRow( 597 prFirst.Repo, 598 prFirst.Organization, 599 prFirst.URL, 600 prFirst.Number, 601 prFirst.User, 602 prFirst.UpdatedAt, 603 prFirst.ClosedAt, 604 prFirst.MergedAt, 605 prFirst.Merged, 606 prFirst.State, 607 prFirst.Additions, 608 prFirst.Deletions, 609 prFirst.MergedBy, 610 ).AddRow( 611 prSecond.Repo, 612 prSecond.Organization, 613 prSecond.URL, 614 prSecond.Number, 615 prSecond.User, 616 prSecond.UpdatedAt, 617 prSecond.ClosedAt, 618 prSecond.MergedAt, 619 prSecond.Merged, 620 prSecond.State, 621 prSecond.Additions, 622 prSecond.Deletions, 623 prSecond.MergedBy, 624 ).AddRow( 625 prThird.Repo, 626 prThird.Organization, 627 prThird.URL, 628 prThird.Number, 629 prThird.User, 630 prThird.UpdatedAt, 631 prThird.ClosedAt, 632 prThird.MergedAt, 633 prThird.Merged, 634 prThird.State, 635 prThird.Additions, 636 prThird.Deletions, 637 prThird.MergedBy, 638 ) 639 640 bothRangeStart := now.Add(-2 * time.Hour).Unix() 641 bothRangeEnd := now.Add(time.Minute).Unix() 642 643 // Query 644 sql := ` 645 SELECT * FROM pullrequests 646 WHERE author = $1 AND updated_at IN 647 (SELECT 648 MAX(updated_at) 649 FROM pullrequests 650 WHERE updated_at BETWEEN $2 AND $3 651 GROUP BY url 652 ) 653 ` 654 655 // Success Expectations 656 mock.ExpectQuery(regexp.QuoteMeta(sql)). 657 WithArgs(prFirst.User, bothRangeStart, bothRangeEnd). 658 WillReturnRows(rows) 659 660 // Execute method 661 _, err := cdb.UpdatedPullRequestsByUserDates(prFirst.User, bothRangeStart, 662 bothRangeEnd) 663 if err != nil { 664 t.Errorf("UpdatedPullRequestsByUserDates unwanted error: %s", err) 665 } 666 // Make sure expectations were met 667 err = mock.ExpectationsWereMet() 668 if err != nil { 669 t.Errorf("unfulfilled expectations: %s", err) 670 } 671 } 672 func TestPullRequestsByURL(t *testing.T) { 673 cdb, mock, close := setupTestDB(t) 674 defer close() 675 676 now := time.Now() 677 prURLFirst := "https://github.com/decred/github/pull/1" 678 prURLSecond := "https://github.com/decred/github/pull/2" 679 prURLThird := "https://github.com/decred/github/pull/3" 680 681 prFirst := &database.PullRequest{ 682 Repo: "github", 683 Organization: "decred", 684 URL: prURLFirst, 685 Number: 1, 686 User: "stakey_author", 687 UpdatedAt: now.Unix(), 688 ClosedAt: now.Unix(), 689 MergedAt: now.Unix(), 690 Merged: true, 691 State: "MERGED", 692 Additions: 11, 693 Deletions: 11, 694 MergedBy: "davec", 695 } 696 697 prSecond := &database.PullRequest{ 698 Repo: "github", 699 Organization: "decred", 700 URL: prURLSecond, 701 Number: 2, 702 User: "stakey_author", 703 UpdatedAt: now.Unix(), 704 ClosedAt: now.Unix(), 705 MergedAt: now.Unix(), 706 Merged: true, 707 State: "MERGED", 708 Additions: 22, 709 Deletions: 22, 710 MergedBy: "davec", 711 } 712 713 prThird := &database.PullRequest{ 714 Repo: "github", 715 Organization: "decred", 716 URL: prURLThird, 717 Number: 3, 718 User: "stakey_author", 719 UpdatedAt: now.Unix(), 720 ClosedAt: now.Unix(), 721 MergedAt: now.Unix(), 722 Merged: true, 723 State: "MERGED", 724 Additions: 33, 725 Deletions: 33, 726 MergedBy: "davec", 727 } 728 729 // Mock rows data 730 rows := sqlmock.NewRows([]string{ 731 "repo", 732 "organization", 733 "url", 734 "number", 735 "author", 736 "updated_at", 737 "closed_at", 738 "merged_at", 739 "merged", 740 "state", 741 "additions", 742 "deletions", 743 "merged_by", 744 }).AddRow( 745 prFirst.Repo, 746 prFirst.Organization, 747 prFirst.URL, 748 prFirst.Number, 749 prFirst.User, 750 prFirst.UpdatedAt, 751 prFirst.ClosedAt, 752 prFirst.MergedAt, 753 prFirst.Merged, 754 prFirst.State, 755 prFirst.Additions, 756 prFirst.Deletions, 757 prFirst.MergedBy, 758 ).AddRow( 759 prSecond.Repo, 760 prSecond.Organization, 761 prSecond.URL, 762 prSecond.Number, 763 prSecond.User, 764 prSecond.UpdatedAt, 765 prSecond.ClosedAt, 766 prSecond.MergedAt, 767 prSecond.Merged, 768 prSecond.State, 769 prSecond.Additions, 770 prSecond.Deletions, 771 prSecond.MergedBy, 772 ).AddRow( 773 prThird.Repo, 774 prThird.Organization, 775 prThird.URL, 776 prThird.Number, 777 prThird.User, 778 prThird.UpdatedAt, 779 prThird.ClosedAt, 780 prThird.MergedAt, 781 prThird.Merged, 782 prThird.State, 783 prThird.Additions, 784 prThird.Deletions, 785 prThird.MergedBy, 786 ) 787 788 // Query 789 sql := ` 790 SELECT * ` + 791 `FROM "pullrequests" ` + 792 `WHERE (url = $1)` 793 794 // Success Expectations 795 mock.ExpectQuery(regexp.QuoteMeta(sql)). 796 WithArgs(prFirst.URL). 797 WillReturnRows(rows) 798 799 // Execute method 800 _, err := cdb.PullRequestsByURL(prFirst.URL) 801 if err != nil { 802 t.Errorf("PullRequestsByURL unwanted error: %s", err) 803 } 804 // Make sure expectations were met 805 err = mock.ExpectationsWereMet() 806 if err != nil { 807 t.Errorf("unfulfilled expectations: %s", err) 808 } 809 } 810 811 func TestReviewByID(t *testing.T) { 812 cdb, mock, close := setupTestDB(t) 813 defer close() 814 815 // Arguments 816 now := time.Now() 817 authorStakey := "stakey" 818 819 prURLFirst := "https://github.com/decred/github/pull/1" 820 821 reviewFirst := &database.PullRequestReview{ 822 ID: 434234234, 823 Repo: "github", 824 PullRequestURL: prURLFirst, 825 Number: 1, 826 Author: authorStakey, 827 SubmittedAt: now.Unix(), 828 State: "APPROVED", 829 Additions: 11, 830 Deletions: 11, 831 CommitID: "abcd1234", 832 } 833 834 rows := sqlmock.NewRows([]string{ 835 "pull_request_url", 836 "id", 837 "author", 838 "state", 839 "submitted_at", 840 "commit_id", 841 "repo", 842 "number", 843 }).AddRow( 844 reviewFirst.PullRequestURL, 845 reviewFirst.ID, 846 reviewFirst.Author, 847 reviewFirst.State, 848 reviewFirst.SubmittedAt, 849 reviewFirst.CommitID, 850 reviewFirst.Repo, 851 reviewFirst.Number, 852 ) 853 854 idNotFound := int64(123456) 855 // Query 856 sql := `SELECT * FROM "reviews" WHERE "reviews"."id" = $1` 857 858 // Success Expectations 859 mock.ExpectQuery(regexp.QuoteMeta(sql)). 860 WithArgs(reviewFirst.ID). 861 WillReturnRows(rows) 862 863 // Execute method 864 _, err := cdb.ReviewByID(reviewFirst.ID) 865 if err != nil { 866 t.Errorf("PullRequestByURL unwanted error: %s", err) 867 } 868 869 expectedError := database.ErrNoPullRequestReviewFound 870 mock.ExpectQuery(regexp.QuoteMeta(sql)). 871 WithArgs(idNotFound). 872 WillReturnError(expectedError) 873 874 foundPr, err := cdb.ReviewByID(idNotFound) 875 if err == nil { 876 t.Errorf("expecting error but there was none") 877 } 878 879 if foundPr != nil { 880 t.Errorf("expecting nil pr to be returned, but got non-nil pr") 881 } 882 883 // Make sure we got the expected error 884 if err != expectedError { 885 t.Errorf("expecting error %s but got %s", expectedError, err) 886 } 887 888 // Make sure expectations were met 889 err = mock.ExpectationsWereMet() 890 if err != nil { 891 t.Errorf("unfulfilled expectations: %s", err) 892 } 893 } 894 895 func TestReviewsByUserDates(t *testing.T) { 896 cdb, mock, close := setupTestDB(t) 897 defer close() 898 899 now := time.Now() 900 authorStakey := "stakey" 901 902 prURLFirst := "https://github.com/decred/github/pull/1" 903 prURLSecond := "https://github.com/decred/github/pull/2" 904 905 reviewFirst := &database.PullRequestReview{ 906 ID: 434234234, 907 Repo: "github", 908 PullRequestURL: prURLFirst, 909 Number: 1, 910 Author: authorStakey, 911 SubmittedAt: now.Unix(), 912 State: "APPROVED", 913 Additions: 11, 914 Deletions: 11, 915 CommitID: "abcd1234", 916 } 917 918 reviewSecond := &database.PullRequestReview{ 919 ID: 434234235, 920 Repo: "github", 921 PullRequestURL: prURLSecond, 922 Number: 2, 923 Author: authorStakey, 924 SubmittedAt: now.Add(-1 * time.Hour).Unix(), 925 State: "APPROVED", 926 CommitID: "abcd1236", 927 } 928 929 rows := sqlmock.NewRows([]string{ 930 "pull_request_url", 931 "id", 932 "author", 933 "state", 934 "submitted_at", 935 "commit_id", 936 "repo", 937 "number", 938 }).AddRow( 939 reviewFirst.PullRequestURL, 940 reviewFirst.ID, 941 reviewFirst.Author, 942 reviewFirst.State, 943 reviewFirst.SubmittedAt, 944 reviewFirst.CommitID, 945 reviewFirst.Repo, 946 reviewFirst.Number, 947 ).AddRow( 948 reviewSecond.PullRequestURL, 949 reviewSecond.ID, 950 reviewSecond.Author, 951 reviewSecond.State, 952 reviewSecond.SubmittedAt, 953 reviewSecond.CommitID, 954 reviewSecond.Repo, 955 reviewSecond.Number, 956 ) 957 958 bothRangeStart := now.Add(-2 * time.Hour).Unix() 959 bothRangeEnd := now.Add(time.Minute).Unix() 960 961 // Query 962 sql := ` 963 SELECT 964 reviews.pull_request_url, 965 reviews.id, 966 reviews.author, 967 reviews.state, 968 reviews.submitted_at, 969 reviews.commit_id, 970 reviews.repo, 971 reviews.number, 972 pullrequests.additions, 973 pullrequests.deletions 974 FROM reviews 975 INNER JOIN pullrequests 976 ON pullrequests.url = reviews.pull_request_url 977 WHERE reviews.author = $1 AND reviews.state = $2 AND 978 reviews.submitted_at BETWEEN $3 AND $4` 979 980 // Success Expectations 981 mock.ExpectQuery(regexp.QuoteMeta(sql)). 982 WithArgs(reviewFirst.Author, "APPROVED", bothRangeStart, bothRangeEnd). 983 WillReturnRows(rows) 984 985 // Execute method 986 _, err := cdb.ReviewsByUserDates(reviewFirst.Author, bothRangeStart, 987 bothRangeEnd) 988 if err != nil { 989 t.Errorf("ReviewsByUserDate unwanted error: %s", err) 990 } 991 992 // Make sure expectations were met 993 err = mock.ExpectationsWereMet() 994 if err != nil { 995 t.Errorf("unfulfilled expectations: %s", err) 996 } 997 } 998 999 func TestNewCommits(t *testing.T) { 1000 cdb, mock, close := setupTestDB(t) 1001 defer close() 1002 1003 now := time.Now() 1004 // Arguments 1005 sha := "40deb80dea8c560dfc851a6c0fce6f29f8ecb57a" 1006 url := "https://api.github.com/repos/decred/politeia/commits/40deb80dea8c560dfc851a6c0fce6f29f8ecb57a" 1007 commit := &database.Commit{ 1008 SHA: sha, 1009 URL: url, 1010 Organization: "decred", 1011 Repo: "politeia", 1012 Author: "stakey", 1013 Committer: "stakey", 1014 Date: now.Unix(), 1015 Message: "This is a sweet commit!", 1016 ParentSHA: "8575154a09049b042634333ad39c3a710c309105", 1017 ParentURL: "https://api.github.com/repos/decred/politeia/commits/8575154a09049b042634333ad39c3a710c309105", 1018 Additions: 100, 1019 Deletions: 99, 1020 } 1021 1022 // Queries 1023 sqlInsertPullRequests := `INSERT INTO "commits" ` + 1024 `("sha","repo","organization","date","author","committer","message",` + 1025 `"url","parent_sha","parent_url","additions","deletions") ` + 1026 `VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) ` + 1027 `RETURNING "commits"."sha"` 1028 1029 // Success Expectations 1030 mock.ExpectBegin() 1031 // Insert user to db 1032 mock.ExpectQuery(regexp.QuoteMeta(sqlInsertPullRequests)). 1033 WithArgs( 1034 commit.SHA, 1035 commit.Repo, 1036 commit.Organization, 1037 commit.Date, 1038 commit.Author, 1039 commit.Committer, 1040 commit.Message, 1041 commit.URL, 1042 commit.ParentSHA, 1043 commit.ParentURL, 1044 commit.Additions, 1045 commit.Deletions, 1046 ). 1047 WillReturnRows(sqlmock.NewRows([]string{"sha"}).AddRow(commit.SHA)) 1048 mock.ExpectCommit() 1049 1050 // Execute method 1051 err := cdb.NewCommit(commit) 1052 if err != nil { 1053 t.Errorf("UserNew unwanted error: %s", err) 1054 } 1055 1056 // Make sure expectations were met for both success and failure 1057 // conditions 1058 err = mock.ExpectationsWereMet() 1059 if err != nil { 1060 t.Errorf("unfulfilled expectations: %s", err) 1061 } 1062 } 1063 1064 func TestCommitsByUserDates(t *testing.T) { 1065 cdb, mock, close := setupTestDB(t) 1066 defer close() 1067 1068 now := time.Now() 1069 1070 commitFirst := &database.Commit{ 1071 SHA: "5a673974e617fc2a5bc67878d8161c103583d968", 1072 URL: "https://api.github.com/repos/decred/politeia/commits/5a673974e617fc2a5bc67878d8161c103583d968", 1073 Organization: "decred", 1074 Repo: "politeia", 1075 Author: "stakey", 1076 Committer: "stakey", 1077 Date: now.Unix(), 1078 Message: "This is a sweet commit! Again", 1079 ParentSHA: "8575154a09049b042634333ad39c3a710c309105", 1080 ParentURL: "https://api.github.com/repos/decred/politeia/commits/8575154a09049b042634333ad39c3a710c309105", 1081 Additions: 100, 1082 Deletions: 99, 1083 } 1084 1085 commitSecond := &database.Commit{ 1086 SHA: "8575154a09049b042634333ad39c3a710c309105", 1087 URL: "https://api.github.com/repos/decred/politeia/commits/8575154a09049b042634333ad39c3a710c309105", 1088 Organization: "decred", 1089 Repo: "politeia", 1090 Author: "stakey", 1091 Committer: "stakey", 1092 Date: now.Unix(), 1093 Message: "This is a sweet commit!", 1094 ParentSHA: "883f75a641b969ce0e7313219efcc0c94f30fd01", 1095 ParentURL: "https://api.github.com/repos/decred/politeia/commits/883f75a641b969ce0e7313219efcc0c94f30fd01", 1096 Additions: 100, 1097 Deletions: 99, 1098 } 1099 1100 rows := sqlmock.NewRows([]string{ 1101 "sha", 1102 "repo", 1103 "organization", 1104 "date", 1105 "author", 1106 "committer", 1107 "message", 1108 "url", 1109 "parent_sha", 1110 "parent_url", 1111 "additions", 1112 "deletions", 1113 }).AddRow( 1114 commitFirst.SHA, 1115 commitFirst.Repo, 1116 commitFirst.Organization, 1117 commitFirst.Date, 1118 commitFirst.Author, 1119 commitFirst.Committer, 1120 commitFirst.Message, 1121 commitFirst.URL, 1122 commitFirst.ParentSHA, 1123 commitFirst.ParentURL, 1124 commitFirst.Additions, 1125 commitFirst.Deletions, 1126 ).AddRow( 1127 commitSecond.SHA, 1128 commitSecond.Repo, 1129 commitSecond.Organization, 1130 commitSecond.Date, 1131 commitSecond.Author, 1132 commitSecond.Committer, 1133 commitSecond.Message, 1134 commitSecond.URL, 1135 commitSecond.ParentSHA, 1136 commitSecond.ParentURL, 1137 commitSecond.Additions, 1138 commitSecond.Deletions, 1139 ) 1140 1141 bothRangeStart := now.Add(-2 * time.Hour).Unix() 1142 bothRangeEnd := now.Add(time.Minute).Unix() 1143 1144 // Query 1145 sql := ` 1146 SELECT * 1147 FROM "commits" 1148 WHERE (author = $1 AND date BETWEEN $2 AND $3)` 1149 1150 // Success Expectations 1151 mock.ExpectQuery(regexp.QuoteMeta(sql)). 1152 WithArgs(commitFirst.Author, bothRangeStart, bothRangeEnd). 1153 WillReturnRows(rows) 1154 1155 // Execute method 1156 _, err := cdb.CommitsByUserDates(commitFirst.Author, bothRangeStart, 1157 bothRangeEnd) 1158 if err != nil { 1159 t.Errorf("ReviewsByUserDate unwanted error: %s", err) 1160 } 1161 1162 // Make sure expectations were met 1163 err = mock.ExpectationsWereMet() 1164 if err != nil { 1165 t.Errorf("unfulfilled expectations: %s", err) 1166 } 1167 } 1168 1169 func TestCommitBySHA(t *testing.T) { 1170 cdb, mock, close := setupTestDB(t) 1171 defer close() 1172 1173 // Arguments 1174 now := time.Now() 1175 commitFirst := &database.Commit{ 1176 SHA: "5a673974e617fc2a5bc67878d8161c103583d968", 1177 URL: "https://api.github.com/repos/decred/politeia/commits/5a673974e617fc2a5bc67878d8161c103583d968", 1178 Organization: "decred", 1179 Repo: "politeia", 1180 Author: "stakey", 1181 Committer: "stakey", 1182 Date: now.Unix(), 1183 Message: "This is a sweet commit! Again", 1184 ParentSHA: "8575154a09049b042634333ad39c3a710c309105", 1185 ParentURL: "https://api.github.com/repos/decred/politeia/commits/8575154a09049b042634333ad39c3a710c309105", 1186 Additions: 100, 1187 Deletions: 99, 1188 } 1189 1190 rows := sqlmock.NewRows([]string{ 1191 "sha", 1192 "repo", 1193 "organization", 1194 "date", 1195 "author", 1196 "committer", 1197 "message", 1198 "url", 1199 "parent_sha", 1200 "parent_url", 1201 "additions", 1202 "deletions", 1203 }).AddRow( 1204 commitFirst.SHA, 1205 commitFirst.Repo, 1206 commitFirst.Organization, 1207 commitFirst.Date, 1208 commitFirst.Author, 1209 commitFirst.Committer, 1210 commitFirst.Message, 1211 commitFirst.URL, 1212 commitFirst.ParentSHA, 1213 commitFirst.ParentURL, 1214 commitFirst.Additions, 1215 commitFirst.Deletions, 1216 ) 1217 1218 shaNotFound := "8575154a09049b042634333ad39c3a710c309105" 1219 1220 // Query 1221 sql := `SELECT * FROM "commits" WHERE "commits"."sha" = $1` 1222 1223 // Success Expectations 1224 mock.ExpectQuery(regexp.QuoteMeta(sql)). 1225 WithArgs(commitFirst.SHA). 1226 WillReturnRows(rows) 1227 1228 // Execute method 1229 _, err := cdb.CommitBySHA(commitFirst.SHA) 1230 if err != nil { 1231 t.Errorf("PullRequestByURL unwanted error: %s", err) 1232 } 1233 1234 expectedError := database.ErrNoCommitFound 1235 mock.ExpectQuery(regexp.QuoteMeta(sql)). 1236 WithArgs(shaNotFound). 1237 WillReturnError(expectedError) 1238 1239 foundPr, err := cdb.CommitBySHA(shaNotFound) 1240 if err == nil { 1241 t.Errorf("expecting error but there was none") 1242 } 1243 1244 if foundPr != nil { 1245 t.Errorf("expecting nil pr to be returned, but got non-nil pr") 1246 } 1247 1248 // Make sure we got the expected error 1249 if err != expectedError { 1250 t.Errorf("expecting error %s but got %s", expectedError, err) 1251 } 1252 1253 // Make sure expectations were met 1254 err = mock.ExpectationsWereMet() 1255 if err != nil { 1256 t.Errorf("unfulfilled expectations: %s", err) 1257 } 1258 }