cli/pkg/cmd/repo/list/list_test.go

369 lines
7.9 KiB
Go

package list
import (
"bytes"
"io/ioutil"
"net/http"
"testing"
"time"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/internal/config"
"github.com/cli/cli/pkg/cmdutil"
"github.com/cli/cli/pkg/httpmock"
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/test"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewCmdList(t *testing.T) {
tests := []struct {
name string
cli string
wants ListOptions
wantsErr string
}{
{
name: "no arguments",
cli: "",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "",
Fork: false,
Source: false,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "with owner",
cli: "monalisa",
wants: ListOptions{
Limit: 30,
Owner: "monalisa",
Visibility: "",
Fork: false,
Source: false,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "with limit",
cli: "-L 101",
wants: ListOptions{
Limit: 101,
Owner: "",
Visibility: "",
Fork: false,
Source: false,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "only public",
cli: "--public",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "public",
Fork: false,
Source: false,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "only private",
cli: "--private",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "private",
Fork: false,
Source: false,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "only forks",
cli: "--fork",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "",
Fork: true,
Source: false,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "only sources",
cli: "--source",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "",
Fork: false,
Source: true,
Language: "",
Archived: false,
NonArchived: false,
},
},
{
name: "with language",
cli: "-l go",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "",
Fork: false,
Source: false,
Language: "go",
Archived: false,
NonArchived: false,
},
},
{
name: "only archived",
cli: "--archived",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "",
Fork: false,
Source: false,
Language: "",
Archived: true,
NonArchived: false,
},
},
{
name: "only non-archived",
cli: "--no-archived",
wants: ListOptions{
Limit: 30,
Owner: "",
Visibility: "",
Fork: false,
Source: false,
Language: "",
Archived: false,
NonArchived: true,
},
},
{
name: "no public and private",
cli: "--public --private",
wantsErr: "specify only one of `--public` or `--private`",
},
{
name: "no forks with sources",
cli: "--fork --source",
wantsErr: "specify only one of `--source` or `--fork`",
},
{
name: "conflicting archived",
cli: "--archived --no-archived",
wantsErr: "specify only one of `--archived` or `--no-archived`",
},
{
name: "too many arguments",
cli: "monalisa hubot",
wantsErr: "accepts at most 1 arg(s), received 2",
},
{
name: "invalid limit",
cli: "-L 0",
wantsErr: "invalid limit: 0",
},
}
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 *ListOptions
cmd := NewCmdList(f, func(opts *ListOptions) error {
gotOpts = opts
return nil
})
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
_, err = cmd.ExecuteC()
if tt.wantsErr != "" {
assert.EqualError(t, err, tt.wantsErr)
return
}
require.NoError(t, err)
assert.Equal(t, tt.wants.Limit, gotOpts.Limit)
assert.Equal(t, tt.wants.Owner, gotOpts.Owner)
assert.Equal(t, tt.wants.Visibility, gotOpts.Visibility)
assert.Equal(t, tt.wants.Fork, gotOpts.Fork)
assert.Equal(t, tt.wants.Source, gotOpts.Source)
assert.Equal(t, tt.wants.Archived, gotOpts.Archived)
assert.Equal(t, tt.wants.NonArchived, gotOpts.NonArchived)
})
}
}
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
io, _, stdout, stderr := iostreams.Test()
io.SetStdoutTTY(isTTY)
io.SetStdinTTY(isTTY)
io.SetStderrTTY(isTTY)
factory := &cmdutil.Factory{
IOStreams: io,
HttpClient: func() (*http.Client, error) {
return &http.Client{Transport: rt}, nil
},
Config: func() (config.Config, error) {
return config.NewBlankConfig(), nil
},
}
cmd := NewCmdList(factory, nil)
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 TestRepoList_nontty(t *testing.T) {
io, _, stdout, stderr := iostreams.Test()
io.SetStdoutTTY(false)
io.SetStdinTTY(false)
io.SetStderrTTY(false)
httpReg := &httpmock.Registry{}
defer httpReg.Verify(t)
httpReg.Register(
httpmock.GraphQL(`query RepositoryList\b`),
httpmock.FileResponse("./fixtures/repoList.json"),
)
opts := ListOptions{
IO: io,
HttpClient: func() (*http.Client, error) {
return &http.Client{Transport: httpReg}, nil
},
Config: func() (config.Config, error) {
return config.NewBlankConfig(), nil
},
Now: func() time.Time {
t, _ := time.Parse(time.RFC822, "19 Feb 21 15:00 UTC")
return t
},
Limit: 30,
}
err := listRun(&opts)
assert.NoError(t, err)
assert.Equal(t, "", stderr.String())
assert.Equal(t, heredoc.Doc(`
octocat/hello-world My first repository public 2021-02-19T06:34:58Z
octocat/cli GitHub CLI public, fork 2021-02-19T06:06:06Z
octocat/testing private 2021-02-11T22:32:05Z
`), stdout.String())
}
func TestRepoList_tty(t *testing.T) {
io, _, stdout, stderr := iostreams.Test()
io.SetStdoutTTY(true)
io.SetStdinTTY(true)
io.SetStderrTTY(true)
httpReg := &httpmock.Registry{}
defer httpReg.Verify(t)
httpReg.Register(
httpmock.GraphQL(`query RepositoryList\b`),
httpmock.FileResponse("./fixtures/repoList.json"),
)
opts := ListOptions{
IO: io,
HttpClient: func() (*http.Client, error) {
return &http.Client{Transport: httpReg}, nil
},
Config: func() (config.Config, error) {
return config.NewBlankConfig(), nil
},
Now: func() time.Time {
t, _ := time.Parse(time.RFC822, "19 Feb 21 15:00 UTC")
return t
},
Limit: 30,
}
err := listRun(&opts)
assert.NoError(t, err)
assert.Equal(t, "", stderr.String())
assert.Equal(t, heredoc.Doc(`
Showing 3 of 3 repositories in @octocat
octocat/hello-world My first repository public 8h
octocat/cli GitHub CLI public, fork 8h
octocat/testing private 7d
`), stdout.String())
}
func TestRepoList_filtering(t *testing.T) {
http := &httpmock.Registry{}
defer http.Verify(t)
http.Register(
httpmock.GraphQL(`query RepositoryList\b`),
httpmock.GraphQLQuery(`{}`, func(_ string, params map[string]interface{}) {
assert.Equal(t, "PRIVATE", params["privacy"])
assert.Equal(t, float64(2), params["perPage"])
}),
)
output, err := runCommand(http, true, `--private --limit 2 `)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "", output.Stderr())
assert.Equal(t, "\nNo results match your search\n\n", output.String())
}