mirror of https://gitlab.com/gitlab-org/cli.git
316 lines
7.6 KiB
Go
316 lines
7.6 KiB
Go
package create
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
|
|
|
"github.com/MakeNowJust/heredoc"
|
|
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
|
"gitlab.com/gitlab-org/cli/pkg/prompt"
|
|
|
|
"github.com/google/shlex"
|
|
"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/config"
|
|
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
|
"gitlab.com/gitlab-org/cli/pkg/git"
|
|
"gitlab.com/gitlab-org/cli/pkg/httpmock"
|
|
"gitlab.com/gitlab-org/cli/test"
|
|
)
|
|
|
|
func runCommand(rt http.RoundTripper, remotes glrepo.Remotes, runE func(opts *CreateOpts) error, branch string, isTTY bool, cli string) (*test.CmdOut, error) {
|
|
io, _, stdout, stderr := iostreams.Test()
|
|
io.IsaTTY = isTTY
|
|
io.IsInTTY = isTTY
|
|
io.IsErrTTY = isTTY
|
|
|
|
factory := &cmdutils.Factory{
|
|
IO: io,
|
|
HttpClient: func() (*gitlab.Client, error) {
|
|
a, err := api.TestClient(&http.Client{Transport: rt}, "", "", false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return a.Lab(), err
|
|
},
|
|
Config: func() (config.Config, error) {
|
|
return config.NewBlankConfig(), nil
|
|
},
|
|
Remotes: func() (glrepo.Remotes, error) {
|
|
if remotes != nil {
|
|
return remotes, nil
|
|
}
|
|
return glrepo.Remotes{
|
|
{
|
|
Remote: &git.Remote{
|
|
Name: "origin",
|
|
Resolved: "base",
|
|
},
|
|
Repo: glrepo.New("OWNER", "REPO"),
|
|
},
|
|
}, nil
|
|
},
|
|
Branch: func() (string, error) {
|
|
return branch, nil
|
|
},
|
|
BaseRepo: func() (glrepo.Interface, error) {
|
|
return glrepo.New("OWNER", "REPO"), nil
|
|
},
|
|
}
|
|
|
|
// TODO: shouldn't be there but the stub doesn't work without it
|
|
_, _ = factory.HttpClient()
|
|
|
|
cmd := NewCmdCreate(factory, runE)
|
|
cmd.PersistentFlags().StringP("repo", "R", "", "")
|
|
|
|
argv, err := shlex.Split(cli)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmd.SetArgs(argv)
|
|
|
|
cmd.SetIn(&bytes.Buffer{})
|
|
cmd.SetOut(ioutil.Discard)
|
|
cmd.SetErr(ioutil.Discard)
|
|
|
|
_, err = cmd.ExecuteC()
|
|
return &test.CmdOut{
|
|
OutBuf: stdout,
|
|
ErrBuf: stderr,
|
|
}, err
|
|
}
|
|
|
|
func TestNewCmdCreate_tty(t *testing.T) {
|
|
fakeHTTP := httpmock.New()
|
|
defer fakeHTTP.Verify(t)
|
|
|
|
fakeHTTP.RegisterResponder("POST", "/projects/OWNER/REPO/merge_requests",
|
|
httpmock.NewStringResponse(200, `
|
|
{
|
|
"id": 1,
|
|
"iid": 12,
|
|
"project_id": 3,
|
|
"title": "myMRtitle",
|
|
"description": "myMRbody",
|
|
"state": "open",
|
|
"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, `
|
|
{
|
|
"id": 1,
|
|
"description": null,
|
|
"default_branch": "master",
|
|
"web_url": "http://gitlab.com/OWNER/REPO",
|
|
"name": "OWNER",
|
|
"path": "REPO",
|
|
"merge_requests_enabled": true,
|
|
"path_with_namespace": "OWNER/REPO"
|
|
}
|
|
`),
|
|
)
|
|
fakeHTTP.RegisterResponder("GET", "/users",
|
|
httpmock.NewStringResponse(200, `
|
|
[{
|
|
"username": "testuser"
|
|
}]
|
|
`),
|
|
)
|
|
|
|
ask, teardown := prompt.InitAskStubber()
|
|
defer teardown()
|
|
|
|
ask.Stub([]*prompt.QuestionStub{
|
|
{
|
|
Name: "confirmation",
|
|
Value: 0,
|
|
},
|
|
})
|
|
|
|
cs, csTeardown := test.InitCmdStubber()
|
|
defer csTeardown()
|
|
cs.Stub("HEAD branch: master\n")
|
|
cs.Stub(heredoc.Doc(`
|
|
deadbeef HEAD
|
|
deadb00f refs/remotes/upstream/feat-new-mr
|
|
deadbeef refs/remotes/origin/feat-new-mr
|
|
`))
|
|
|
|
cliStr := []string{
|
|
"-t", "myMRtitle",
|
|
"-d", "myMRbody",
|
|
"-l", "test,bug",
|
|
"--milestone", "1",
|
|
"--assignee", "testuser",
|
|
}
|
|
|
|
cli := strings.Join(cliStr, " ")
|
|
|
|
runE := func(opts *CreateOpts) error {
|
|
opts.HeadRepo = func() (glrepo.Interface, error) {
|
|
return glrepo.New("OWNER", "REPO"), nil
|
|
}
|
|
return createRun(opts)
|
|
}
|
|
t.Log(cli)
|
|
|
|
pu, _ := url.Parse("https://github.com/OWNER/REPO.git")
|
|
t.Log(pu)
|
|
remotes := 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"),
|
|
},
|
|
}
|
|
output, err := runCommand(fakeHTTP, remotes, runE, "feat-new-mr", true, cli)
|
|
if err != nil {
|
|
if errors.Is(err, cmdutils.SilentError) {
|
|
t.Errorf("Unexpected error: %q", output.Stderr())
|
|
}
|
|
t.Error(err)
|
|
return
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
func TestMRCreate_nontty_insufficient_flags(t *testing.T) {
|
|
fakeHTTP := httpmock.New()
|
|
defer fakeHTTP.Verify(t)
|
|
|
|
_, err := runCommand(fakeHTTP, nil, nil, "test-br", false, "")
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
|
|
assert.Equal(t, "--title or --fill required for non-interactive mode", err.Error())
|
|
}
|
|
|
|
func TestMrBodyAndTitle(t *testing.T) {
|
|
opts := &CreateOpts{
|
|
SourceBranch: "mr-autofill-test-br",
|
|
TargetBranch: "master",
|
|
TargetTrackingBranch: "origin/master",
|
|
}
|
|
t.Run("", func(t *testing.T) {
|
|
cs, csTeardown := test.InitCmdStubber()
|
|
defer csTeardown()
|
|
cs.Stub("d1sd2e,docs: add some changes to txt file") // git log
|
|
cs.Stub("Here, I am adding some commit body.\nLittle longer\n\nResolves #1\n") // git log
|
|
|
|
if err := mrBodyAndTitle(opts); err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
return
|
|
}
|
|
|
|
assert.Equal(t, "docs: add some changes to txt file", opts.Title)
|
|
assert.Equal(t, "Here, I am adding some commit body.\nLittle longer\n\nResolves #1\n", opts.Description)
|
|
})
|
|
t.Run("given-title", func(t *testing.T) {
|
|
cs, csTeardown := test.InitCmdStubber()
|
|
defer csTeardown()
|
|
|
|
cs.Stub("d1sd2e,docs: add some changes to txt file")
|
|
cs.Stub("Here, I am adding some commit body.\nLittle longer\n\nResolves #1\n") // git log
|
|
|
|
opts := *opts
|
|
opts.Title = "docs: make some other stuff"
|
|
if err := mrBodyAndTitle(&opts); err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
return
|
|
}
|
|
|
|
assert.Equal(t, "docs: make some other stuff", opts.Title)
|
|
assert.Equal(t, `Here, I am adding some commit body.
|
|
Little longer
|
|
|
|
Resolves #1
|
|
`, opts.Description)
|
|
})
|
|
t.Run("given-description", func(t *testing.T) {
|
|
cs, csTeardown := test.InitCmdStubber()
|
|
defer csTeardown()
|
|
|
|
cs.Stub("d1sd2e,docs: add some changes to txt file")
|
|
|
|
opts := *opts
|
|
opts.Description = `Make it multiple lines
|
|
like this
|
|
|
|
resolves #1
|
|
`
|
|
if err := mrBodyAndTitle(&opts); err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
return
|
|
}
|
|
|
|
assert.Equal(t, "docs: add some changes to txt file", opts.Title)
|
|
assert.Equal(t, `Make it multiple lines
|
|
like this
|
|
|
|
resolves #1
|
|
`, opts.Description)
|
|
})
|
|
t.Run("given-fill-commit-body", func(t *testing.T) {
|
|
opts = &CreateOpts{
|
|
SourceBranch: "mr-autofill-test-br",
|
|
TargetBranch: "master",
|
|
TargetTrackingBranch: "origin/master",
|
|
}
|
|
cs, csTeardown := test.InitCmdStubber()
|
|
defer csTeardown()
|
|
|
|
cs.Stub("d1sd2e,chore: some tidying\nd2asa3,docs: more changes to more things")
|
|
cs.Stub("Here, I am adding some commit body.\nLittle longer\n\nResolves #1\n")
|
|
cs.Stub("another body for another commit\ncloses 1234\n")
|
|
|
|
opts := *opts
|
|
opts.FillCommitBody = true
|
|
|
|
if err := mrBodyAndTitle(&opts); err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
return
|
|
}
|
|
|
|
assert.Equal(t, "mr autofill test br", opts.Title)
|
|
assert.Equal(t, `- docs: more changes to more things
|
|
Here, I am adding some commit body.
|
|
Little longer
|
|
Resolves #1
|
|
|
|
- chore: some tidying
|
|
another body for another commit
|
|
closes 1234
|
|
|
|
`, opts.Description)
|
|
})
|
|
}
|