194 lines
4.7 KiB
Go
194 lines
4.7 KiB
Go
package transfer
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/cli/cli/v2/internal/config"
|
|
"github.com/cli/cli/v2/internal/gh"
|
|
"github.com/cli/cli/v2/internal/ghrepo"
|
|
"github.com/cli/cli/v2/pkg/cmdutil"
|
|
"github.com/cli/cli/v2/pkg/httpmock"
|
|
"github.com/cli/cli/v2/pkg/iostreams"
|
|
"github.com/cli/cli/v2/test"
|
|
"github.com/google/shlex"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func runCommand(rt http.RoundTripper, cli string) (*test.CmdOut, error) {
|
|
ios, _, stdout, stderr := iostreams.Test()
|
|
|
|
factory := &cmdutil.Factory{
|
|
IOStreams: ios,
|
|
HttpClient: func() (*http.Client, error) {
|
|
return &http.Client{Transport: rt}, nil
|
|
},
|
|
Config: func() (gh.Config, error) {
|
|
return config.NewBlankConfig(), nil
|
|
},
|
|
BaseRepo: func() (ghrepo.Interface, error) {
|
|
return ghrepo.New("OWNER", "REPO"), nil
|
|
},
|
|
}
|
|
|
|
ios.SetStdoutTTY(true)
|
|
|
|
cmd := NewCmdTransfer(factory, nil)
|
|
|
|
argv, err := shlex.Split(cli)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmd.SetArgs(argv)
|
|
|
|
cmd.SetIn(&bytes.Buffer{})
|
|
cmd.SetOut(io.Discard)
|
|
cmd.SetErr(io.Discard)
|
|
|
|
_, err = cmd.ExecuteC()
|
|
|
|
return &test.CmdOut{
|
|
OutBuf: stdout,
|
|
ErrBuf: stderr,
|
|
}, err
|
|
}
|
|
|
|
func TestNewCmdTransfer(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cli string
|
|
wants TransferOptions
|
|
wantBaseRepo ghrepo.Interface
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "no argument",
|
|
cli: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "issue number argument",
|
|
cli: "--repo cli/repo 23 OWNER/REPO",
|
|
wants: TransferOptions{
|
|
IssueNumber: 23,
|
|
DestRepoSelector: "OWNER/REPO",
|
|
},
|
|
wantBaseRepo: ghrepo.New("cli", "repo"),
|
|
},
|
|
{
|
|
name: "argument is hash prefixed number",
|
|
// Escaping is required here to avoid what I think is shellex treating it as a comment.
|
|
cli: "--repo cli/repo \\#23 OWNER/REPO",
|
|
wants: TransferOptions{
|
|
IssueNumber: 23,
|
|
DestRepoSelector: "OWNER/REPO",
|
|
},
|
|
wantBaseRepo: ghrepo.New("cli", "repo"),
|
|
},
|
|
{
|
|
name: "argument is a URL",
|
|
cli: "https://github.com/cli/cli/issues/23 OWNER/REPO",
|
|
wants: TransferOptions{
|
|
IssueNumber: 23,
|
|
DestRepoSelector: "OWNER/REPO",
|
|
},
|
|
wantBaseRepo: ghrepo.New("cli", "cli"),
|
|
},
|
|
{
|
|
name: "argument cannot be parsed to an issue",
|
|
cli: "unparseable OWNER/REPO",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := &cmdutil.Factory{}
|
|
|
|
argv, err := shlex.Split(tt.cli)
|
|
assert.NoError(t, err)
|
|
|
|
var gotOpts *TransferOptions
|
|
cmd := NewCmdTransfer(f, func(opts *TransferOptions) error {
|
|
gotOpts = opts
|
|
return nil
|
|
})
|
|
cmdutil.EnableRepoOverride(cmd, f)
|
|
|
|
cmd.SetArgs(argv)
|
|
cmd.SetIn(&bytes.Buffer{})
|
|
cmd.SetOut(&bytes.Buffer{})
|
|
cmd.SetErr(&bytes.Buffer{})
|
|
|
|
_, cErr := cmd.ExecuteC()
|
|
if tt.wantErr {
|
|
require.Error(t, cErr)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, cErr)
|
|
assert.Equal(t, tt.wants.IssueNumber, gotOpts.IssueNumber)
|
|
assert.Equal(t, tt.wants.DestRepoSelector, gotOpts.DestRepoSelector)
|
|
actualBaseRepo, err := gotOpts.BaseRepo()
|
|
require.NoError(t, err)
|
|
assert.True(
|
|
t,
|
|
ghrepo.IsSame(tt.wantBaseRepo, actualBaseRepo),
|
|
"expected base repo %+v, got %+v", tt.wantBaseRepo, actualBaseRepo,
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_transferRun_noflags(t *testing.T) {
|
|
http := &httpmock.Registry{}
|
|
defer http.Verify(t)
|
|
|
|
output, err := runCommand(http, "")
|
|
|
|
if err != nil {
|
|
assert.Equal(t, "issue and destination repository are required", err.Error())
|
|
}
|
|
|
|
assert.Equal(t, "", output.String())
|
|
}
|
|
|
|
func Test_transferRunSuccessfulIssueTransfer(t *testing.T) {
|
|
http := &httpmock.Registry{}
|
|
defer http.Verify(t)
|
|
|
|
http.Register(
|
|
httpmock.GraphQL(`query IssueByNumber\b`),
|
|
httpmock.StringResponse(`
|
|
{ "data": { "repository": {
|
|
"hasIssuesEnabled": true,
|
|
"issue": { "id": "THE-ID", "number": 1234, "title": "The title of the issue"}
|
|
} } }`))
|
|
|
|
http.Register(
|
|
httpmock.GraphQL(`query IssueRepositoryInfo\b`),
|
|
httpmock.StringResponse(`
|
|
{ "data": { "repository": {
|
|
"id": "dest-id",
|
|
"name": "REPO1",
|
|
"owner": { "login": "OWNER1" },
|
|
"viewerPermission": "WRITE",
|
|
"hasIssuesEnabled": true
|
|
}}}`))
|
|
|
|
http.Register(
|
|
httpmock.GraphQL(`mutation IssueTransfer\b`),
|
|
httpmock.GraphQLMutation(`{"data":{"transferIssue":{"issue":{"url":"https://github.com/OWNER1/REPO1/issues/1"}}}}`, func(input map[string]interface{}) {
|
|
assert.Equal(t, input["issueId"], "THE-ID")
|
|
assert.Equal(t, input["repositoryId"], "dest-id")
|
|
}))
|
|
|
|
output, err := runCommand(http, "1234 OWNER1/REPO1")
|
|
if err != nil {
|
|
t.Errorf("error running command `issue transfer`: %v", err)
|
|
}
|
|
assert.Equal(t, "https://github.com/OWNER1/REPO1/issues/1\n", output.String())
|
|
}
|