github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/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/ungtb10d/cli/v2/internal/config" 10 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 11 "github.com/ungtb10d/cli/v2/pkg/httpmock" 12 "github.com/ungtb10d/cli/v2/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 readConfigs := config.StubWriteConfig(t) 75 76 tests := []struct { 77 name string 78 opts *StatusOptions 79 httpStubs func(*httpmock.Registry) 80 cfgStubs func(*config.ConfigMock) 81 wantErr string 82 wantErrOut *regexp.Regexp 83 }{ 84 { 85 name: "hostname set", 86 opts: &StatusOptions{ 87 Hostname: "joel.miller", 88 }, 89 cfgStubs: func(c *config.ConfigMock) { 90 c.Set("joel.miller", "oauth_token", "abc123") 91 c.Set("github.com", "oauth_token", "abc123") 92 }, 93 httpStubs: func(reg *httpmock.Registry) { 94 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 95 reg.Register( 96 httpmock.GraphQL(`query UserCurrent\b`), 97 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 98 }, 99 wantErrOut: regexp.MustCompile(`Logged in to joel.miller as.*tess`), 100 }, 101 { 102 name: "missing scope", 103 opts: &StatusOptions{}, 104 cfgStubs: func(c *config.ConfigMock) { 105 c.Set("joel.miller", "oauth_token", "abc123") 106 c.Set("github.com", "oauth_token", "abc123") 107 }, 108 httpStubs: func(reg *httpmock.Registry) { 109 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo")) 110 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 111 reg.Register( 112 httpmock.GraphQL(`query UserCurrent\b`), 113 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 114 }, 115 wantErrOut: regexp.MustCompile(`joel.miller: missing required.*Logged in to github.com as.*tess`), 116 wantErr: "SilentError", 117 }, 118 { 119 name: "bad token", 120 opts: &StatusOptions{}, 121 cfgStubs: func(c *config.ConfigMock) { 122 c.Set("joel.miller", "oauth_token", "abc123") 123 c.Set("github.com", "oauth_token", "abc123") 124 }, 125 httpStubs: func(reg *httpmock.Registry) { 126 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.StatusStringResponse(400, "no bueno")) 127 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 128 reg.Register( 129 httpmock.GraphQL(`query UserCurrent\b`), 130 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 131 }, 132 wantErrOut: regexp.MustCompile(`joel.miller: authentication failed.*Logged in to github.com as.*tess`), 133 wantErr: "SilentError", 134 }, 135 { 136 name: "all good", 137 opts: &StatusOptions{}, 138 cfgStubs: func(c *config.ConfigMock) { 139 c.Set("github.com", "oauth_token", "abc123") 140 c.Set("joel.miller", "oauth_token", "abc123") 141 }, 142 httpStubs: func(reg *httpmock.Registry) { 143 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 144 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 145 reg.Register( 146 httpmock.GraphQL(`query UserCurrent\b`), 147 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 148 reg.Register( 149 httpmock.GraphQL(`query UserCurrent\b`), 150 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 151 }, 152 wantErrOut: regexp.MustCompile(`(?s)Logged in to github.com as.*tess.*Logged in to joel.miller as.*tess`), 153 }, 154 { 155 name: "hide token", 156 opts: &StatusOptions{}, 157 cfgStubs: func(c *config.ConfigMock) { 158 c.Set("joel.miller", "oauth_token", "abc123") 159 c.Set("github.com", "oauth_token", "xyz456") 160 }, 161 httpStubs: func(reg *httpmock.Registry) { 162 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 163 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 164 reg.Register( 165 httpmock.GraphQL(`query UserCurrent\b`), 166 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 167 reg.Register( 168 httpmock.GraphQL(`query UserCurrent\b`), 169 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 170 }, 171 wantErrOut: regexp.MustCompile(`(?s)Token: \*{19}.*Token: \*{19}`), 172 }, 173 { 174 name: "show token", 175 opts: &StatusOptions{ 176 ShowToken: true, 177 }, 178 cfgStubs: func(c *config.ConfigMock) { 179 c.Set("github.com", "oauth_token", "xyz456") 180 c.Set("joel.miller", "oauth_token", "abc123") 181 }, 182 httpStubs: func(reg *httpmock.Registry) { 183 reg.Register(httpmock.REST("GET", "api/v3/"), httpmock.ScopesResponder("repo,read:org")) 184 reg.Register(httpmock.REST("GET", ""), httpmock.ScopesResponder("repo,read:org")) 185 reg.Register( 186 httpmock.GraphQL(`query UserCurrent\b`), 187 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 188 reg.Register( 189 httpmock.GraphQL(`query UserCurrent\b`), 190 httpmock.StringResponse(`{"data":{"viewer":{"login":"tess"}}}`)) 191 }, 192 wantErrOut: regexp.MustCompile(`(?s)Token: xyz456.*Token: abc123`), 193 }, 194 { 195 name: "missing hostname", 196 opts: &StatusOptions{ 197 Hostname: "github.example.com", 198 }, 199 cfgStubs: func(c *config.ConfigMock) { 200 c.Set("github.com", "oauth_token", "abc123") 201 }, 202 httpStubs: func(reg *httpmock.Registry) {}, 203 wantErrOut: regexp.MustCompile(`(?s)Hostname "github.example.com" not found among authenticated GitHub hosts`), 204 wantErr: "SilentError", 205 }, 206 } 207 208 for _, tt := range tests { 209 t.Run(tt.name, func(t *testing.T) { 210 if tt.opts == nil { 211 tt.opts = &StatusOptions{} 212 } 213 214 ios, _, _, stderr := iostreams.Test() 215 216 ios.SetStdinTTY(true) 217 ios.SetStderrTTY(true) 218 ios.SetStdoutTTY(true) 219 tt.opts.IO = ios 220 221 cfg := config.NewFromString("") 222 if tt.cfgStubs != nil { 223 tt.cfgStubs(cfg) 224 } 225 tt.opts.Config = func() (config.Config, error) { 226 return cfg, nil 227 } 228 229 reg := &httpmock.Registry{} 230 tt.opts.HttpClient = func() (*http.Client, error) { 231 return &http.Client{Transport: reg}, nil 232 } 233 if tt.httpStubs != nil { 234 tt.httpStubs(reg) 235 } 236 237 err := statusRun(tt.opts) 238 if tt.wantErr != "" { 239 assert.EqualError(t, err, tt.wantErr) 240 return 241 } else { 242 assert.NoError(t, err) 243 } 244 245 if tt.wantErrOut == nil { 246 assert.Equal(t, "", stderr.String()) 247 } else { 248 assert.True(t, tt.wantErrOut.MatchString(stderr.String())) 249 } 250 251 mainBuf := bytes.Buffer{} 252 hostsBuf := bytes.Buffer{} 253 readConfigs(&mainBuf, &hostsBuf) 254 255 assert.Equal(t, "", mainBuf.String()) 256 assert.Equal(t, "", hostsBuf.String()) 257 258 reg.Verify(t) 259 }) 260 } 261 }