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