mirror of https://gitlab.com/gitlab-org/cli.git
851 lines
20 KiB
Go
851 lines
20 KiB
Go
package mrutils
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/xanzy/go-gitlab"
|
|
"gitlab.com/gitlab-org/cli/api"
|
|
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
|
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
|
"gitlab.com/gitlab-org/cli/pkg/prompt"
|
|
)
|
|
|
|
func Test_DisplayMR(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
mr *gitlab.MergeRequest
|
|
output string
|
|
outputToTTY bool
|
|
}{
|
|
{
|
|
name: "opened",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
State: "opened",
|
|
Title: "This is open",
|
|
SourceBranch: "main",
|
|
WebURL: "https://gitlab.com/gitlab-org/cli/-/merge_requests/1",
|
|
},
|
|
output: "!1 This is open (main)\n https://gitlab.com/gitlab-org/cli/-/merge_requests/1\n",
|
|
outputToTTY: true,
|
|
},
|
|
{
|
|
name: "merged",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 2,
|
|
State: "merged",
|
|
Title: "This is merged",
|
|
SourceBranch: "main",
|
|
WebURL: "https://gitlab.com/gitlab-org/cli/-/merge_requests/2",
|
|
},
|
|
output: "!2 This is merged (main)\n https://gitlab.com/gitlab-org/cli/-/merge_requests/2\n",
|
|
outputToTTY: true,
|
|
},
|
|
{
|
|
name: "closed",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 3,
|
|
State: "closed",
|
|
Title: "This is closed",
|
|
SourceBranch: "main",
|
|
WebURL: "https://gitlab.com/gitlab-org/cli/-/merge_requests/3",
|
|
},
|
|
output: "!3 This is closed (main)\n https://gitlab.com/gitlab-org/cli/-/merge_requests/3\n",
|
|
outputToTTY: true,
|
|
},
|
|
{
|
|
name: "non-tty terse output",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 4,
|
|
State: "open",
|
|
Title: "This shouldn't be visible",
|
|
SourceBranch: "main",
|
|
WebURL: "https://gitlab.com/gitlab-org/cli/-/merge_requests/4",
|
|
},
|
|
output: "https://gitlab.com/gitlab-org/cli/-/merge_requests/4",
|
|
outputToTTY: false,
|
|
},
|
|
}
|
|
streams, _, _, _ := iostreams.Test()
|
|
for _, tC := range testCases {
|
|
t.Run(tC.name, func(t *testing.T) {
|
|
got := DisplayMR(streams.Color(), tC.mr, tC.outputToTTY)
|
|
assert.Equal(t, tC.output, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_MRCheckErrors(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
mr *gitlab.MergeRequest
|
|
errOpts MRCheckErrOptions
|
|
output string
|
|
}{
|
|
{
|
|
name: "draft",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
WorkInProgress: true,
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
WorkInProgress: true,
|
|
},
|
|
output: "this merge request is still a work in progress. Run `glab mr update 1 --ready` to mark it as ready for review",
|
|
},
|
|
{
|
|
name: "pipeline",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
MergeWhenPipelineSucceeds: true,
|
|
Pipeline: &gitlab.PipelineInfo{
|
|
Status: "failure",
|
|
},
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
PipelineStatus: true,
|
|
},
|
|
output: "pipeline for this merge request has failed. Pipeline is required to succeed before merging",
|
|
},
|
|
{
|
|
name: "merged",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
State: "merged",
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
Merged: true,
|
|
},
|
|
output: "this merge request has already been merged",
|
|
},
|
|
{
|
|
name: "closed",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
State: "closed",
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
Closed: true,
|
|
},
|
|
output: "this merge request has been closed",
|
|
},
|
|
{
|
|
name: "opened",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
State: "opened",
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
Opened: true,
|
|
},
|
|
output: "this merge request is already open",
|
|
},
|
|
{
|
|
name: "subscribed",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
Subscribed: true,
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
Subscribed: true,
|
|
},
|
|
output: "you are already subscribed to this merge request",
|
|
},
|
|
{
|
|
name: "unsubscribed",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
Subscribed: false,
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
Unsubscribed: true,
|
|
},
|
|
output: "you are not subscribed to this merge request",
|
|
},
|
|
{
|
|
name: "merge-privilege",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
User: struct {
|
|
CanMerge bool "json:\"can_merge\""
|
|
}{CanMerge: false},
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
MergePrivilege: true,
|
|
},
|
|
output: "you do not have enough priviledges to merge this merge request",
|
|
},
|
|
{
|
|
name: "conflicts",
|
|
mr: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
HasConflicts: true,
|
|
},
|
|
errOpts: MRCheckErrOptions{
|
|
Conflict: true,
|
|
},
|
|
output: "there are merge conflicts. Resolve conflicts and try again or merge locally",
|
|
},
|
|
}
|
|
for _, tC := range testCases {
|
|
t.Run(tC.name, func(t *testing.T) {
|
|
err := MRCheckErrors(tC.mr, tC.errOpts)
|
|
assert.EqualError(t, err, tC.output)
|
|
})
|
|
}
|
|
|
|
t.Run("nil", func(t *testing.T) {
|
|
err := MRCheckErrors(&gitlab.MergeRequest{}, MRCheckErrOptions{})
|
|
assert.Nil(t, err)
|
|
})
|
|
}
|
|
|
|
func Test_getMRForBranchFails(t *testing.T) {
|
|
baseRepo := glrepo.NewWithHost("foo", "bar", "gitlab.com")
|
|
|
|
t.Run("API-call-failed", func(t *testing.T) {
|
|
api.ListMRs = func(_ *gitlab.Client, _ interface{}, _ *gitlab.ListProjectMergeRequestsOptions) ([]*gitlab.MergeRequest, error) {
|
|
return nil, errors.New("API call failed")
|
|
}
|
|
|
|
got, err := getMRForBranch(&gitlab.Client{}, baseRepo, "foo", "opened")
|
|
assert.Nil(t, got)
|
|
assert.EqualError(t, err, `failed to get open merge request for "foo": API call failed`)
|
|
})
|
|
|
|
t.Run("no-return", func(t *testing.T) {
|
|
api.ListMRs = func(_ *gitlab.Client, _ interface{}, _ *gitlab.ListProjectMergeRequestsOptions) ([]*gitlab.MergeRequest, error) {
|
|
return []*gitlab.MergeRequest{}, nil
|
|
}
|
|
|
|
got, err := getMRForBranch(&gitlab.Client{}, baseRepo, "foo", "opened")
|
|
assert.Nil(t, got)
|
|
assert.EqualError(t, err, `no open merge request available for "foo"`)
|
|
})
|
|
|
|
t.Run("owner-no-match", func(t *testing.T) {
|
|
api.ListMRs = func(_ *gitlab.Client, _ interface{}, _ *gitlab.ListProjectMergeRequestsOptions) ([]*gitlab.MergeRequest, error) {
|
|
return []*gitlab.MergeRequest{
|
|
{
|
|
IID: 1,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "profclems",
|
|
},
|
|
},
|
|
{
|
|
IID: 2,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "maxice8",
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
got, err := getMRForBranch(&gitlab.Client{}, baseRepo, "zemzale:foo", "opened")
|
|
assert.Nil(t, got)
|
|
assert.EqualError(t, err, `no open merge request available for "foo" owned by @zemzale`)
|
|
})
|
|
}
|
|
|
|
func Test_getMRForBranch(t *testing.T) {
|
|
baseRepo := glrepo.NewWithHost("foo", "bar", "gitlab.com")
|
|
|
|
testCases := []struct {
|
|
name string
|
|
input string
|
|
mrs []*gitlab.MergeRequest
|
|
expect *gitlab.MergeRequest
|
|
}{
|
|
{
|
|
name: "one-match",
|
|
mrs: []*gitlab.MergeRequest{
|
|
{
|
|
IID: 1,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "profclems",
|
|
},
|
|
},
|
|
},
|
|
expect: &gitlab.MergeRequest{
|
|
IID: 1,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "profclems",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "owner-match",
|
|
input: "maxice8:foo",
|
|
mrs: []*gitlab.MergeRequest{
|
|
{
|
|
IID: 1,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "profclems",
|
|
},
|
|
},
|
|
{
|
|
IID: 2,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "maxice8",
|
|
},
|
|
},
|
|
},
|
|
expect: &gitlab.MergeRequest{
|
|
IID: 2,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "maxice8",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tC := range testCases {
|
|
t.Run(tC.name, func(t *testing.T) {
|
|
api.ListMRs = func(_ *gitlab.Client, _ interface{}, _ *gitlab.ListProjectMergeRequestsOptions) ([]*gitlab.MergeRequest, error) {
|
|
return tC.mrs, nil
|
|
}
|
|
|
|
got, err := getMRForBranch(&gitlab.Client{}, baseRepo, tC.input, "opened")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, tC.expect.IID, got.IID)
|
|
assert.Equal(t, tC.expect.Author.Username, got.Author.Username)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getMRForBranchPrompt(t *testing.T) {
|
|
baseRepo := glrepo.NewWithHost("foo", "bar", "gitlab.com")
|
|
|
|
api.ListMRs = func(_ *gitlab.Client, _ interface{}, _ *gitlab.ListProjectMergeRequestsOptions) ([]*gitlab.MergeRequest, error) {
|
|
return []*gitlab.MergeRequest{
|
|
{
|
|
IID: 1,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "profclems",
|
|
},
|
|
},
|
|
{
|
|
IID: 2,
|
|
Author: &gitlab.BasicUser{
|
|
Username: "maxice8",
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
as, restoreAsk := prompt.InitAskStubber()
|
|
defer restoreAsk()
|
|
|
|
as.Stub([]*prompt.QuestionStub{
|
|
{
|
|
Name: "mr",
|
|
Value: "!1 (foo) by @profclems",
|
|
},
|
|
})
|
|
|
|
got, err := getMRForBranch(&gitlab.Client{}, baseRepo, "foo", "opened")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 1, got.IID)
|
|
assert.Equal(t, "profclems", got.Author.Username)
|
|
})
|
|
|
|
t.Run("error", func(t *testing.T) {
|
|
as, restoreAsk := prompt.InitAskStubber()
|
|
defer restoreAsk()
|
|
|
|
as.Stub([]*prompt.QuestionStub{
|
|
{
|
|
Name: "mr",
|
|
Value: errors.New("prompt failed"),
|
|
},
|
|
})
|
|
|
|
got, err := getMRForBranch(&gitlab.Client{}, baseRepo, "foo", "opened")
|
|
assert.Nil(t, got)
|
|
assert.EqualError(t, err, "a merge request must be picked: prompt failed")
|
|
})
|
|
}
|
|
|
|
func Test_MRFromArgsWithOpts(t *testing.T) {
|
|
// Mock cmdutils.Factory object that can be modified as required to perform certain functions
|
|
f := &cmdutils.Factory{
|
|
HttpClient: func() (*gitlab.Client, error) { return &gitlab.Client{}, nil },
|
|
BaseRepo: func() (glrepo.Interface, error) { return glrepo.New("foo", "bar"), nil },
|
|
Branch: func() (string, error) { return "main", nil },
|
|
}
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
t.Run("via-ID", func(t *testing.T) {
|
|
f := *f
|
|
|
|
api.GetMR = func(client *gitlab.Client, projectID interface{}, mrID int, opts *gitlab.GetMergeRequestsOptions) (*gitlab.MergeRequest, error) {
|
|
return &gitlab.MergeRequest{
|
|
IID: 2,
|
|
Title: "test mr",
|
|
SourceBranch: "main",
|
|
}, nil
|
|
}
|
|
|
|
expectedRepo, err := f.BaseRepo()
|
|
if err != nil {
|
|
t.Skipf("failed to get base repo: %s", err)
|
|
}
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{"2"}, "")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedRepo.FullName(), gotRepo.FullName())
|
|
|
|
assert.Equal(t, 2, gotMR.IID)
|
|
assert.Equal(t, "test mr", gotMR.Title)
|
|
assert.Equal(t, "main", gotMR.SourceBranch)
|
|
})
|
|
t.Run("via-name", func(t *testing.T) {
|
|
f := *f
|
|
|
|
getMRForBranch = func(apiClient *gitlab.Client, baseRepo glrepo.Interface, arg string, state string) (*gitlab.MergeRequest, error) {
|
|
return &gitlab.MergeRequest{
|
|
IID: 2,
|
|
Title: "test mr",
|
|
SourceBranch: "main",
|
|
}, nil
|
|
}
|
|
|
|
api.GetMR = func(client *gitlab.Client, projectID interface{}, mrID int, opts *gitlab.GetMergeRequestsOptions) (*gitlab.MergeRequest, error) {
|
|
return &gitlab.MergeRequest{
|
|
IID: 2,
|
|
Title: "test mr",
|
|
SourceBranch: "main",
|
|
}, nil
|
|
}
|
|
|
|
expectedRepo, err := f.BaseRepo()
|
|
if err != nil {
|
|
t.Skipf("failed to get base repo: %s", err)
|
|
}
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{"foo"}, "")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedRepo.FullName(), gotRepo.FullName())
|
|
|
|
assert.Equal(t, 2, gotMR.IID)
|
|
assert.Equal(t, "test mr", gotMR.Title)
|
|
assert.Equal(t, "main", gotMR.SourceBranch)
|
|
})
|
|
})
|
|
|
|
t.Run("fail", func(t *testing.T) {
|
|
t.Run("HttpClient", func(t *testing.T) {
|
|
f := *f
|
|
|
|
f.HttpClient = func() (*gitlab.Client, error) { return nil, errors.New("failed to create HttpClient") }
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{}, "")
|
|
assert.Nil(t, gotMR)
|
|
assert.Nil(t, gotRepo)
|
|
assert.EqualError(t, err, "failed to create HttpClient")
|
|
})
|
|
t.Run("BaseRepo", func(t *testing.T) {
|
|
f := *f
|
|
|
|
f.BaseRepo = func() (glrepo.Interface, error) { return nil, errors.New("failed to create glrepo.Interface") }
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{}, "")
|
|
assert.Nil(t, gotMR)
|
|
assert.Nil(t, gotRepo)
|
|
assert.EqualError(t, err, "failed to create glrepo.Interface")
|
|
})
|
|
t.Run("Branch", func(t *testing.T) {
|
|
f := *f
|
|
|
|
f.Branch = func() (string, error) { return "", errors.New("failed to get Branch") }
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{}, "")
|
|
assert.Nil(t, gotMR)
|
|
assert.Nil(t, gotRepo)
|
|
assert.EqualError(t, err, "failed to get Branch")
|
|
})
|
|
t.Run("Invalid-MR-ID", func(t *testing.T) {
|
|
f := *f
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{"0"}, "")
|
|
assert.Nil(t, gotMR)
|
|
assert.Nil(t, gotRepo)
|
|
assert.EqualError(t, err, "invalid merge request ID provided")
|
|
})
|
|
t.Run("invalid-name", func(t *testing.T) {
|
|
f := *f
|
|
|
|
getMRForBranch = func(apiClient *gitlab.Client, baseRepo glrepo.Interface, arg string, state string) (*gitlab.MergeRequest, error) {
|
|
return nil, fmt.Errorf("no merge requests from branch %q", arg)
|
|
}
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{"foo"}, "")
|
|
assert.Nil(t, gotMR)
|
|
assert.Nil(t, gotRepo)
|
|
assert.EqualError(t, err, `no merge requests from branch "foo"`)
|
|
})
|
|
t.Run("api.GetMR", func(t *testing.T) {
|
|
f := *f
|
|
|
|
api.GetMR = func(client *gitlab.Client, projectID interface{}, mrID int, opts *gitlab.GetMergeRequestsOptions) (*gitlab.MergeRequest, error) {
|
|
return nil, errors.New("API call failed")
|
|
}
|
|
|
|
gotMR, gotRepo, err := MRFromArgs(&f, []string{"2"}, "")
|
|
assert.Nil(t, gotMR)
|
|
assert.Nil(t, gotRepo)
|
|
assert.EqualError(t, err, "failed to get merge request 2: API call failed")
|
|
})
|
|
})
|
|
}
|
|
|
|
func Test_DisplayAllMRs(t *testing.T) {
|
|
streams, _, _, _ := iostreams.Test()
|
|
mrs := []*gitlab.MergeRequest{
|
|
{
|
|
IID: 1,
|
|
State: "opened",
|
|
Title: "add tests",
|
|
TargetBranch: "main",
|
|
SourceBranch: "new-tests",
|
|
References: &gitlab.IssueReferences{
|
|
Full: "OWNER/REPO/merge_requests/1",
|
|
Relative: "#1",
|
|
Short: "#1",
|
|
},
|
|
},
|
|
{
|
|
IID: 2,
|
|
State: "merged",
|
|
Title: "fix bug",
|
|
TargetBranch: "main",
|
|
SourceBranch: "new-feature",
|
|
References: &gitlab.IssueReferences{
|
|
Full: "OWNER/REPO/merge_requests/2",
|
|
Relative: "#2",
|
|
Short: "#2",
|
|
},
|
|
},
|
|
{
|
|
IID: 1,
|
|
State: "closed",
|
|
Title: "add new feature",
|
|
TargetBranch: "main",
|
|
SourceBranch: "new-tests",
|
|
References: &gitlab.IssueReferences{
|
|
Full: "OWNER/REPO/merge_requests/3",
|
|
Relative: "#3",
|
|
Short: "#3",
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := `!1 OWNER/REPO/merge_requests/1 add tests (main) ← (new-tests)
|
|
!2 OWNER/REPO/merge_requests/2 fix bug (main) ← (new-feature)
|
|
!1 OWNER/REPO/merge_requests/3 add new feature (main) ← (new-tests)
|
|
`
|
|
|
|
got := DisplayAllMRs(streams, mrs)
|
|
assert.Equal(t, expected, got)
|
|
}
|
|
|
|
func Test_PrintMRApprovalState(t *testing.T) {
|
|
scenarios := []struct {
|
|
name string
|
|
approvalState *gitlab.MergeRequestApprovalState
|
|
expected string
|
|
}{
|
|
{
|
|
name: "approved, min approvers met",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "user1",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "user2",
|
|
Name: "User Two",
|
|
},
|
|
},
|
|
Approved: true,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" sufficient approvals (2/2 required):
|
|
User One user1 👍
|
|
User Two user2 👍
|
|
|
|
`,
|
|
},
|
|
{
|
|
name: "not-approved, min approvers not met",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "user1",
|
|
Name: "User One",
|
|
},
|
|
},
|
|
Approved: false,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" insufficient approvals (1/2 required):
|
|
User One user1 👍
|
|
|
|
`,
|
|
},
|
|
{
|
|
name: "approved, eligible approvers",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
EligibleApprovers: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "user1",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "user2",
|
|
Name: "User Two",
|
|
},
|
|
},
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "user1",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "user2",
|
|
Name: "User Two",
|
|
},
|
|
},
|
|
Approved: true,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" sufficient approvals (2/2 required):
|
|
User One user1 👍
|
|
User Two user2 👍
|
|
|
|
`,
|
|
},
|
|
{
|
|
name: "not approved, missing eligible approver",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
EligibleApprovers: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "user1",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "user2",
|
|
Name: "User Two",
|
|
},
|
|
},
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "user1",
|
|
Name: "User One",
|
|
},
|
|
},
|
|
Approved: false,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" insufficient approvals (1/2 required):
|
|
User One user1 👍
|
|
User Two user2 -
|
|
|
|
`,
|
|
},
|
|
{
|
|
name: "deterministic output without eligible approvers",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "aaa",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "zzz",
|
|
Name: "User Two",
|
|
},
|
|
{
|
|
ID: 3,
|
|
Username: "000",
|
|
Name: "User Three",
|
|
},
|
|
{
|
|
ID: 4,
|
|
Username: "xyz",
|
|
Name: "User Four",
|
|
},
|
|
},
|
|
Approved: true,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" sufficient approvals (4/2 required):
|
|
User Three 000 👍
|
|
User One aaa 👍
|
|
User Four xyz 👍
|
|
User Two zzz 👍
|
|
|
|
`,
|
|
},
|
|
{
|
|
name: "deterministic output with all eligible approvers",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 4,
|
|
Username: "xyz",
|
|
Name: "User Four",
|
|
},
|
|
{
|
|
ID: 1,
|
|
Username: "aaa",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "zzz",
|
|
Name: "User Two",
|
|
},
|
|
{
|
|
ID: 3,
|
|
Username: "000",
|
|
Name: "User Three",
|
|
},
|
|
},
|
|
EligibleApprovers: []*gitlab.BasicUser{
|
|
{
|
|
ID: 4,
|
|
Username: "xyz",
|
|
Name: "User Four",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "zzz",
|
|
Name: "User Two",
|
|
},
|
|
},
|
|
Approved: true,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" sufficient approvals (4/2 required):
|
|
User Four xyz 👍
|
|
User Two zzz 👍
|
|
User Three 000 👍
|
|
User One aaa 👍
|
|
|
|
`,
|
|
},
|
|
{
|
|
name: "deterministic output with no eligible approvers",
|
|
approvalState: &gitlab.MergeRequestApprovalState{
|
|
Rules: []*gitlab.MergeRequestApprovalRule{
|
|
{
|
|
ID: 1,
|
|
Name: "rule 1",
|
|
ApprovalsRequired: 2,
|
|
ApprovedBy: []*gitlab.BasicUser{
|
|
{
|
|
ID: 1,
|
|
Username: "aaa",
|
|
Name: "User One",
|
|
},
|
|
{
|
|
ID: 3,
|
|
Username: "000",
|
|
Name: "User Three",
|
|
},
|
|
},
|
|
EligibleApprovers: []*gitlab.BasicUser{
|
|
{
|
|
ID: 4,
|
|
Username: "xyz",
|
|
Name: "User Four",
|
|
},
|
|
{
|
|
ID: 2,
|
|
Username: "zzz",
|
|
Name: "User Two",
|
|
},
|
|
},
|
|
Approved: true,
|
|
},
|
|
},
|
|
},
|
|
expected: `Rule "rule 1" sufficient approvals (2/2 required):
|
|
User Four xyz -
|
|
User Two zzz -
|
|
User Three 000 👍
|
|
User One aaa 👍
|
|
|
|
`,
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
t.Run(scenario.name, func(t *testing.T) {
|
|
streams, _, stdout, _ := iostreams.Test()
|
|
|
|
PrintMRApprovalState(streams, scenario.approvalState)
|
|
assert.Equal(t, scenario.expected, stdout.String())
|
|
})
|
|
}
|
|
}
|