github.com/secman-team/gh-api@v1.8.2/pkg/cmd/auth/logout/logout_test.go (about) 1 package logout 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/secman-team/gh-api/pkg/prompt" 14 "github.com/google/shlex" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func Test_NewCmdLogout(t *testing.T) { 19 tests := []struct { 20 name string 21 cli string 22 wants LogoutOptions 23 wantsErr bool 24 tty bool 25 }{ 26 { 27 name: "tty with hostname", 28 tty: true, 29 cli: "--hostname harry.mason", 30 wants: LogoutOptions{ 31 Hostname: "harry.mason", 32 }, 33 }, 34 { 35 name: "tty no arguments", 36 tty: true, 37 cli: "", 38 wants: LogoutOptions{ 39 Hostname: "", 40 }, 41 }, 42 { 43 name: "nontty with hostname", 44 cli: "--hostname harry.mason", 45 wants: LogoutOptions{ 46 Hostname: "harry.mason", 47 }, 48 }, 49 { 50 name: "nontty no arguments", 51 cli: "", 52 wantsErr: true, 53 }, 54 } 55 for _, tt := range tests { 56 t.Run(tt.name, func(t *testing.T) { 57 io, _, _, _ := iostreams.Test() 58 f := &cmdutil.Factory{ 59 IOStreams: io, 60 } 61 io.SetStdinTTY(tt.tty) 62 io.SetStdoutTTY(tt.tty) 63 64 argv, err := shlex.Split(tt.cli) 65 assert.NoError(t, err) 66 67 var gotOpts *LogoutOptions 68 cmd := NewCmdLogout(f, func(opts *LogoutOptions) error { 69 gotOpts = opts 70 return nil 71 }) 72 // TODO cobra hack-around 73 cmd.Flags().BoolP("help", "x", false, "") 74 75 cmd.SetArgs(argv) 76 cmd.SetIn(&bytes.Buffer{}) 77 cmd.SetOut(&bytes.Buffer{}) 78 cmd.SetErr(&bytes.Buffer{}) 79 80 _, err = cmd.ExecuteC() 81 if tt.wantsErr { 82 assert.Error(t, err) 83 return 84 } 85 assert.NoError(t, err) 86 87 assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname) 88 }) 89 90 } 91 } 92 93 func Test_logoutRun_tty(t *testing.T) { 94 tests := []struct { 95 name string 96 opts *LogoutOptions 97 askStubs func(*prompt.AskStubber) 98 cfgHosts []string 99 wantHosts string 100 wantErrOut *regexp.Regexp 101 wantErr string 102 }{ 103 { 104 name: "no arguments, multiple hosts", 105 opts: &LogoutOptions{}, 106 cfgHosts: []string{"cheryl.mason", "github.com"}, 107 wantHosts: "cheryl.mason:\n oauth_token: abc123\n", 108 askStubs: func(as *prompt.AskStubber) { 109 as.StubOne("github.com") 110 as.StubOne(true) 111 }, 112 wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`), 113 }, 114 { 115 name: "no arguments, one host", 116 opts: &LogoutOptions{}, 117 cfgHosts: []string{"github.com"}, 118 askStubs: func(as *prompt.AskStubber) { 119 as.StubOne(true) 120 }, 121 wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`), 122 }, 123 { 124 name: "no arguments, no hosts", 125 opts: &LogoutOptions{}, 126 wantErr: `not logged in to any hosts`, 127 }, 128 { 129 name: "hostname", 130 opts: &LogoutOptions{ 131 Hostname: "cheryl.mason", 132 }, 133 cfgHosts: []string{"cheryl.mason", "github.com"}, 134 wantHosts: "github.com:\n oauth_token: abc123\n", 135 askStubs: func(as *prompt.AskStubber) { 136 as.StubOne(true) 137 }, 138 wantErrOut: regexp.MustCompile(`Logged out of cheryl.mason account 'cybilb'`), 139 }, 140 } 141 142 for _, tt := range tests { 143 t.Run(tt.name, func(t *testing.T) { 144 io, _, _, stderr := iostreams.Test() 145 146 io.SetStdinTTY(true) 147 io.SetStdoutTTY(true) 148 149 tt.opts.IO = io 150 cfg := config.NewBlankConfig() 151 tt.opts.Config = func() (config.Config, error) { 152 return cfg, nil 153 } 154 155 for _, hostname := range tt.cfgHosts { 156 _ = cfg.Set(hostname, "oauth_token", "abc123") 157 } 158 159 reg := &httpmock.Registry{} 160 reg.Register( 161 httpmock.GraphQL(`query UserCurrent\b`), 162 httpmock.StringResponse(`{"data":{"viewer":{"login":"cybilb"}}}`)) 163 164 tt.opts.HttpClient = func() (*http.Client, error) { 165 return &http.Client{Transport: reg}, nil 166 } 167 168 mainBuf := bytes.Buffer{} 169 hostsBuf := bytes.Buffer{} 170 defer config.StubWriteConfig(&mainBuf, &hostsBuf)() 171 172 as, teardown := prompt.InitAskStubber() 173 defer teardown() 174 if tt.askStubs != nil { 175 tt.askStubs(as) 176 } 177 178 err := logoutRun(tt.opts) 179 if tt.wantErr != "" { 180 assert.EqualError(t, err, tt.wantErr) 181 return 182 } else { 183 assert.NoError(t, err) 184 } 185 186 if tt.wantErrOut == nil { 187 assert.Equal(t, "", stderr.String()) 188 } else { 189 assert.True(t, tt.wantErrOut.MatchString(stderr.String())) 190 } 191 192 assert.Equal(t, tt.wantHosts, hostsBuf.String()) 193 reg.Verify(t) 194 }) 195 } 196 } 197 198 func Test_logoutRun_nontty(t *testing.T) { 199 tests := []struct { 200 name string 201 opts *LogoutOptions 202 cfgHosts []string 203 wantHosts string 204 wantErr string 205 ghtoken string 206 }{ 207 { 208 name: "hostname, one host", 209 opts: &LogoutOptions{ 210 Hostname: "harry.mason", 211 }, 212 cfgHosts: []string{"harry.mason"}, 213 }, 214 { 215 name: "hostname, multiple hosts", 216 opts: &LogoutOptions{ 217 Hostname: "harry.mason", 218 }, 219 cfgHosts: []string{"harry.mason", "cheryl.mason"}, 220 wantHosts: "cheryl.mason:\n oauth_token: abc123\n", 221 }, 222 { 223 name: "hostname, no hosts", 224 opts: &LogoutOptions{ 225 Hostname: "harry.mason", 226 }, 227 wantErr: `not logged in to any hosts`, 228 }, 229 } 230 231 for _, tt := range tests { 232 t.Run(tt.name, func(t *testing.T) { 233 io, _, _, stderr := iostreams.Test() 234 235 io.SetStdinTTY(false) 236 io.SetStdoutTTY(false) 237 238 tt.opts.IO = io 239 cfg := config.NewBlankConfig() 240 tt.opts.Config = func() (config.Config, error) { 241 return cfg, nil 242 } 243 244 for _, hostname := range tt.cfgHosts { 245 _ = cfg.Set(hostname, "oauth_token", "abc123") 246 } 247 248 reg := &httpmock.Registry{} 249 tt.opts.HttpClient = func() (*http.Client, error) { 250 return &http.Client{Transport: reg}, nil 251 } 252 253 mainBuf := bytes.Buffer{} 254 hostsBuf := bytes.Buffer{} 255 defer config.StubWriteConfig(&mainBuf, &hostsBuf)() 256 257 err := logoutRun(tt.opts) 258 if tt.wantErr != "" { 259 assert.EqualError(t, err, tt.wantErr) 260 } else { 261 assert.NoError(t, err) 262 } 263 264 assert.Equal(t, "", stderr.String()) 265 266 assert.Equal(t, tt.wantHosts, hostsBuf.String()) 267 reg.Verify(t) 268 }) 269 } 270 }