github.com/secman-team/gh-api@v1.8.2/pkg/cmd/auth/status/status_test.go (about) 1 package status 2 3 import ( 4 "bytes" 5 "net/http" 6 "regexp" 7 "testing" 8 9 "github.com/secman-team/gh-api/core/config" 10 "github.com/secman-team/gh-api/pkg/cmdutil" 11 "github.com/secman-team/gh-api/pkg/httpmock" 12 "github.com/secman-team/gh-api/pkg/iostreams" 13 "github.com/google/shlex" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func Test_NewCmdStatus(t *testing.T) { 18 tests := []struct { 19 name string 20 cli string 21 wants StatusOptions 22 }{ 23 { 24 name: "no arguments", 25 cli: "", 26 wants: StatusOptions{}, 27 }, 28 { 29 name: "hostname set", 30 cli: "--hostname ellie.williams", 31 wants: StatusOptions{ 32 Hostname: "ellie.williams", 33 }, 34 }, 35 { 36 name: "show token", 37 cli: "--show-token", 38 wants: StatusOptions{ 39 ShowToken: true, 40 }, 41 }, 42 } 43 44 for _, tt := range tests { 45 t.Run(tt.name, func(t *testing.T) { 46 f := &cmdutil.Factory{} 47 48 argv, err := shlex.Split(tt.cli) 49 assert.NoError(t, err) 50 51 var gotOpts *StatusOptions 52 cmd := NewCmdStatus(f, func(opts *StatusOptions) error { 53 gotOpts = opts 54 return nil 55 }) 56 57 // TODO cobra hack-around 58 cmd.Flags().BoolP("help", "x", false, "") 59 60 cmd.SetArgs(argv) 61 cmd.SetIn(&bytes.Buffer{}) 62 cmd.SetOut(&bytes.Buffer{}) 63 cmd.SetErr(&bytes.Buffer{}) 64 65 _, err = cmd.ExecuteC() 66 assert.NoError(t, err) 67 68 assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname) 69 }) 70 } 71 } 72 73 func Test_statusRun(t *testing.T) { 74 tests := []struct { 75 name string 76 opts *StatusOptions 77 httpStubs func(*httpmock.Registry) 78 cfg func(config.Config) 79 wantErr string 80 wantErrOut *regexp.Regexp 81 }{ 82 { 83 name: "hostname set", 84 opts: &StatusOptions{ 85 Hostname: "joel.miller", 86 }, 87 cfg: func(c config.Config) { 88 _ = c.Set("joel.miller", "oauth_token", "abc123") 89 _ = c.Set("github.com", "oauth_token", "abc123") 90 }, 91 httpStubs: func(reg *httpmock.Registry) { 92 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 93 reg.Register( 94 httpmock.GraphQL(`query UserCurrent\b`), 95 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 96 }, 97 wantErrOut: regexp.MustCompile(`Logged in to joel.miller as.*tess`), 98 }, 99 { 100 name: "missing scope", 101 opts: &StatusOptions{}, 102 cfg: func(c config.Config) { 103 _ = c.Set("joel.miller", "oauth_token", "abc123") 104 _ = c.Set("github.com", "oauth_token", "abc123") 105 }, 106 httpStubs: func(reg *httpmock.Registry) { 107 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo")) 108 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 109 reg.Register( 110 httpmock.GraphQL(`query UserCurrent\b`), 111 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 112 }, 113 wantErrOut: regexp.MustCompile(`joel.miller: missing required.*Logged in to github.com as.*tess`), 114 wantErr: "SilentError", 115 }, 116 { 117 name: "bad token", 118 opts: &StatusOptions{}, 119 cfg: func(c config.Config) { 120 _ = c.Set("joel.miller", "oauth_token", "abc123") 121 _ = c.Set("github.com", "oauth_token", "abc123") 122 }, 123 httpStubs: func(reg *httpmock.Registry) { 124 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.StatusStringResponse(400, "no bueno")) 125 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 126 reg.Register( 127 httpmock.GraphQL(`query UserCurrent\b`), 128 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 129 }, 130 wantErrOut: regexp.MustCompile(`joel.miller: authentication failed.*Logged in to github.com as.*tess`), 131 wantErr: "SilentError", 132 }, 133 { 134 name: "all good", 135 opts: &StatusOptions{}, 136 cfg: func(c config.Config) { 137 _ = c.Set("joel.miller", "oauth_token", "abc123") 138 _ = c.Set("github.com", "oauth_token", "abc123") 139 }, 140 httpStubs: func(reg *httpmock.Registry) { 141 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 142 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 143 reg.Register( 144 httpmock.GraphQL(`query UserCurrent\b`), 145 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 146 reg.Register( 147 httpmock.GraphQL(`query UserCurrent\b`), 148 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 149 }, 150 wantErrOut: regexp.MustCompile(`(?s)Logged in to github.com as.*tess.*Logged in to joel.miller as.*tess`), 151 }, 152 { 153 name: "hide token", 154 opts: &StatusOptions{}, 155 cfg: func(c config.Config) { 156 _ = c.Set("joel.miller", "oauth_token", "abc123") 157 _ = c.Set("github.com", "oauth_token", "xyz456") 158 }, 159 httpStubs: func(reg *httpmock.Registry) { 160 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 161 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 162 reg.Register( 163 httpmock.GraphQL(`query UserCurrent\b`), 164 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 165 reg.Register( 166 httpmock.GraphQL(`query UserCurrent\b`), 167 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 168 }, 169 wantErrOut: regexp.MustCompile(`(?s)Token: \*{19}.*Token: \*{19}`), 170 }, 171 { 172 name: "show token", 173 opts: &StatusOptions{ 174 ShowToken: true, 175 }, 176 cfg: func(c config.Config) { 177 _ = c.Set("joel.miller", "oauth_token", "abc123") 178 _ = c.Set("github.com", "oauth_token", "xyz456") 179 }, 180 httpStubs: func(reg *httpmock.Registry) { 181 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 182 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 183 reg.Register( 184 httpmock.GraphQL(`query UserCurrent\b`), 185 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 186 reg.Register( 187 httpmock.GraphQL(`query UserCurrent\b`), 188 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 189 }, 190 wantErrOut: regexp.MustCompile(`(?s)Token: xyz456.*Token: abc123`), 191 }, { 192 name: "missing hostname", 193 opts: &StatusOptions{ 194 Hostname: "github.example.com", 195 }, 196 cfg: func(c config.Config) { 197 _ = c.Set("github.com", "oauth_token", "abc123") 198 }, 199 httpStubs: func(reg *httpmock.Registry) {}, 200 wantErrOut: regexp.MustCompile(`(?s)Hostname "github.example.com" not found among authenticated GitHub hosts`), 201 wantErr: "SilentError", 202 }, 203 } 204 205 for _, tt := range tests { 206 t.Run(tt.name, func(t *testing.T) { 207 if tt.opts == nil { 208 tt.opts = &StatusOptions{} 209 } 210 211 io, _, _, stderr := iostreams.Test() 212 213 io.SetStdinTTY(true) 214 io.SetStderrTTY(true) 215 io.SetStdoutTTY(true) 216 217 tt.opts.IO = io 218 219 cfg := config.NewBlankConfig() 220 221 if tt.cfg != nil { 222 tt.cfg(cfg) 223 } 224 tt.opts.Config = func() (config.Config, error) { 225 return cfg, nil 226 } 227 228 reg := &httpmock.Registry{} 229 tt.opts.HttpClient = func() (*http.Client, error) { 230 return &http.Client{Transport: reg}, nil 231 } 232 if tt.httpStubs != nil { 233 tt.httpStubs(reg) 234 } 235 mainBuf := bytes.Buffer{} 236 hostsBuf := bytes.Buffer{} 237 defer config.StubWriteConfig(&mainBuf, &hostsBuf)() 238 239 err := statusRun(tt.opts) 240 if tt.wantErr != "" { 241 assert.EqualError(t, err, tt.wantErr) 242 return 243 } else { 244 assert.NoError(t, err) 245 } 246 247 if tt.wantErrOut == nil { 248 assert.Equal(t, "", stderr.String()) 249 } else { 250 assert.True(t, tt.wantErrOut.MatchString(stderr.String())) 251 } 252 253 assert.Equal(t, "", mainBuf.String()) 254 assert.Equal(t, "", hostsBuf.String()) 255 256 reg.Verify(t) 257 }) 258 } 259 }