cli/pkg/cmd/auth/refresh/refresh_test.go
Mislav Marohnić c80292c2e8 Extend Config object with GITHUB_TOKEN support
Adding GITHUB_TOKEN & GITHUB_ENTERPRISE_TOKEN support orthogonal to
Config was getting out of hand, especially in `auth` commands that
adjust their messaging and error status based on the presence of these
environment variables.

The new approach builds in support for tokens from environment straight
into Config object by composition. Thus, commands need not ever be
concerned with any specific environment variables.
2020-09-07 21:33:26 +02:00

231 lines
4.8 KiB
Go

package refresh
import (
"bytes"
"regexp"
"testing"
"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/pkg/prompt"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
func Test_NewCmdRefresh(t *testing.T) {
tests := []struct {
name string
cli string
wants RefreshOptions
}{
{
name: "no arguments",
wants: RefreshOptions{
Hostname: "",
},
},
{
name: "hostname",
cli: "-h aline.cedrac",
wants: RefreshOptions{
Hostname: "aline.cedrac",
},
},
{
name: "one scope",
cli: "--scopes repo:invite",
wants: RefreshOptions{
Scopes: []string{"repo:invite"},
},
},
{
name: "scopes",
cli: "--scopes repo:invite,read:public_key",
wants: RefreshOptions{
Scopes: []string{"repo:invite", "read:public_key"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
io, _, _, _ := iostreams.Test()
f := &cmdutil.Factory{
IOStreams: io,
}
argv, err := shlex.Split(tt.cli)
assert.NoError(t, err)
var gotOpts *RefreshOptions
cmd := NewCmdRefresh(f, func(opts *RefreshOptions) error {
gotOpts = opts
return nil
})
// TODO cobra hack-around
cmd.Flags().BoolP("help", "x", false, "")
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
_, err = cmd.ExecuteC()
assert.NoError(t, err)
assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname)
assert.Equal(t, tt.wants.Scopes, gotOpts.Scopes)
})
}
}
type authArgs struct {
hostname string
scopes []string
}
func Test_refreshRun(t *testing.T) {
tests := []struct {
name string
opts *RefreshOptions
askStubs func(*prompt.AskStubber)
cfgHosts []string
wantErr *regexp.Regexp
nontty bool
wantAuthArgs authArgs
}{
{
name: "non tty",
opts: &RefreshOptions{},
nontty: true,
wantErr: regexp.MustCompile(`not attached to a terminal;`),
},
{
name: "no hosts configured",
opts: &RefreshOptions{},
wantErr: regexp.MustCompile(`not logged in to any hosts`),
},
{
name: "hostname given but dne",
cfgHosts: []string{
"github.com",
"aline.cedrac",
},
opts: &RefreshOptions{
Hostname: "obed.morton",
},
wantErr: regexp.MustCompile(`not logged in to obed.morton`),
},
{
name: "hostname provided and is configured",
cfgHosts: []string{
"obed.morton",
"github.com",
},
opts: &RefreshOptions{
Hostname: "obed.morton",
},
wantAuthArgs: authArgs{
hostname: "obed.morton",
scopes: nil,
},
},
{
name: "no hostname, one host configured",
cfgHosts: []string{
"github.com",
},
opts: &RefreshOptions{
Hostname: "",
},
wantAuthArgs: authArgs{
hostname: "github.com",
scopes: nil,
},
},
{
name: "no hostname, multiple hosts configured",
cfgHosts: []string{
"github.com",
"aline.cedrac",
},
opts: &RefreshOptions{
Hostname: "",
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne("github.com")
},
wantAuthArgs: authArgs{
hostname: "github.com",
scopes: nil,
},
},
{
name: "scopes provided",
cfgHosts: []string{
"github.com",
},
opts: &RefreshOptions{
Scopes: []string{"repo:invite", "public_key:read"},
},
wantAuthArgs: authArgs{
hostname: "github.com",
scopes: []string{"repo:invite", "public_key:read"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
aa := authArgs{}
tt.opts.AuthFlow = func(_ config.Config, hostname string, scopes []string) error {
aa.hostname = hostname
aa.scopes = scopes
return nil
}
io, _, _, _ := iostreams.Test()
io.SetStdinTTY(!tt.nontty)
io.SetStdoutTTY(!tt.nontty)
tt.opts.IO = io
cfg := config.NewBlankConfig()
tt.opts.Config = func() (config.Config, error) {
return cfg, nil
}
for _, hostname := range tt.cfgHosts {
_ = cfg.Set(hostname, "oauth_token", "abc123")
}
reg := &httpmock.Registry{}
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"cybilb"}}}`))
mainBuf := bytes.Buffer{}
hostsBuf := bytes.Buffer{}
defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
err := refreshRun(tt.opts)
assert.Equal(t, tt.wantErr == nil, err == nil)
if err != nil {
if tt.wantErr != nil {
assert.True(t, tt.wantErr.MatchString(err.Error()))
return
} else {
t.Fatalf("unexpected error: %s", err)
}
}
assert.Equal(t, aa.hostname, tt.wantAuthArgs.hostname)
assert.Equal(t, aa.scopes, tt.wantAuthArgs.scopes)
})
}
}