github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/cmd/repo/list/list_test.go (about) 1 package list 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 "testing" 8 "time" 9 10 "github.com/MakeNowJust/heredoc" 11 "github.com/cli/cli/internal/config" 12 "github.com/cli/cli/pkg/cmdutil" 13 "github.com/cli/cli/pkg/httpmock" 14 "github.com/cli/cli/pkg/iostreams" 15 "github.com/cli/cli/test" 16 "github.com/google/shlex" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func TestNewCmdList(t *testing.T) { 22 tests := []struct { 23 name string 24 cli string 25 wants ListOptions 26 wantsErr string 27 }{ 28 { 29 name: "no arguments", 30 cli: "", 31 wants: ListOptions{ 32 Limit: 30, 33 Owner: "", 34 Visibility: "", 35 Fork: false, 36 Source: false, 37 Language: "", 38 Topic: "", 39 Archived: false, 40 NonArchived: false, 41 }, 42 }, 43 { 44 name: "with owner", 45 cli: "monalisa", 46 wants: ListOptions{ 47 Limit: 30, 48 Owner: "monalisa", 49 Visibility: "", 50 Fork: false, 51 Source: false, 52 Language: "", 53 Topic: "", 54 Archived: false, 55 NonArchived: false, 56 }, 57 }, 58 { 59 name: "with limit", 60 cli: "-L 101", 61 wants: ListOptions{ 62 Limit: 101, 63 Owner: "", 64 Visibility: "", 65 Fork: false, 66 Source: false, 67 Language: "", 68 Topic: "", 69 Archived: false, 70 NonArchived: false, 71 }, 72 }, 73 { 74 name: "only public", 75 cli: "--public", 76 wants: ListOptions{ 77 Limit: 30, 78 Owner: "", 79 Visibility: "public", 80 Fork: false, 81 Source: false, 82 Language: "", 83 Topic: "", 84 Archived: false, 85 NonArchived: false, 86 }, 87 }, 88 { 89 name: "only private", 90 cli: "--private", 91 wants: ListOptions{ 92 Limit: 30, 93 Owner: "", 94 Visibility: "private", 95 Fork: false, 96 Source: false, 97 Language: "", 98 Topic: "", 99 Archived: false, 100 NonArchived: false, 101 }, 102 }, 103 { 104 name: "only forks", 105 cli: "--fork", 106 wants: ListOptions{ 107 Limit: 30, 108 Owner: "", 109 Visibility: "", 110 Fork: true, 111 Source: false, 112 Language: "", 113 Topic: "", 114 Archived: false, 115 NonArchived: false, 116 }, 117 }, 118 { 119 name: "only sources", 120 cli: "--source", 121 wants: ListOptions{ 122 Limit: 30, 123 Owner: "", 124 Visibility: "", 125 Fork: false, 126 Source: true, 127 Language: "", 128 Topic: "", 129 Archived: false, 130 NonArchived: false, 131 }, 132 }, 133 { 134 name: "with language", 135 cli: "-l go", 136 wants: ListOptions{ 137 Limit: 30, 138 Owner: "", 139 Visibility: "", 140 Fork: false, 141 Source: false, 142 Language: "go", 143 Topic: "", 144 Archived: false, 145 NonArchived: false, 146 }, 147 }, 148 { 149 name: "only archived", 150 cli: "--archived", 151 wants: ListOptions{ 152 Limit: 30, 153 Owner: "", 154 Visibility: "", 155 Fork: false, 156 Source: false, 157 Language: "", 158 Topic: "", 159 Archived: true, 160 NonArchived: false, 161 }, 162 }, 163 { 164 name: "only non-archived", 165 cli: "--no-archived", 166 wants: ListOptions{ 167 Limit: 30, 168 Owner: "", 169 Visibility: "", 170 Fork: false, 171 Source: false, 172 Language: "", 173 Topic: "", 174 Archived: false, 175 NonArchived: true, 176 }, 177 }, 178 { 179 name: "with topic", 180 cli: "--topic cli", 181 wants: ListOptions{ 182 Limit: 30, 183 Owner: "", 184 Visibility: "", 185 Fork: false, 186 Source: false, 187 Language: "", 188 Topic: "cli", 189 Archived: false, 190 NonArchived: false, 191 }, 192 }, 193 { 194 name: "no public and private", 195 cli: "--public --private", 196 wantsErr: "specify only one of `--public` or `--private`", 197 }, 198 { 199 name: "no forks with sources", 200 cli: "--fork --source", 201 wantsErr: "specify only one of `--source` or `--fork`", 202 }, 203 { 204 name: "conflicting archived", 205 cli: "--archived --no-archived", 206 wantsErr: "specify only one of `--archived` or `--no-archived`", 207 }, 208 { 209 name: "too many arguments", 210 cli: "monalisa hubot", 211 wantsErr: "accepts at most 1 arg(s), received 2", 212 }, 213 { 214 name: "invalid limit", 215 cli: "-L 0", 216 wantsErr: "invalid limit: 0", 217 }, 218 } 219 220 for _, tt := range tests { 221 t.Run(tt.name, func(t *testing.T) { 222 f := &cmdutil.Factory{} 223 224 argv, err := shlex.Split(tt.cli) 225 assert.NoError(t, err) 226 227 var gotOpts *ListOptions 228 cmd := NewCmdList(f, func(opts *ListOptions) error { 229 gotOpts = opts 230 return nil 231 }) 232 cmd.SetArgs(argv) 233 cmd.SetIn(&bytes.Buffer{}) 234 cmd.SetOut(&bytes.Buffer{}) 235 cmd.SetErr(&bytes.Buffer{}) 236 237 _, err = cmd.ExecuteC() 238 if tt.wantsErr != "" { 239 assert.EqualError(t, err, tt.wantsErr) 240 return 241 } 242 require.NoError(t, err) 243 244 assert.Equal(t, tt.wants.Limit, gotOpts.Limit) 245 assert.Equal(t, tt.wants.Owner, gotOpts.Owner) 246 assert.Equal(t, tt.wants.Visibility, gotOpts.Visibility) 247 assert.Equal(t, tt.wants.Fork, gotOpts.Fork) 248 assert.Equal(t, tt.wants.Topic, gotOpts.Topic) 249 assert.Equal(t, tt.wants.Source, gotOpts.Source) 250 assert.Equal(t, tt.wants.Archived, gotOpts.Archived) 251 assert.Equal(t, tt.wants.NonArchived, gotOpts.NonArchived) 252 }) 253 } 254 } 255 256 func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) { 257 io, _, stdout, stderr := iostreams.Test() 258 io.SetStdoutTTY(isTTY) 259 io.SetStdinTTY(isTTY) 260 io.SetStderrTTY(isTTY) 261 262 factory := &cmdutil.Factory{ 263 IOStreams: io, 264 HttpClient: func() (*http.Client, error) { 265 return &http.Client{Transport: rt}, nil 266 }, 267 Config: func() (config.Config, error) { 268 return config.NewBlankConfig(), nil 269 }, 270 } 271 272 cmd := NewCmdList(factory, nil) 273 274 argv, err := shlex.Split(cli) 275 if err != nil { 276 return nil, err 277 } 278 cmd.SetArgs(argv) 279 280 cmd.SetIn(&bytes.Buffer{}) 281 cmd.SetOut(ioutil.Discard) 282 cmd.SetErr(ioutil.Discard) 283 284 _, err = cmd.ExecuteC() 285 return &test.CmdOut{ 286 OutBuf: stdout, 287 ErrBuf: stderr, 288 }, err 289 } 290 291 func TestRepoList_nontty(t *testing.T) { 292 io, _, stdout, stderr := iostreams.Test() 293 io.SetStdoutTTY(false) 294 io.SetStdinTTY(false) 295 io.SetStderrTTY(false) 296 297 httpReg := &httpmock.Registry{} 298 defer httpReg.Verify(t) 299 300 httpReg.Register( 301 httpmock.GraphQL(`query RepositoryList\b`), 302 httpmock.FileResponse("./fixtures/repoList.json"), 303 ) 304 305 opts := ListOptions{ 306 IO: io, 307 HttpClient: func() (*http.Client, error) { 308 return &http.Client{Transport: httpReg}, nil 309 }, 310 Config: func() (config.Config, error) { 311 return config.NewBlankConfig(), nil 312 }, 313 Now: func() time.Time { 314 t, _ := time.Parse(time.RFC822, "19 Feb 21 15:00 UTC") 315 return t 316 }, 317 Limit: 30, 318 } 319 320 err := listRun(&opts) 321 assert.NoError(t, err) 322 323 assert.Equal(t, "", stderr.String()) 324 325 assert.Equal(t, heredoc.Doc(` 326 octocat/hello-world My first repository public 2021-02-19T06:34:58Z 327 octocat/cli GitHub CLI public, fork 2021-02-19T06:06:06Z 328 octocat/testing private 2021-02-11T22:32:05Z 329 `), stdout.String()) 330 } 331 332 func TestRepoList_tty(t *testing.T) { 333 io, _, stdout, stderr := iostreams.Test() 334 io.SetStdoutTTY(true) 335 io.SetStdinTTY(true) 336 io.SetStderrTTY(true) 337 338 httpReg := &httpmock.Registry{} 339 defer httpReg.Verify(t) 340 341 httpReg.Register( 342 httpmock.GraphQL(`query RepositoryList\b`), 343 httpmock.FileResponse("./fixtures/repoList.json"), 344 ) 345 346 opts := ListOptions{ 347 IO: io, 348 HttpClient: func() (*http.Client, error) { 349 return &http.Client{Transport: httpReg}, nil 350 }, 351 Config: func() (config.Config, error) { 352 return config.NewBlankConfig(), nil 353 }, 354 Now: func() time.Time { 355 t, _ := time.Parse(time.RFC822, "19 Feb 21 15:00 UTC") 356 return t 357 }, 358 Limit: 30, 359 } 360 361 err := listRun(&opts) 362 assert.NoError(t, err) 363 364 assert.Equal(t, "", stderr.String()) 365 366 assert.Equal(t, heredoc.Doc(` 367 368 Showing 3 of 3 repositories in @octocat 369 370 octocat/hello-world My first repository public 8h 371 octocat/cli GitHub CLI public, fork 8h 372 octocat/testing private 7d 373 `), stdout.String()) 374 } 375 376 func TestRepoList_filtering(t *testing.T) { 377 http := &httpmock.Registry{} 378 defer http.Verify(t) 379 380 http.Register( 381 httpmock.GraphQL(`query RepositoryList\b`), 382 httpmock.GraphQLQuery(`{}`, func(_ string, params map[string]interface{}) { 383 assert.Equal(t, "PRIVATE", params["privacy"]) 384 assert.Equal(t, float64(2), params["perPage"]) 385 }), 386 ) 387 388 output, err := runCommand(http, true, `--private --limit 2 `) 389 if err != nil { 390 t.Fatal(err) 391 } 392 393 assert.Equal(t, "", output.Stderr()) 394 assert.Equal(t, "\nNo results match your search\n\n", output.String()) 395 }