add review checks

This commit is contained in:
Adam Majer 2025-01-11 21:37:59 +01:00
parent 8ab35475fc
commit e63a450c5d
5 changed files with 71 additions and 32 deletions

View File

@ -65,7 +65,7 @@ type GiteaPRFetcher interface {
} }
type GiteaReviewFetcher interface { type GiteaReviewFetcher interface {
GetPullRequestReviews(org, project string, num int64) ([]*models.PullReview, error) GetPullRequestReviews(org, project string, PRnum int64) ([]*models.PullReview, error)
} }
type GiteaReviewRequester interface { type GiteaReviewRequester interface {

View File

@ -11,7 +11,7 @@ import (
) )
type PRInfo struct { type PRInfo struct {
pr *models.PullRequest pr *models.PullRequest
} }
type PRSet struct { type PRSet struct {
@ -96,7 +96,18 @@ func (rs *PRSet) IsConsistent() bool {
return true return true
} }
func (rs *PRSet) IsReviewed() bool { func (rs *PRSet) IsReviewed(gitea common.GiteaReviewFetcher) bool {
return false common_reviwers := rs.config.Reviewers
is_reviewed := false
for _, pr := range rs.prs {
r, err := FetchGiteaReviews(gitea, common_reviwers, pr.pr.Base.Repo.Owner.UserName, pr.pr.Base.Repo.Name, pr.pr.Index)
if err != nil {
return false
}
is_reviewed = r.IsReviewed()
if !is_reviewed {
return false
}
}
return is_reviewed
} }

View File

@ -29,8 +29,10 @@ func TestPR(t *testing.T) {
} }
type prdata struct { type prdata struct {
pr *models.PullRequest pr *models.PullRequest
err error pr_err error
reviews []*models.PullReview
review_error error
} }
t.Run("TestPR", func(t *testing.T) { t.Run("TestPR", func(t *testing.T) {
@ -44,13 +46,12 @@ func TestPR(t *testing.T) {
consistentSet bool consistentSet bool
prjGitPRIndex int prjGitPRIndex int
customMockSetup func(*mock_common.MockGiteaPRFetcher) error
reviewSetFetcher func(*mock_common.MockGiteaPRFetcher) (*PRSet, error) reviewSetFetcher func(*mock_common.MockGiteaPRFetcher) (*PRSet, error)
}{ }{
{ {
name: "Error fetching PullRequest", name: "Error fetching PullRequest",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}, err: errors.New("Missing PR")}, {pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}, pr_err: errors.New("Missing PR")},
}, },
}, },
@ -58,7 +59,7 @@ func TestPR(t *testing.T) {
name: "Error fetching PullRequest in PrjGit", name: "Error fetching PullRequest in PrjGit",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "PR: foo/barPrj#22", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}}, {pr: &models.PullRequest{Body: "PR: foo/barPrj#22", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
{pr: &models.PullRequest{Body: "", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}, err: errors.New("Missing PR")}, {pr: &models.PullRequest{Body: "", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}, pr_err: errors.New("Missing PR")},
}, },
}, },
@ -104,11 +105,18 @@ func TestPR(t *testing.T) {
{ {
name: "Review set of prjgit PR is consistent", name: "Review set of prjgit PR is consistent",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}}, {
pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
}, },
resLen: 1, resLen: 1,
prjGitPRIndex: 0, prjGitPRIndex: 0,
consistentSet: true, consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRFetcher) (*PRSet, error) { reviewSetFetcher: func(mock *mock_common.MockGiteaPRFetcher) (*PRSet, error) {
return FetchPRSet(mock, "foo", "barPrj", 42, &baseConfig) return FetchPRSet(mock, "foo", "barPrj", 42, &baseConfig)
}, },
@ -139,29 +147,27 @@ func TestPR(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
mock := mock_common.NewMockGiteaPRFetcher(ctl) pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
review_mock := mock_common.NewMockGiteaReviewFetcher(ctl)
var test_err error var test_err error
if test.customMockSetup != nil { for _, data := range test.data {
if err := test.customMockSetup(mock); err != nil { pr_mock.EXPECT().GetPullRequest(data.pr.Base.Repo.Owner.UserName, data.pr.Base.Repo.Name, data.pr.Index).Return(data.pr, data.pr_err).AnyTimes()
test_err = err if data.pr_err != nil {
} test_err = data.pr_err
} else {
for _, data := range test.data {
mock.EXPECT().GetPullRequest(data.pr.Base.Repo.Owner.UserName, data.pr.Base.Repo.Name, data.pr.Index).Return(data.pr, data.err).AnyTimes()
if data.err != nil {
test_err = data.err
}
} }
review_mock.EXPECT().GetPullRequestReviews(data.pr.Base.Repo.Owner.UserName, data.pr.Base.Repo.Name, data.pr.Index).Return(data.reviews, data.review_error).AnyTimes()
} }
var res *PRSet var res *PRSet
var err error var err error
if test.reviewSetFetcher != nil { if test.reviewSetFetcher != nil {
res, err = test.reviewSetFetcher(mock) res, err = test.reviewSetFetcher(pr_mock)
} else { } else {
res, err = FetchPRSet(mock, "test", "repo", 42, &baseConfig) res, err = FetchPRSet(pr_mock, "test", "repo", 42, &baseConfig)
} }
if err == nil { if err == nil {
if test_err != nil { if test_err != nil {
t.Fatal("Expected", test_err, "but got", err) t.Fatal("Expected", test_err, "but got", err)
@ -181,8 +187,6 @@ func TestPR(t *testing.T) {
return return
} }
t.Log(res)
if test.resLen != len(res.prs) { if test.resLen != len(res.prs) {
t.Error("expected result len", test.resLen, "but got", len(res.prs)) t.Error("expected result len", test.resLen, "but got", len(res.prs))
} }
@ -214,8 +218,8 @@ func TestPR(t *testing.T) {
t.Error("IsConsistent() returned unexpected:", test.consistentSet) t.Error("IsConsistent() returned unexpected:", test.consistentSet)
} }
if res.IsReviewed() != test.reviewed { if isReviewed := res.IsReviewed(review_mock); isReviewed != test.reviewed {
t.Error("expected reviewed to be NOT", res.IsReviewed()) t.Error("expected reviewed to be NOT", isReviewed)
} }
}) })
} }

