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) } }) } }