package common_test import ( "errors" "testing" "go.uber.org/mock/gomock" "src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common/gitea-generated/models" mock_common "src.opensuse.org/autogits/common/mock" ) func TestReviews(t *testing.T) { tests := []struct { name string reviews []*models.PullReview timeline []*models.TimelineComment reviewers []string fetchErr error isApproved bool isReviewedByTest1 bool isPendingByTest1 bool }{ { name: "Reviews of PR with no review requirements", isApproved: true, }, { name: "Single reviewer done", reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}}, reviewers: []string{"user1"}, isApproved: true, isReviewedByTest1: true, }, { name: "Two reviewer, one not approved", reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}}, reviewers: []string{"user1", "user2"}, isApproved: false, isReviewedByTest1: true, }, { name: "Two reviewer, one stale approved", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, Stale: true}, }, reviewers: []string{"user1", "user2"}, isApproved: false, isReviewedByTest1: true, }, { name: "Two reviewer, one is pending", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateRequestReview, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, }, reviewers: []string{"user1", "user2"}, isApproved: false, isPendingByTest1: true, }, { name: "Two reviewer, one stale and pending", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateRequestReview, User: &models.User{UserName: "user1"}, Stale: true}, }, reviewers: []string{"user1", "user2"}, isApproved: false, isPendingByTest1: false, isReviewedByTest1: false, }, { name: "Two reviewer approved", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, }, reviewers: []string{"user1", "user2"}, isApproved: true, isReviewedByTest1: true, }, { name: "Two reviewer approved, one is dismissed", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, Dismissed: true}, }, reviewers: []string{"user1", "user2"}, isApproved: false, isReviewedByTest1: true, }, { name: "Two reviewer approved, but fetch error", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, }, reviewers: []string{"user1", "user2"}, fetchErr: errors.New("System error fetching reviews."), isApproved: true, isReviewedByTest1: true, }, { name: "Extra reviewers are ignored", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user4"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, }, reviewers: []string{"user1", "user2"}, isApproved: true, isReviewedByTest1: true, }, { name: "Review ignored before push", reviews: []*models.PullReview{ &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}, ID: 1001}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, ID: 1000}, }, timeline: []*models.TimelineComment{ &models.TimelineComment{Type: common.TimelineCommentType_Review, ReviewID: 1001}, &models.TimelineComment{Type: common.TimelineCommentType_PushPull}, &models.TimelineComment{Type: common.TimelineCommentType_Review, ReviewID: 1000}, }, reviewers: []string{"user1", "user2"}, isApproved: false, isReviewedByTest1: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { ctl := gomock.NewController(t) rf := mock_common.NewMockGiteaReviewTimelineFetcher(ctl) if test.timeline == nil { test.timeline = reviewsToTimeline(test.reviews) } rf.EXPECT().GetTimeline("test", "pr", int64(1)).Return(test.timeline, nil) rf.EXPECT().GetPullRequestReviews("test", "pr", int64(1)).Return(test.reviews, test.fetchErr) reviews, err := common.FetchGiteaReviews(rf, test.reviewers, "test", "pr", 1) if test.fetchErr != nil { if err != test.fetchErr { t.Fatal("FetchReviews() failed with unexpected error:", err) } return } if r := reviews.IsApproved(); r != test.isApproved { t.Fatal("Unexpected IsReviewed():", r, "vs. expected", test.isApproved) } if r := reviews.HasPendingReviewBy("user1"); r != test.isPendingByTest1 { t.Fatal("Unexpected IsReviewPendingBy(user1):", r) } if r := reviews.IsReviewedBy("user1"); r != test.isReviewedByTest1 { t.Fatal("Unexpected IsReviewedBy(user1):", r) } if r := reviews.HasPendingReviewBy("random"); r { t.Fatal("Unexpected IsReviewPendingBy(random):", r) } if r := reviews.IsReviewedBy("random"); r { t.Fatal("Unexpected IsReviewedBy(random):", r) } }) } }