diff --git a/workflow-pr/pr.go b/workflow-pr/pr.go index 4688c28..979fade 100644 --- a/workflow-pr/pr.go +++ b/workflow-pr/pr.go @@ -12,10 +12,9 @@ import ( type PRInfo struct { pr *models.PullRequest - reviews []*models.PullReview } -type ReviewSet struct { +type PRSet struct { prs []PRInfo config *common.AutogitConfig } @@ -46,16 +45,16 @@ func readPRData(gitea common.GiteaPRFetcher, org, repo string, num int64, curren return retSet, nil } -func FetchReviewSet(gitea common.GiteaPRFetcher, org, repo string, num int64, config *common.AutogitConfig) (*ReviewSet, error) { +func FetchPRSet(gitea common.GiteaPRFetcher, org, repo string, num int64, config *common.AutogitConfig) (*PRSet, error) { prs, err := readPRData(gitea, org, repo, num, nil) if err != nil { return nil, err } - return &ReviewSet{prs: prs, config: config}, nil + return &PRSet{prs: prs, config: config}, nil } -func (rs *ReviewSet) GetPrjGitPR() (*models.PullRequest, error) { +func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) { var ret *models.PullRequest for _, prinfo := range rs.prs { @@ -75,7 +74,7 @@ func (rs *ReviewSet) GetPrjGitPR() (*models.PullRequest, error) { return nil, errors.New("No PrjGit PR found") } -func (rs *ReviewSet) IsConsistent() bool { +func (rs *PRSet) IsConsistent() bool { prjpr, err := rs.GetPrjGitPR() if err != nil { return false @@ -97,7 +96,7 @@ func (rs *ReviewSet) IsConsistent() bool { return true } -func (rs *ReviewSet) IsReviewed() bool { +func (rs *PRSet) IsReviewed() bool { return false } diff --git a/workflow-pr/pr_test.go b/workflow-pr/pr_test.go index f7dbd63..fe45e21 100644 --- a/workflow-pr/pr_test.go +++ b/workflow-pr/pr_test.go @@ -45,7 +45,7 @@ func TestPR(t *testing.T) { prjGitPRIndex int customMockSetup func(*mock_common.MockGiteaPRFetcher) error - reviewSetFetcher func(*mock_common.MockGiteaPRFetcher) (*ReviewSet, error) + reviewSetFetcher func(*mock_common.MockGiteaPRFetcher) (*PRSet, error) }{ { name: "Error fetching PullRequest", @@ -109,8 +109,8 @@ func TestPR(t *testing.T) { resLen: 1, prjGitPRIndex: 0, consistentSet: true, - reviewSetFetcher: func(mock *mock_common.MockGiteaPRFetcher) (*ReviewSet, error) { - return FetchReviewSet(mock, "foo", "barPrj", 42, &baseConfig) + reviewSetFetcher: func(mock *mock_common.MockGiteaPRFetcher) (*PRSet, error) { + return FetchPRSet(mock, "foo", "barPrj", 42, &baseConfig) }, }, { @@ -155,12 +155,12 @@ func TestPR(t *testing.T) { } } - var res *ReviewSet + var res *PRSet var err error if test.reviewSetFetcher != nil { res, err = test.reviewSetFetcher(mock) } else { - res, err = FetchReviewSet(mock, "test", "repo", 42, &baseConfig) + res, err = FetchPRSet(mock, "test", "repo", 42, &baseConfig) } if err == nil { if test_err != nil { diff --git a/workflow-pr/reviews.go b/workflow-pr/reviews.go new file mode 100644 index 0000000..9ab1e9b --- /dev/null +++ b/workflow-pr/reviews.go @@ -0,0 +1,43 @@ +package main + +import ( + "src.opensuse.org/autogits/common" + "src.opensuse.org/autogits/common/gitea-generated/models" +) + +type PRReviews struct { + reviews []*models.PullReview + reviewers []string +} + +func FetchReviews(rf common.GiteaReviewFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) { + reviews, err := rf.GetPullRequestReviews(org, repo, no) + if err != nil { + return nil, err + } + + return &PRReviews{ + reviews: reviews, + reviewers: reviewers, + }, nil +} + +func (r *PRReviews) IsReviewed() bool { + goodReview := false + + for _, reviewer := range r.reviewers { + goodReview = false + for _, review := range r.reviews { + if review.User.UserName == reviewer && review.State == common.ReviewStateApproved && !review.Stale { + goodReview = true + break + } + } + + if !goodReview { + break + } + } + + return goodReview +} diff --git a/workflow-pr/reviews_test.go b/workflow-pr/reviews_test.go new file mode 100644 index 0000000..4d54dcb --- /dev/null +++ b/workflow-pr/reviews_test.go @@ -0,0 +1,74 @@ +package main + +import ( + "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 + reviewers []string + fetchErr error + isReviewed bool + }{ + { + name: "Reviews of unreviews PR", + isReviewed: false, + }, + { + name: "Single reviewer done", + reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}}, + reviewers: []string{"user1"}, + isReviewed: true, + }, + { + name: "Two reviewer, one not approved", + reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}}, + reviewers: []string{"user1", "user2"}, + isReviewed: false, + }, + { + 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"}, + isReviewed: 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"}, + isReviewed: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ctl := gomock.NewController(t) + rf := mock_common.NewMockGiteaReviewFetcher(ctl) + + rf.EXPECT().GetPullRequestReviews("test", "pr", int64(1)).Return(test.reviews, test.fetchErr) + + reviews, err := FetchReviews(rf, test.reviewers, "test", "pr", 1) + + if err != test.fetchErr { + t.Fatal("FetchReviews() failed with unexpected error:", err) + } + + if r := reviews.IsReviewed(); r != test.isReviewed { + t.Fatal("Unexpected IsReviewed():", r, "vs. expected", test.isReviewed) + } + }) + } +}