mirror of https://gitlab.com/gitlab-org/cli.git
test(mr): add tests for remaining mr commands
This commit is contained in:
parent
d6c59371b2
commit
4cd66bba19
|
@ -0,0 +1,168 @@
|
|||
package checkout
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"gitlab.com/gitlab-org/cli/pkg/git"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, branch string, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
pu, _ := url.Parse("https://gitlab.com/OWNER/REPO.git")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
factory.Remotes = func() (glrepo.Remotes, error) {
|
||||
return glrepo.Remotes{
|
||||
{
|
||||
Remote: &git.Remote{
|
||||
Name: "upstream",
|
||||
Resolved: "base",
|
||||
PushURL: pu,
|
||||
},
|
||||
Repo: glrepo.New("OWNER", "REPO"),
|
||||
},
|
||||
{
|
||||
Remote: &git.Remote{
|
||||
Name: "origin",
|
||||
Resolved: "base",
|
||||
PushURL: pu,
|
||||
},
|
||||
Repo: glrepo.New("monalisa", "REPO"),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
factory.Branch = func() (string, error) {
|
||||
return branch, nil
|
||||
}
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdCheckout(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestMrCheckout(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
commandArgs string
|
||||
branch string
|
||||
httpMocks []httpMock
|
||||
|
||||
shelloutStubs []string
|
||||
|
||||
expectedShellouts []string
|
||||
}{
|
||||
{
|
||||
name: "when a valid MR is checked out using MR id",
|
||||
commandArgs: "123",
|
||||
branch: "main",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened",
|
||||
"source_branch":"feat-new-mr"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
shelloutStubs: []string{
|
||||
"HEAD branch: master\n",
|
||||
heredoc.Doc(`
|
||||
deadbeef HEAD
|
||||
deadb00f refs/remotes/upstream/feat-new-mr
|
||||
deadbeef refs/remotes/origin/feat-new-mr
|
||||
`),
|
||||
},
|
||||
|
||||
expectedShellouts: []string{"git fetch upstream refs/merge-requests/123/head:feat-new-mr", "git checkout feat-new-mr"},
|
||||
},
|
||||
{
|
||||
name: "when a valid MR is checked out using MR id and specifying branch",
|
||||
commandArgs: "123 --branch foo",
|
||||
branch: "main",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened",
|
||||
"source_branch":"feat-new-mr"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
shelloutStubs: []string{
|
||||
"HEAD branch: master\n",
|
||||
heredoc.Doc(`
|
||||
deadbeef HEAD
|
||||
deadb00f refs/remotes/upstream/feat-new-mr
|
||||
deadbeef refs/remotes/origin/feat-new-mr
|
||||
`),
|
||||
},
|
||||
|
||||
expectedShellouts: []string{"git fetch upstream refs/merge-requests/123/head:foo", "git checkout foo"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := httpmock.New()
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
cs, csTeardown := test.InitCmdStubber()
|
||||
defer csTeardown()
|
||||
for _, stub := range tc.shelloutStubs {
|
||||
cs.Stub(stub)
|
||||
}
|
||||
|
||||
output, err := runCommand(fakeHTTP, tc.branch, false, tc.commandArgs)
|
||||
|
||||
if assert.NoErrorf(t, err, "error running command `mr checkout %s`: %v", tc.commandArgs, err) {
|
||||
assert.Empty(t, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
||||
assert.Equal(t, len(tc.expectedShellouts), cs.Count)
|
||||
for idx, expectedShellout := range tc.expectedShellouts {
|
||||
assert.Equal(t, expectedShellout, strings.Join(cs.Calls[idx].Args, " "))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -70,23 +70,23 @@ func TestNewCmdCreate_tty(t *testing.T) {
|
|||
fakeHTTP := httpmock.New()
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
fakeHTTP.RegisterResponder("POST", "/projects/OWNER/REPO/merge_requests",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, "/projects/OWNER/REPO/merge_requests",
|
||||
httpmock.NewStringResponse(http.StatusCreated, `
|
||||
{
|
||||
"id": 1,
|
||||
"iid": 12,
|
||||
"project_id": 3,
|
||||
"title": "myMRtitle",
|
||||
"description": "myMRbody",
|
||||
"state": "open",
|
||||
"state": "opened",
|
||||
"target_branch": "master",
|
||||
"source_branch": "feat-new-mr",
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/merge_requests/12"
|
||||
}
|
||||
`),
|
||||
)
|
||||
fakeHTTP.RegisterResponder("GET", "/projects/OWNER/REPO",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO",
|
||||
httpmock.NewStringResponse(http.StatusOK, `
|
||||
{
|
||||
"id": 1,
|
||||
"description": null,
|
||||
|
@ -99,8 +99,8 @@ func TestNewCmdCreate_tty(t *testing.T) {
|
|||
}
|
||||
`),
|
||||
)
|
||||
fakeHTTP.RegisterResponder("GET", "/users",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/users",
|
||||
httpmock.NewStringResponse(http.StatusOK, `
|
||||
[{
|
||||
"username": "testuser"
|
||||
}]
|
||||
|
@ -147,7 +147,7 @@ func TestNewCmdCreate_tty(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
assert.Contains(t, cmdtest.FirstLine([]byte(output.String())), `!12 myMRtitle (feat-new-mr)`)
|
||||
assert.Contains(t, cmdtest.FirstLine([]byte(output.String())), "!12 myMRtitle (feat-new-mr)")
|
||||
assert.Contains(t, output.Stderr(), "\nCreating merge request for feat-new-mr into master in OWNER/REPO\n\n")
|
||||
assert.Contains(t, output.String(), "https://gitlab.com/OWNER/REPO/-/merge_requests/12")
|
||||
}
|
||||
|
@ -156,19 +156,19 @@ func TestNewCmdCreate_RelatedIssue(t *testing.T) {
|
|||
fakeHTTP := httpmock.New()
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
fakeHTTP.RegisterResponder("POST", "/projects/OWNER/REPO/merge_requests",
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, "/projects/OWNER/REPO/merge_requests",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
rb, _ := io.ReadAll(req.Body)
|
||||
assert.Contains(t, string(rb), "\"title\":\"Draft: Resolve \\\"this is a issue title\\\"")
|
||||
assert.Contains(t, string(rb), "\"description\":\"\\n\\nCloses #1\"")
|
||||
resp, _ := httpmock.NewStringResponse(200, `
|
||||
resp, _ := httpmock.NewStringResponse(http.StatusCreated, `
|
||||
{
|
||||
"id": 1,
|
||||
"iid": 12,
|
||||
"project_id": 3,
|
||||
"title": "Draft: Resolve \"this is a issue title\"",
|
||||
"description": "\n\nCloses #1",
|
||||
"state": "open",
|
||||
"state": "opened",
|
||||
"target_branch": "master",
|
||||
"source_branch": "feat-new-mr",
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/merge_requests/12"
|
||||
|
@ -177,8 +177,8 @@ func TestNewCmdCreate_RelatedIssue(t *testing.T) {
|
|||
return resp, nil
|
||||
},
|
||||
)
|
||||
fakeHTTP.RegisterResponder("GET", "/projects/OWNER/REPO",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO",
|
||||
httpmock.NewStringResponse(http.StatusOK, `
|
||||
{
|
||||
"id": 1,
|
||||
"description": null,
|
||||
|
@ -191,8 +191,8 @@ func TestNewCmdCreate_RelatedIssue(t *testing.T) {
|
|||
}
|
||||
`),
|
||||
)
|
||||
fakeHTTP.RegisterResponder("GET", "/projects/OWNER/REPO/issues/1",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/issues/1",
|
||||
httpmock.NewStringResponse(http.StatusOK, `
|
||||
{
|
||||
"id":1,
|
||||
"iid":1,
|
||||
|
@ -239,19 +239,19 @@ func TestNewCmdCreate_RelatedIssueWithTitleAndDescription(t *testing.T) {
|
|||
fakeHTTP := httpmock.New()
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
fakeHTTP.RegisterResponder("POST", "/projects/OWNER/REPO/merge_requests",
|
||||
fakeHTTP.RegisterResponder(http.MethodPost, "/projects/OWNER/REPO/merge_requests",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
rb, _ := io.ReadAll(req.Body)
|
||||
assert.Contains(t, string(rb), "\"title\":\"Draft: my custom MR title\"")
|
||||
assert.Contains(t, string(rb), "\"description\":\"my custom MR description\\n\\nCloses #1\"")
|
||||
resp, _ := httpmock.NewStringResponse(200, `
|
||||
resp, _ := httpmock.NewStringResponse(http.StatusCreated, `
|
||||
{
|
||||
"id": 1,
|
||||
"iid": 12,
|
||||
"project_id": 3,
|
||||
"title": "my custom MR title",
|
||||
"description": "myMRbody",
|
||||
"state": "open",
|
||||
"state": "opened",
|
||||
"target_branch": "master",
|
||||
"source_branch": "feat-new-mr",
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/merge_requests/12"
|
||||
|
@ -260,8 +260,8 @@ func TestNewCmdCreate_RelatedIssueWithTitleAndDescription(t *testing.T) {
|
|||
return resp, nil
|
||||
},
|
||||
)
|
||||
fakeHTTP.RegisterResponder("GET", "/projects/OWNER/REPO",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO",
|
||||
httpmock.NewStringResponse(http.StatusOK, `
|
||||
{
|
||||
"id": 1,
|
||||
"description": null,
|
||||
|
@ -274,8 +274,8 @@ func TestNewCmdCreate_RelatedIssueWithTitleAndDescription(t *testing.T) {
|
|||
}
|
||||
`),
|
||||
)
|
||||
fakeHTTP.RegisterResponder("GET", "/projects/OWNER/REPO/issues/1",
|
||||
httpmock.NewStringResponse(200, `
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/issues/1",
|
||||
httpmock.NewStringResponse(http.StatusOK, `
|
||||
{
|
||||
"id":1,
|
||||
"iid":1,
|
||||
|
@ -314,7 +314,7 @@ func TestNewCmdCreate_RelatedIssueWithTitleAndDescription(t *testing.T) {
|
|||
t.Error(err)
|
||||
return
|
||||
}
|
||||
assert.Contains(t, cmdtest.FirstLine([]byte(output.String())), `!12 my custom MR title (feat-new-mr)`)
|
||||
assert.Contains(t, cmdtest.FirstLine([]byte(output.String())), "!12 my custom MR title (feat-new-mr)")
|
||||
assert.Contains(t, output.Stderr(), "\nCreating draft merge request for feat-new-mr into master in OWNER/REPO\n\n")
|
||||
assert.Contains(t, output.String(), "https://gitlab.com/OWNER/REPO/-/merge_requests/12")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package rebase
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
factory.Branch = func() (string, error) {
|
||||
return "current-branch", nil
|
||||
}
|
||||
|
||||
cmd := NewCmdRebase(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestMrRebase(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
httpMocks []httpMock
|
||||
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "when an MR is rebased using an MR id",
|
||||
cli: "123",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodPut,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/rebase",
|
||||
http.StatusAccepted,
|
||||
`{ "rebase_in_progress": true }`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123?include_rebase_in_progress=true",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"rebase_in_progress": false,
|
||||
"merge_error": null
|
||||
}`,
|
||||
},
|
||||
},
|
||||
|
||||
expectedOut: "✓ Rebase successful\n",
|
||||
},
|
||||
{
|
||||
name: "when an MR is rebased using current branch",
|
||||
cli: "",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests?per_page=30&source_branch=current-branch&state=opened",
|
||||
http.StatusOK,
|
||||
`[{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}]`,
|
||||
},
|
||||
{
|
||||
http.MethodPut,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/rebase",
|
||||
http.StatusAccepted,
|
||||
`{ "rebase_in_progress": true }`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123?include_rebase_in_progress=true",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"rebase_in_progress": false,
|
||||
"merge_error": null
|
||||
}`,
|
||||
},
|
||||
},
|
||||
|
||||
expectedOut: "✓ Rebase successful\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
output, err := runCommand(fakeHTTP, false, tc.cli)
|
||||
|
||||
if assert.NoErrorf(t, err, "error running command `mr rebase %s`: %v", tc.cli, err) {
|
||||
out := output.String()
|
||||
|
||||
assert.Equal(t, tc.expectedOut, out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package reopen
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdReopen(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestMrReopen(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
httpMocks []httpMock
|
||||
|
||||
expectedPUTBody string
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "when an MR is reopened using an MR id",
|
||||
cli: "123",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "closed"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
|
||||
expectedPUTBody: `"state_event":"reopen"`,
|
||||
expectedOut: "- Reopening Merge request !123...\n✓ Reopened Merge request !123\n\n",
|
||||
},
|
||||
{
|
||||
name: "when an MR is reopened using a branch name",
|
||||
cli: "foo",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests?per_page=30&source_branch=foo&state=closed",
|
||||
http.StatusOK,
|
||||
`[{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}]`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "closed"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
|
||||
expectedPUTBody: `"state_event":"reopen"`,
|
||||
expectedOut: "- Reopening Merge request !123...\n✓ Reopened Merge request !123\n\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
fakeHTTP.RegisterResponder(http.MethodPut, "/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
rb, _ := io.ReadAll(req.Body)
|
||||
|
||||
// ensure CLI updates MR to reopen
|
||||
assert.Contains(t, string(rb), tc.expectedPUTBody)
|
||||
resp, _ := httpmock.NewStringResponse(http.StatusOK, `{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"}`)(req)
|
||||
return resp, nil
|
||||
},
|
||||
)
|
||||
|
||||
output, err := runCommand(fakeHTTP, false, tc.cli)
|
||||
|
||||
if assert.NoErrorf(t, err, "error running command `mr reopen %s`: %v", tc.cli, err) {
|
||||
out := output.String()
|
||||
|
||||
assert.Equal(t, tc.expectedOut, out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ func NewCmdRevoke(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(f.IO.StdOut, "- Revoking approval for Merge Request #%d...\n", mr.IID)
|
||||
fmt.Fprintf(f.IO.StdOut, "- Revoking approval for Merge Request !%d...\n", mr.IID)
|
||||
|
||||
err = api.UnapproveMR(apiClient, repo.FullName(), mr.IID)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
package revoke
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
factory.Branch = func() (string, error) {
|
||||
return "current-branch", nil
|
||||
}
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdRevoke(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestMrRevoke(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
httpMocks []httpMock
|
||||
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "when an MR is unapproved using an MR id",
|
||||
cli: "123",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodPost,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/unapprove",
|
||||
http.StatusCreated,
|
||||
"{}",
|
||||
},
|
||||
},
|
||||
|
||||
expectedOut: heredoc.Doc(`
|
||||
- Revoking approval for Merge Request !123...
|
||||
✓ Merge Request approval revoked
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "when an MR is unapproved using the current branch",
|
||||
cli: "",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests?per_page=30&source_branch=current-branch&state=opened",
|
||||
http.StatusOK,
|
||||
`[{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}]`,
|
||||
},
|
||||
{
|
||||
http.MethodPost,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/unapprove",
|
||||
http.StatusCreated,
|
||||
"{}",
|
||||
},
|
||||
},
|
||||
|
||||
expectedOut: heredoc.Doc(`
|
||||
- Revoking approval for Merge Request !123...
|
||||
✓ Merge Request approval revoked
|
||||
`),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
output, err := runCommand(fakeHTTP, false, tc.cli)
|
||||
|
||||
if assert.NoErrorf(t, err, "error running command `mr revoke %s`: %v", tc.cli, err) {
|
||||
out := output.String()
|
||||
|
||||
assert.Equal(t, tc.expectedOut, out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package todo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
||||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdTodo(factory)
|
||||
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestMrTodo(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
httpMocks []httpMock
|
||||
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "when an MR is added as a todo using an MR id",
|
||||
cli: "123",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodPost,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/todo",
|
||||
http.StatusCreated,
|
||||
"{}",
|
||||
},
|
||||
},
|
||||
expectedOut: "✓ Done!!\n",
|
||||
},
|
||||
{
|
||||
name: "when an MR is added as a todo using a branch name",
|
||||
cli: "foo",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests?per_page=30&source_branch=foo",
|
||||
http.StatusOK,
|
||||
`[{
|
||||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"state": "opened"
|
||||
}]`,
|
||||
},
|
||||
{
|
||||
http.MethodPost,
|
||||
"/api/v4/projects/OWNER/REPO/merge_requests/123/todo",
|
||||
http.StatusCreated,
|
||||
"{}",
|
||||
},
|
||||
},
|
||||
expectedOut: "✓ Done!!\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeHTTP := &httpmock.Mocker{
|
||||
MatchURL: httpmock.PathAndQuerystring,
|
||||
}
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
}
|
||||
|
||||
output, err := runCommand(fakeHTTP, false, tc.cli)
|
||||
|
||||
if assert.NoErrorf(t, err, "error running command `mr todo %s`: %v", tc.cli, err) {
|
||||
out := output.String()
|
||||
|
||||
assert.Equal(t, tc.expectedOut, out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue