639 lines
19 KiB
Go
639 lines
19 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/go-openapi/strfmt"
|
|
"go.uber.org/mock/gomock"
|
|
"src.opensuse.org/autogits/common"
|
|
"src.opensuse.org/autogits/common/gitea-generated/models"
|
|
mock "src.opensuse.org/autogits/common/mock"
|
|
"src.opensuse.org/autogits/common/test_utils"
|
|
)
|
|
|
|
type MockMaintainershipFetcher struct {
|
|
data common.MaintainershipData
|
|
err error
|
|
}
|
|
|
|
func (m *MockMaintainershipFetcher) FetchProjectMaintainershipData(gitea common.GiteaMaintainershipReader, config *common.AutogitConfig) (common.MaintainershipData, error) {
|
|
return m.data, m.err
|
|
}
|
|
|
|
type MockMaintainershipData struct {
|
|
maintainers []string
|
|
}
|
|
|
|
func (m *MockMaintainershipData) ListProjectMaintainers(groups []*common.ReviewGroup) []string {
|
|
return m.maintainers
|
|
}
|
|
func (m *MockMaintainershipData) ListPackageMaintainers(pkg string, groups []*common.ReviewGroup) []string {
|
|
return m.maintainers
|
|
}
|
|
func (m *MockMaintainershipData) IsApproved(pkg string, reviews []*models.PullReview, submitter string, groups []*common.ReviewGroup) bool {
|
|
return true
|
|
}
|
|
|
|
func TestParseSourceReposFromIssue(t *testing.T) {
|
|
bot := &ReparentBot{}
|
|
tests := []struct {
|
|
name string
|
|
body string
|
|
expected []RepoInfo
|
|
}{
|
|
{
|
|
name: "single repo",
|
|
body: "https://src.opensuse.org/owner/repo",
|
|
expected: []RepoInfo{
|
|
{Owner: "owner", Name: "repo", Branch: ""},
|
|
},
|
|
},
|
|
{
|
|
name: "repo with branch",
|
|
body: "https://src.opensuse.org/owner/repo#branch",
|
|
expected: []RepoInfo{
|
|
{Owner: "owner", Name: "repo", Branch: "branch"},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple repos",
|
|
body: "Check these out:\nhttps://src.opensuse.org/o1/r1\nhttps://src.opensuse.org/o2/r2#b2",
|
|
expected: []RepoInfo{
|
|
{Owner: "o1", Name: "r1", Branch: ""},
|
|
{Owner: "o2", Name: "r2", Branch: "b2"},
|
|
},
|
|
},
|
|
{
|
|
name: "no repos",
|
|
body: "Nothing here",
|
|
expected: nil,
|
|
},
|
|
{
|
|
name: "not matching url",
|
|
body: "invalid link",
|
|
expected: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := bot.ParseSourceReposFromIssue(&models.Issue{Body: tc.body})
|
|
if len(got) != len(tc.expected) {
|
|
t.Fatalf("expected %d repos, got %d", len(tc.expected), len(got))
|
|
}
|
|
for i := range got {
|
|
if got[i] != tc.expected[i] {
|
|
t.Errorf("at index %d: expected %+v, got %+v", i, tc.expected[i], got[i])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsMaintainer(t *testing.T) {
|
|
bot := &ReparentBot{}
|
|
maintainers := []string{"alice", "bob"}
|
|
tests := []struct {
|
|
user string
|
|
expected bool
|
|
}{
|
|
{"alice", true},
|
|
{"bob", true},
|
|
{"charlie", false},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.user, func(t *testing.T) {
|
|
if got := bot.IsMaintainer(tc.user, maintainers); got != tc.expected {
|
|
t.Errorf("expected %v for %s, got %v", tc.expected, tc.user, got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsApproval(t *testing.T) {
|
|
bot := &ReparentBot{}
|
|
tests := []struct {
|
|
body string
|
|
expected bool
|
|
}{
|
|
{"approved", true},
|
|
{"LGTM", true},
|
|
{"Looks good to me, approved!", true},
|
|
{"not yet", false},
|
|
{"", false},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.body, func(t *testing.T) {
|
|
if got := bot.IsApproval(tc.body); got != tc.expected {
|
|
t.Errorf("expected %v for %s, got %v", tc.expected, tc.body, got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasComment(t *testing.T) {
|
|
bot := &ReparentBot{botUser: "bot"}
|
|
timeline := []*models.TimelineComment{
|
|
{Type: common.TimelineCommentType_Comment, User: &models.User{UserName: "user"}, Body: "hello"},
|
|
{Type: common.TimelineCommentType_Comment, User: &models.User{UserName: "bot"}, Body: "ping"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
msg string
|
|
expected bool
|
|
}{
|
|
{"exists", "ping", true},
|
|
{"exists with spaces", " ping ", true},
|
|
{"not exists", "pong", false},
|
|
{"other user", "hello", false},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := bot.HasComment(timeline, tc.msg); got != tc.expected {
|
|
t.Errorf("expected %v for %s, got %v", tc.expected, tc.msg, got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestProcessIssue(t *testing.T) {
|
|
var mockGitea *mock.MockGitea
|
|
mockFetcher := &MockMaintainershipFetcher{}
|
|
bot := &ReparentBot{
|
|
botUser: "bot",
|
|
maintainershipFetcher: mockFetcher,
|
|
configs: common.AutogitConfigs{
|
|
&common.AutogitConfig{Organization: "org", Branch: "master"},
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
issue *models.Issue
|
|
dryRun bool
|
|
setupMock func()
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "closed issue",
|
|
issue: &models.Issue{
|
|
State: "closed",
|
|
},
|
|
setupMock: func() {},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "no [ADD] prefix",
|
|
issue: &models.Issue{
|
|
State: "open",
|
|
Title: "Just a comment",
|
|
},
|
|
setupMock: func() {},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "no NewRepository label",
|
|
issue: &models.Issue{
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
},
|
|
setupMock: func() {},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "timeline fetch error",
|
|
issue: &models.Issue{
|
|
Index: 10,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(10)).Return(nil, errors.New("error"))
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no source repos parsed",
|
|
issue: &models.Issue{
|
|
Index: 11,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Body: "No links here",
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(11)).Return(nil, nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "missing config",
|
|
issue: &models.Issue{
|
|
Index: 1,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/wrong-branch",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(1)).Return(nil, nil)
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "config found in loop",
|
|
issue: &models.Issue{
|
|
Index: 6,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(6)).Return(nil, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(&models.Repository{DefaultBranch: "master"}, nil)
|
|
mockGitea.EXPECT().GetRepository("org", "repo").Return(nil, nil)
|
|
mockGitea.EXPECT().UpdateIssue("org", "repo", int64(6), gomock.Any()).Return(nil, nil)
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), gomock.Any()).Return(nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "maintainer fetch error",
|
|
issue: &models.Issue{
|
|
Index: 12,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(12)).Return(nil, nil)
|
|
mockFetcher.err = errors.New("error")
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no maintainers found",
|
|
issue: &models.Issue{
|
|
Index: 13,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(13)).Return(nil, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: nil}
|
|
mockFetcher.err = nil
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "not approved - requests review",
|
|
issue: &models.Issue{
|
|
Index: 2,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(2)).Return(nil, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(&models.Repository{DefaultBranch: "master"}, nil)
|
|
mockGitea.EXPECT().GetRepository("org", "repo").Return(nil, nil)
|
|
mockGitea.EXPECT().UpdateIssue("org", "repo", int64(2), gomock.Any()).Return(nil, nil)
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), gomock.Any()).Return(nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "approved - processes repos",
|
|
issue: &models.Issue{
|
|
Index: 3,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
User: &models.User{UserName: "owner"},
|
|
},
|
|
setupMock: func() {
|
|
timeline := []*models.TimelineComment{
|
|
{
|
|
Type: common.TimelineCommentType_Comment,
|
|
User: &models.User{UserName: "m1"},
|
|
Body: "approved",
|
|
},
|
|
}
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(3)).Return(timeline, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
|
|
repo := &models.Repository{Name: "repo", Owner: &models.User{UserName: "owner"}, DefaultBranch: "master"}
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(repo, nil)
|
|
mockGitea.EXPECT().GetRepository("org", "repo").Return(nil, nil)
|
|
mockGitea.EXPECT().ReparentRepository("owner", "repo", "org").Return(nil, nil)
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), gomock.Any()).Return(nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "approved - dry run",
|
|
dryRun: true,
|
|
issue: &models.Issue{
|
|
Index: 3,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
User: &models.User{UserName: "owner"},
|
|
},
|
|
setupMock: func() {
|
|
timeline := []*models.TimelineComment{
|
|
{
|
|
Type: common.TimelineCommentType_Comment,
|
|
User: &models.User{UserName: "m1"},
|
|
Body: "approved",
|
|
},
|
|
}
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(3)).Return(timeline, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(&models.Repository{DefaultBranch: "master"}, nil)
|
|
mockGitea.EXPECT().GetRepository("org", "repo").Return(nil, nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "approved - source repo fetch error",
|
|
issue: &models.Issue{
|
|
Index: 3,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
User: &models.User{UserName: "owner"},
|
|
},
|
|
setupMock: func() {
|
|
timeline := []*models.TimelineComment{
|
|
{
|
|
Type: common.TimelineCommentType_Comment,
|
|
User: &models.User{UserName: "m1"},
|
|
Body: "approved",
|
|
},
|
|
}
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(3)).Return(timeline, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(nil, errors.New("error"))
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "approved - source repo not found",
|
|
issue: &models.Issue{
|
|
Index: 3,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
User: &models.User{UserName: "owner"},
|
|
},
|
|
setupMock: func() {
|
|
timeline := []*models.TimelineComment{
|
|
{
|
|
Type: common.TimelineCommentType_Comment,
|
|
User: &models.User{UserName: "m1"},
|
|
Body: "approved",
|
|
},
|
|
}
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(3)).Return(timeline, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(nil, nil)
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), gomock.Any()).Return(nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "approved - reparent error",
|
|
issue: &models.Issue{
|
|
Index: 3,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
User: &models.User{UserName: "owner"},
|
|
},
|
|
setupMock: func() {
|
|
timeline := []*models.TimelineComment{
|
|
{
|
|
Type: common.TimelineCommentType_Comment,
|
|
User: &models.User{UserName: "m1"},
|
|
Body: "approved",
|
|
},
|
|
}
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(3)).Return(timeline, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
|
|
repo := &models.Repository{Name: "repo", Owner: &models.User{UserName: "owner"}, DefaultBranch: "master"}
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(repo, nil)
|
|
mockGitea.EXPECT().GetRepository("org", "repo").Return(nil, nil)
|
|
mockGitea.EXPECT().ReparentRepository("owner", "repo", "org").Return(nil, errors.New("error"))
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "user nil panic",
|
|
issue: &models.Issue{
|
|
Index: 99,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo",
|
|
User: nil,
|
|
},
|
|
setupMock: func() {
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(99)).Return(nil, nil)
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
mockGitea.EXPECT().GetRepository("owner", "repo").Return(&models.Repository{DefaultBranch: "master", Fork: true}, nil)
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), gomock.Any()).Return(nil)
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
ctrl := test_utils.NewController(t)
|
|
defer ctrl.Finish()
|
|
mockGitea = mock.NewMockGitea(ctrl)
|
|
mockGitea.EXPECT().ResetTimelineCache(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
|
bot.gitea = mockGitea
|
|
|
|
common.IsDryRun = tc.dryRun
|
|
if tc.issue != nil {
|
|
if tc.issue.Repository == nil {
|
|
tc.issue.Repository = &models.RepositoryMeta{Owner: "org", Name: "repo"}
|
|
}
|
|
if tc.issue.User == nil && tc.name != "user nil panic" {
|
|
tc.issue.User = &models.User{UserName: "owner"}
|
|
}
|
|
}
|
|
tc.setupMock()
|
|
err := bot.ProcessIssue("org", "repo", tc.issue)
|
|
if (err != nil) != tc.wantErr {
|
|
t.Errorf("ProcessIssue() error = %v, wantErr %v", err, tc.wantErr)
|
|
}
|
|
})
|
|
}
|
|
common.IsDryRun = false
|
|
}
|
|
|
|
func TestGetMaintainers(t *testing.T) {
|
|
mockFetcher := &MockMaintainershipFetcher{}
|
|
bot := &ReparentBot{maintainershipFetcher: mockFetcher}
|
|
config := &common.AutogitConfig{}
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
got, err := bot.GetMaintainers(config)
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
if len(got) != 1 || got[0] != "m1" {
|
|
t.Errorf("expected [m1], got %v", got)
|
|
}
|
|
})
|
|
|
|
t.Run("error", func(t *testing.T) {
|
|
mockFetcher.err = errors.New("error")
|
|
_, err := bot.GetMaintainers(config)
|
|
if err == nil {
|
|
t.Error("expected error, got nil")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestAddCommentOnce(t *testing.T) {
|
|
ctrl := test_utils.NewController(t)
|
|
defer ctrl.Finish()
|
|
mockGitea := mock.NewMockGitea(ctrl)
|
|
bot := &ReparentBot{gitea: mockGitea, botUser: "bot"}
|
|
|
|
timeline := []*models.TimelineComment{
|
|
{Type: common.TimelineCommentType_Comment, User: &models.User{UserName: "bot"}, Body: "already there"},
|
|
}
|
|
|
|
t.Run("already exists", func(t *testing.T) {
|
|
bot.AddCommentOnce("org", "repo", 1, timeline, "already there")
|
|
// No expectation means it should NOT call AddComment
|
|
})
|
|
|
|
t.Run("new comment", func(t *testing.T) {
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), "new").Return(nil)
|
|
bot.AddCommentOnce("org", "repo", 1, timeline, "new")
|
|
})
|
|
}
|
|
|
|
func TestProcessIssue_ApprovalReuse(t *testing.T) {
|
|
// This test verifies that an approval for a previous version of the issue body (e.g. repo1)
|
|
// is IGNORED for a new version (e.g. repo2).
|
|
// We simulate an issue that was updated AFTER the approval comment.
|
|
|
|
ctrl := test_utils.NewController(t)
|
|
defer ctrl.Finish()
|
|
mockGitea := mock.NewMockGitea(ctrl)
|
|
|
|
mockFetcher := &MockMaintainershipFetcher{}
|
|
bot := &ReparentBot{
|
|
botUser: "bot",
|
|
maintainershipFetcher: mockFetcher,
|
|
configs: common.AutogitConfigs{
|
|
&common.AutogitConfig{Organization: "org", Branch: "master"},
|
|
},
|
|
gitea: mockGitea,
|
|
}
|
|
|
|
// Timestamps
|
|
approvalTime := time.Now().Add(-2 * time.Hour)
|
|
issueUpdateTime := time.Now().Add(-1 * time.Hour)
|
|
|
|
issue := &models.Issue{
|
|
Index: 100,
|
|
State: "open",
|
|
Title: "[ADD] My Repo",
|
|
Labels: []*models.Label{{Name: common.Label_NewRepository}},
|
|
Ref: "refs/heads/master",
|
|
Body: "https://src.opensuse.org/owner/repo2", // Changed to repo2
|
|
User: &models.User{UserName: "owner"},
|
|
Updated: strfmt.DateTime(issueUpdateTime),
|
|
Repository: &models.RepositoryMeta{Owner: "org", Name: "repo"},
|
|
}
|
|
|
|
// Setup expectations
|
|
mockGitea.EXPECT().ResetTimelineCache("org", "repo", int64(100)).AnyTimes()
|
|
|
|
// Timeline has an OLD approval
|
|
timeline := []*models.TimelineComment{
|
|
{
|
|
Type: common.TimelineCommentType_Comment,
|
|
User: &models.User{UserName: "m1"},
|
|
Body: "approved",
|
|
Created: strfmt.DateTime(approvalTime),
|
|
Updated: strfmt.DateTime(approvalTime),
|
|
},
|
|
}
|
|
mockGitea.EXPECT().GetTimeline("org", "repo", int64(100)).Return(timeline, nil)
|
|
|
|
// Maintainers
|
|
mockFetcher.data = &MockMaintainershipData{maintainers: []string{"m1"}}
|
|
mockFetcher.err = nil
|
|
|
|
// Repo info fetching
|
|
repo2 := &models.Repository{Name: "repo2", Owner: &models.User{UserName: "owner"}, DefaultBranch: "master"}
|
|
mockGitea.EXPECT().GetRepository("owner", "repo2").Return(repo2, nil)
|
|
|
|
// Check for existing repo in target org
|
|
mockGitea.EXPECT().GetRepository("org", "repo2").Return(nil, nil)
|
|
|
|
// CRITICAL: We expect ReparentRepository to NOT be called because the approval is stale.
|
|
mockGitea.EXPECT().ReparentRepository(gomock.Any(), gomock.Any(), gomock.Any()).Times(0)
|
|
|
|
// It should request review instead
|
|
mockGitea.EXPECT().UpdateIssue(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
|
mockGitea.EXPECT().AddComment(gomock.Any(), gomock.Any()).AnyTimes()
|
|
|
|
// Execute
|
|
common.IsDryRun = false
|
|
err := bot.ProcessIssue("org", "repo", issue)
|
|
if err != nil {
|
|
t.Errorf("ProcessIssue() unexpected error: %v", err)
|
|
}
|
|
}
|