autogits/workflow-pr/maintainership_test.go
2024-12-11 01:12:59 +01:00

229 lines
6.3 KiB
Go

package main
import (
"errors"
"slices"
"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"
mock_main "src.opensuse.org/workflow-pr/mock"
)
func TestMaintainership(t *testing.T) {
config := common.AutogitConfig{
Branch: "bar",
Organization: "foo",
GitProjectName: common.DefaultGitPrj,
}
packageTests := []struct {
name string
maintainersFile []byte
maintainersFileErr error
maintainers []string
otherError bool
}{
{
name: "No maintainer in empty package",
},
{
name: "Error in MaintainerListForPackage when remote has an error",
maintainersFileErr: errors.New("some error here"),
},
{
name: "Multiple package maintainers",
maintainersFile: []byte(`{"pkg": ["user1", "user2"], "": ["user1", "user3"]}`),
maintainers: []string{"user1", "user2", "user3"},
},
{
name: "No package maintainers and only project maintainer",
maintainersFile: []byte(`{"pkg2": ["user1", "user2"], "": ["user1", "user3"]}`),
maintainers: []string{"user1", "user3"},
},
{
name: "Invalid list of package maintainers",
maintainersFile: []byte(`{"pkg": 3,"": ["user", 4]}`),
otherError: true,
},
}
for _, test := range packageTests {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
mi := mock_common.NewMockGiteaMaintainershipInterface(ctl)
mi.EXPECT().FetchMaintainershipFile("foo", common.DefaultGitPrj, "bar").
Return(test.maintainersFile, test.maintainersFileErr)
maintainers, err := ProjectMaintainershipData(mi, config.Organization, config.GitProjectName, config.Branch)
if err != nil && !test.otherError {
if test.maintainersFileErr == nil {
t.Fatal("Unexpected error recieved", err)
} else if err != test.maintainersFileErr {
t.Error("Unexpected error recieved", err)
}
} else if test.maintainersFileErr != nil {
t.Fatal("Expected an error...")
} else if test.otherError && err == nil {
t.Fatal("Expected an error...")
}
m := MaintainerListForPackage(maintainers, "pkg")
if len(m) != len(test.maintainers) {
t.Error("Invalid number of maintainers for package", err)
}
for i := range m {
if !slices.Contains(test.maintainers, m[i]) {
t.Fatal("Can't find expected users. Found:", m)
}
}
})
}
projectTests := []struct {
name string
maintainersFile []byte
maintainersFileErr error
numMaintainers int
maintainers []string
otherError bool
}{
{
name: "No maintainer for empty project",
},
{
name: "No maintainer for empty project maintainer file",
maintainersFile: []byte("{}"),
},
{
name: "Error in MaintainerListForProject when remote has an error",
maintainersFileErr: errors.New("some error here"),
},
{
name: "Multiple project maintainers",
maintainersFile: []byte(`{"": ["user1", "user2"]}`),
numMaintainers: 2,
maintainers: []string{"user1", "user2"},
},
{
name: "Single project maintainer",
maintainersFile: []byte(`{"": ["user"]}`),
numMaintainers: 1,
maintainers: []string{"user"},
},
{
name: "Invalid list of project maintainers",
maintainersFile: []byte(`{"": ["user", 4]}`),
otherError: true,
},
{
name: "Invalid list of project maintainers",
maintainersFile: []byte(`{"": 4}`),
otherError: true,
},
}
for _, test := range projectTests {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
mi := mock_common.NewMockGiteaMaintainershipInterface(ctl)
mi.EXPECT().FetchMaintainershipFile("foo", common.DefaultGitPrj, "bar").
Return(test.maintainersFile, test.maintainersFileErr)
maintainers, err := ProjectMaintainershipData(mi, config.Organization, config.GitProjectName, config.Branch)
if err != nil && !test.otherError {
if test.maintainersFileErr == nil {
t.Fatal("Unexpected error recieved", err)
} else if err != test.maintainersFileErr {
t.Error("Unexpected error recieved", err)
}
} else if test.maintainersFileErr != nil {
t.Fatal("Expected an error...")
} else if test.otherError && err == nil {
t.Fatal("Expected an error...")
}
m := MaintainerListForProject(maintainers)
if len(m) != test.numMaintainers {
t.Error("Invalid number of maintainers", err)
}
for i := range m {
if i >= len(test.maintainers) || test.maintainers[i] != m[i] {
t.Error("Can't find expected users. Found:", m)
}
}
})
}
}
func TestReviewApproval(t *testing.T) {
config := common.AutogitConfig{
Branch: "bar",
Organization: "foo",
GitProjectName: common.DefaultGitPrj,
}
tests := []struct {
name string
pr *models.PullRequest
reviews []*models.PullReview
maintainerFile []byte
approved bool
}{
{
name: "Maintainer not approved",
pr: &models.PullRequest{Body: "PR: foo/foo#10", Index: 10, RequestedReviewers: []*models.User{}},
reviews: []*models.PullReview{},
maintainerFile: []byte(`{"foo": ["bingo"]}`),
approved: false,
},
{
name: "Maintainer approved",
pr: &models.PullRequest{Body: "", Index: 10, RequestedReviewers: []*models.User{}},
reviews: []*models.PullReview{
&models.PullReview{
Body: "wow!",
Stale: false,
State: common.ReviewStateApproved,
User: &models.User{
UserName: "king",
},
},
},
maintainerFile: []byte(`{"": ["king"], "foo": ["bingo"]}`),
approved: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
mi := mock_common.NewMockGiteaMaintainershipInterface(ctl)
pri := mock_main.NewMockGiteaPRInterface(ctl)
pri.EXPECT().GetPullRequestAndReviews("foo", common.DefaultGitPrj, int64(10)).
Return(test.pr, test.reviews, nil)
mi.EXPECT().FetchMaintainershipFile("foo", common.DefaultGitPrj, "bar").Return(test.maintainerFile, nil)
approved, err := IsPrjGitPRApproved(mi, pri, config, 10)
if approved != test.approved {
t.Error("Unexpected approve state:", approved, "vs. expected", test.approved, ", or err:", err)
}
if err != nil {
t.Error("Unexpected error", err)
}
})
}
}