cli/pkg/cmd/auth/status/status_test.go
2021-08-25 12:41:30 +02:00

259 lines
7.3 KiB
Go

package status
import (
"bytes"
"net/http"
"regexp"
"testing"
"github.com/cli/cli/v2/internal/config"
"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"
)
func Test_NewCmdStatus(t *testing.T) {
tests := []struct {
name string
cli string
wants StatusOptions
}{
{
name: "no arguments",
cli: "",
wants: StatusOptions{},
},
{
name: "hostname set",
cli: "--hostname ellie.williams",
wants: StatusOptions{
Hostname: "ellie.williams",
},
},
{
name: "show token",
cli: "--show-token",
wants: StatusOptions{
ShowToken: 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 *StatusOptions
cmd := NewCmdStatus(f, func(opts *StatusOptions) 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)
})
}
}
func Test_statusRun(t *testing.T) {
tests := []struct {
name string
opts *StatusOptions
httpStubs func(*httpmock.Registry)
cfg func(config.Config)
wantErr string
wantErrOut *regexp.Regexp
}{
{
name: "hostname set",
opts: &StatusOptions{
Hostname: "joel.miller",
},
cfg: func(c config.Config) {
_ = c.Set("joel.miller", "oauth_token", "abc123")
_ = c.Set("github.com", "oauth_token", "abc123")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org"))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
},
wantErrOut: regexp.MustCompile(`Logged in to joel.miller as.*tess`),
},
{
name: "missing scope",
opts: &StatusOptions{},
cfg: func(c config.Config) {
_ = c.Set("joel.miller", "oauth_token", "abc123")
_ = c.Set("github.com", "oauth_token", "abc123")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo"))
reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org"))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
},
wantErrOut: regexp.MustCompile(`joel.miller: missing required.*Logged in to github.com as.*tess`),
wantErr: "SilentError",
},
{
name: "bad token",
opts: &StatusOptions{},
cfg: func(c config.Config) {
_ = c.Set("joel.miller", "oauth_token", "abc123")
_ = c.Set("github.com", "oauth_token", "abc123")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.StatusStringResponse(400, "no bueno"))
reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org"))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
},
wantErrOut: regexp.MustCompile(`joel.miller: authentication failed.*Logged in to github.com as.*tess`),
wantErr: "SilentError",
},
{
name: "all good",
opts: &StatusOptions{},
cfg: func(c config.Config) {
_ = c.Set("joel.miller", "oauth_token", "abc123")
_ = c.Set("github.com", "oauth_token", "abc123")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org"))
reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org"))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
},
wantErrOut: regexp.MustCompile(`(?s)Logged in to github.com as.*tess.*Logged in to joel.miller as.*tess`),
},
{
name: "hide token",
opts: &StatusOptions{},
cfg: func(c config.Config) {
_ = c.Set("joel.miller", "oauth_token", "abc123")
_ = c.Set("github.com", "oauth_token", "xyz456")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org"))
reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org"))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
},
wantErrOut: regexp.MustCompile(`(?s)Token: \*{19}.*Token: \*{19}`),
},
{
name: "show token",
opts: &StatusOptions{
ShowToken: true,
},
cfg: func(c config.Config) {
_ = c.Set("joel.miller", "oauth_token", "abc123")
_ = c.Set("github.com", "oauth_token", "xyz456")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org"))
reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org"))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
reg.Register(
httpmock.GraphQL(`query UserCurrent\b`),
httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`))
},
wantErrOut: regexp.MustCompile(`(?s)Token: xyz456.*Token: abc123`),
}, {
name: "missing hostname",
opts: &StatusOptions{
Hostname: "github.example.com",
},
cfg: func(c config.Config) {
_ = c.Set("github.com", "oauth_token", "abc123")
},
httpStubs: func(reg *httpmock.Registry) {},
wantErrOut: regexp.MustCompile(`(?s)Hostname "github.example.com" not found among authenticated GitHub hosts`),
wantErr: "SilentError",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.opts == nil {
tt.opts = &StatusOptions{}
}
io, _, _, stderr := iostreams.Test()
io.SetStdinTTY(true)
io.SetStderrTTY(true)
io.SetStdoutTTY(true)
tt.opts.IO = io
cfg := config.NewBlankConfig()
if tt.cfg != nil {
tt.cfg(cfg)
}
tt.opts.Config = func() (config.Config, error) {
return cfg, nil
}
reg := &httpmock.Registry{}
tt.opts.HttpClient = func() (*http.Client, error) {
return &http.Client{Transport: reg}, nil
}
if tt.httpStubs != nil {
tt.httpStubs(reg)
}
mainBuf := bytes.Buffer{}
hostsBuf := bytes.Buffer{}
defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
err := statusRun(tt.opts)
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr)
return
} else {
assert.NoError(t, err)
}
if tt.wantErrOut == nil {
assert.Equal(t, "", stderr.String())
} else {
assert.True(t, tt.wantErrOut.MatchString(stderr.String()))
}
assert.Equal(t, "", mainBuf.String())
assert.Equal(t, "", hostsBuf.String())
reg.Verify(t)
})
}
}