github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/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/ungtb10d/cli/v2/internal/config" 10 "github.com/ungtb10d/cli/v2/internal/prompter" 11 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 12 "github.com/ungtb10d/cli/v2/pkg/httpmock" 13 "github.com/ungtb10d/cli/v2/pkg/iostreams" 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: "nontty no arguments", 28 cli: "", 29 wantsErr: true, 30 }, 31 { 32 name: "tty no arguments", 33 tty: true, 34 cli: "", 35 wants: LogoutOptions{ 36 Hostname: "", 37 }, 38 }, 39 { 40 name: "tty with hostname", 41 tty: true, 42 cli: "--hostname harry.mason", 43 wants: LogoutOptions{ 44 Hostname: "harry.mason", 45 }, 46 }, 47 { 48 name: "nontty with hostname", 49 cli: "--hostname harry.mason", 50 wants: LogoutOptions{ 51 Hostname: "harry.mason", 52 }, 53 }, 54 } 55 for _, tt := range tests { 56 t.Run(tt.name, func(t *testing.T) { 57 ios, _, _, _ := iostreams.Test() 58 f := &cmdutil.Factory{ 59 IOStreams: ios, 60 } 61 ios.SetStdinTTY(tt.tty) 62 ios.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 prompterStubs func(*prompter.PrompterMock) 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 prompterStubs: func(pm *prompter.PrompterMock) { 109 pm.SelectFunc = func(_, _ string, opts []string) (int, error) { 110 return prompter.IndexFor(opts, "github.com") 111 } 112 }, 113 wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`), 114 }, 115 { 116 name: "no arguments, one host", 117 opts: &LogoutOptions{}, 118 cfgHosts: []string{"github.com"}, 119 wantHosts: "{}\n", 120 wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`), 121 }, 122 { 123 name: "no arguments, no hosts", 124 opts: &LogoutOptions{}, 125 wantErr: `not logged in to any hosts`, 126 }, 127 { 128 name: "hostname", 129 opts: &LogoutOptions{ 130 Hostname: "cheryl.mason", 131 }, 132 cfgHosts: []string{"cheryl.mason", "github.com"}, 133 wantHosts: "github.com:\n oauth_token: abc123\n", 134 wantErrOut: regexp.MustCompile(`Logged out of cheryl.mason account 'cybilb'`), 135 }, 136 } 137 138 for _, tt := range tests { 139 t.Run(tt.name, func(t *testing.T) { 140 readConfigs := config.StubWriteConfig(t) 141 cfg := config.NewFromString("") 142 for _, hostname := range tt.cfgHosts { 143 cfg.Set(hostname, "oauth_token", "abc123") 144 } 145 tt.opts.Config = func() (config.Config, error) { 146 return cfg, nil 147 } 148 149 ios, _, _, stderr := iostreams.Test() 150 ios.SetStdinTTY(true) 151 ios.SetStdoutTTY(true) 152 tt.opts.IO = ios 153 154 reg := &httpmock.Registry{} 155 reg.Register( 156 httpmock.GraphQL(`query UserCurrent\b`), 157 httpmock.StringResponse(`{"data":{"viewer":{"login":"cybilb"}}}`), 158 ) 159 tt.opts.HttpClient = func() (*http.Client, error) { 160 return &http.Client{Transport: reg}, nil 161 } 162 163 pm := &prompter.PrompterMock{} 164 if tt.prompterStubs != nil { 165 tt.prompterStubs(pm) 166 } 167 tt.opts.Prompter = pm 168 169 err := logoutRun(tt.opts) 170 if tt.wantErr != "" { 171 assert.EqualError(t, err, tt.wantErr) 172 return 173 } else { 174 assert.NoError(t, err) 175 } 176 177 if tt.wantErrOut == nil { 178 assert.Equal(t, "", stderr.String()) 179 } else { 180 assert.True(t, tt.wantErrOut.MatchString(stderr.String())) 181 } 182 183 mainBuf := bytes.Buffer{} 184 hostsBuf := bytes.Buffer{} 185 readConfigs(&mainBuf, &hostsBuf) 186 187 assert.Equal(t, tt.wantHosts, hostsBuf.String()) 188 reg.Verify(t) 189 }) 190 } 191 } 192 193 func Test_logoutRun_nontty(t *testing.T) { 194 tests := []struct { 195 name string 196 opts *LogoutOptions 197 cfgHosts []string 198 wantHosts string 199 wantErr string 200 ghtoken string 201 }{ 202 { 203 name: "hostname, one host", 204 opts: &LogoutOptions{ 205 Hostname: "harry.mason", 206 }, 207 cfgHosts: []string{"harry.mason"}, 208 wantHosts: "{}\n", 209 }, 210 { 211 name: "hostname, multiple hosts", 212 opts: &LogoutOptions{ 213 Hostname: "harry.mason", 214 }, 215 cfgHosts: []string{"harry.mason", "cheryl.mason"}, 216 wantHosts: "cheryl.mason:\n oauth_token: abc123\n", 217 }, 218 { 219 name: "hostname, no hosts", 220 opts: &LogoutOptions{ 221 Hostname: "harry.mason", 222 }, 223 wantErr: `not logged in to any hosts`, 224 }, 225 } 226 227 for _, tt := range tests { 228 t.Run(tt.name, func(t *testing.T) { 229 readConfigs := config.StubWriteConfig(t) 230 cfg := config.NewFromString("") 231 for _, hostname := range tt.cfgHosts { 232 cfg.Set(hostname, "oauth_token", "abc123") 233 } 234 tt.opts.Config = func() (config.Config, error) { 235 return cfg, nil 236 } 237 238 ios, _, _, stderr := iostreams.Test() 239 ios.SetStdinTTY(false) 240 ios.SetStdoutTTY(false) 241 tt.opts.IO = ios 242 243 reg := &httpmock.Registry{} 244 tt.opts.HttpClient = func() (*http.Client, error) { 245 return &http.Client{Transport: reg}, nil 246 } 247 248 err := logoutRun(tt.opts) 249 if tt.wantErr != "" { 250 assert.EqualError(t, err, tt.wantErr) 251 } else { 252 assert.NoError(t, err) 253 } 254 255 assert.Equal(t, "", stderr.String()) 256 257 mainBuf := bytes.Buffer{} 258 hostsBuf := bytes.Buffer{} 259 readConfigs(&mainBuf, &hostsBuf) 260 261 assert.Equal(t, tt.wantHosts, hostsBuf.String()) 262 reg.Verify(t) 263 }) 264 } 265 }