View File

@ -10,7 +10,7 @@ type PRReviews struct {
reviewers []string reviewers []string
} }
func FetchReviews(rf common.GiteaReviewFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) { func FetchGiteaReviews(rf common.GiteaReviewFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) {
reviews, err := rf.GetPullRequestReviews(org, repo, no) reviews, err := rf.GetPullRequestReviews(org, repo, no)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"testing" "testing"
"go.uber.org/mock/gomock" "go.uber.org/mock/gomock"
@ -51,6 +52,26 @@ func TestReviews(t *testing.T) {
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isReviewed: true, isReviewed: 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."),
isReviewed: 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"},
isReviewed: true,
},
} }
for _, test := range tests { for _, test := range tests {
@ -60,10 +81,13 @@ func TestReviews(t *testing.T) {
rf.EXPECT().GetPullRequestReviews("test", "pr", int64(1)).Return(test.reviews, test.fetchErr) rf.EXPECT().GetPullRequestReviews("test", "pr", int64(1)).Return(test.reviews, test.fetchErr)
reviews, err := FetchReviews(rf, test.reviewers, "test", "pr", 1) reviews, err := FetchGiteaReviews(rf, test.reviewers, "test", "pr", 1)
if err != test.fetchErr { if test.fetchErr != nil {
t.Fatal("FetchReviews() failed with unexpected error:", err) if err != test.fetchErr {
t.Fatal("FetchReviews() failed with unexpected error:", err)
}
return
} }
if r := reviews.IsReviewed(); r != test.isReviewed { if r := reviews.IsReviewed(); r != test.isReviewed {