cli/pkg/cmd/release/list/list_test.go
2024-01-26 16:10:48 -05:00

251 lines
6 KiB
Go

package list
import (
"bytes"
"fmt"
"io"
"net/http"
"testing"
"time"
"github.com/MakeNowJust/heredoc"
"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/google/shlex"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_NewCmdList(t *testing.T) {
tests := []struct {
name string
args string
isTTY bool
want ListOptions
wantErr string
}{
{
name: "no arguments",
args: "",
isTTY: true,
want: ListOptions{
LimitResults: 30,
ExcludeDrafts: false,
ExcludePreReleases: false,
Order: "desc",
},
},
{
name: "exclude drafts",
args: "--exclude-drafts",
want: ListOptions{
LimitResults: 30,
ExcludeDrafts: true,
ExcludePreReleases: false,
Order: "desc",
},
},
{
name: "exclude pre-releases",
args: "--exclude-pre-releases",
want: ListOptions{
LimitResults: 30,
ExcludeDrafts: false,
ExcludePreReleases: true,
Order: "desc",
},
},
{
name: "with order",
args: "--order asc",
want: ListOptions{
LimitResults: 30,
ExcludeDrafts: false,
ExcludePreReleases: false,
Order: "asc",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ios, _, _, _ := iostreams.Test()
ios.SetStdoutTTY(tt.isTTY)
ios.SetStdinTTY(tt.isTTY)
ios.SetStderrTTY(tt.isTTY)
f := &cmdutil.Factory{
IOStreams: ios,
}
var opts *ListOptions
cmd := NewCmdList(f, func(o *ListOptions) error {
opts = o
return nil
})
cmd.PersistentFlags().StringP("repo", "R", "", "")
argv, err := shlex.Split(tt.args)
require.NoError(t, err)
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
_, err = cmd.ExecuteC()
if tt.wantErr != "" {
require.EqualError(t, err, tt.wantErr)
return
} else {
require.NoError(t, err)
}
assert.Equal(t, tt.want.LimitResults, opts.LimitResults)
assert.Equal(t, tt.want.ExcludeDrafts, opts.ExcludeDrafts)
assert.Equal(t, tt.want.ExcludePreReleases, opts.ExcludePreReleases)
assert.Equal(t, tt.want.Order, opts.Order)
})
}
}
func Test_listRun(t *testing.T) {
frozenTime, err := time.Parse(time.RFC3339, "2020-08-31T15:44:24+02:00")
require.NoError(t, err)
tests := []struct {
name string
isTTY bool
opts ListOptions
wantErr string
wantStdout string
wantStderr string
}{
{
name: "list releases",
isTTY: true,
opts: ListOptions{
LimitResults: 30,
},
wantStdout: heredoc.Doc(`
TITLE TYPE TAG NAME PUBLISHED
v1.1.0 Draft v1.1.0 about 1 day ago
The big 1.0 Latest v1.0.0 about 1 day ago
1.0 release candidate Pre-release v1.0.0-pre.2 about 1 day ago
New features v0.9.2 about 1 day ago
`),
wantStderr: ``,
},
{
name: "machine-readable",
isTTY: false,
opts: ListOptions{
LimitResults: 30,
},
wantStdout: heredoc.Doc(`
v1.1.0 Draft v1.1.0 2020-08-31T15:44:24+02:00
The big 1.0 Latest v1.0.0 2020-08-31T15:44:24+02:00
1.0 release candidate Pre-release v1.0.0-pre.2 2020-08-31T15:44:24+02:00
New features v0.9.2 2020-08-31T15:44:24+02:00
`),
wantStderr: ``,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ios, _, stdout, stderr := iostreams.Test()
ios.SetStdoutTTY(tt.isTTY)
ios.SetStdinTTY(tt.isTTY)
ios.SetStderrTTY(tt.isTTY)
createdAt := frozenTime
if tt.isTTY {
createdAt = time.Now().Add(time.Duration(-24) * time.Hour)
}
fakeHTTP := &httpmock.Registry{}
fakeHTTP.Register(httpmock.GraphQL(`\bRepositoryReleaseList\(`), httpmock.StringResponse(fmt.Sprintf(`
{ "data": { "repository": { "releases": {
"nodes": [
{
"name": "",
"tagName": "v1.1.0",
"isLatest": false,
"isDraft": true,
"isPrerelease": false,
"createdAt": "%[1]s",
"publishedAt": "%[1]s"
},
{
"name": "The big 1.0",
"tagName": "v1.0.0",
"isLatest": true,
"isDraft": false,
"isPrerelease": false,
"createdAt": "%[1]s",
"publishedAt": "%[1]s"
},
{
"name": "1.0 release candidate",
"tagName": "v1.0.0-pre.2",
"isLatest": false,
"isDraft": false,
"isPrerelease": true,
"createdAt": "%[1]s",
"publishedAt": "%[1]s"
},
{
"name": "New features",
"tagName": "v0.9.2",
"isLatest": false,
"isDraft": false,
"isPrerelease": false,
"createdAt": "%[1]s",
"publishedAt": "%[1]s"
}
]
} } } }`, createdAt.Format(time.RFC3339))))
tt.opts.IO = ios
tt.opts.HttpClient = func() (*http.Client, error) {
return &http.Client{Transport: fakeHTTP}, nil
}
tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
return ghrepo.FromFullName("OWNER/REPO")
}
err := listRun(&tt.opts)
if tt.wantErr != "" {
require.EqualError(t, err, tt.wantErr)
return
} else {
require.NoError(t, err)
}
assert.Equal(t, tt.wantStdout, stdout.String())
assert.Equal(t, tt.wantStderr, stderr.String())
})
}
}
func TestExportReleases(t *testing.T) {
ios, _, stdout, _ := iostreams.Test()
createdAt, _ := time.Parse(time.RFC3339, "2024-01-01T00:00:00Z")
publishedAt, _ := time.Parse(time.RFC3339, "2024-02-01T00:00:00Z")
rs := []Release{{
Name: "v1",
TagName: "tag",
IsDraft: true,
IsLatest: false,
IsPrerelease: true,
CreatedAt: createdAt,
PublishedAt: publishedAt,
}}
exporter := cmdutil.NewJSONExporter()
exporter.SetFields(releaseFields)
require.NoError(t, exporter.Write(ios, rs))
require.JSONEq(t,
`[{"createdAt":"2024-01-01T00:00:00Z","isDraft":true,"isLatest":false,"isPrerelease":true,"name":"v1","publishedAt":"2024-02-01T00:00:00Z","tagName":"tag"}]`,
stdout.String())
}