github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/extension/browse/browse_test.go (about) 1 package browse 2 3 import ( 4 "encoding/base64" 5 "io" 6 "log" 7 "net/http" 8 "net/url" 9 "testing" 10 "time" 11 12 "github.com/ungtb10d/cli/v2/internal/config" 13 "github.com/ungtb10d/cli/v2/internal/ghrepo" 14 "github.com/ungtb10d/cli/v2/pkg/cmd/repo/view" 15 "github.com/ungtb10d/cli/v2/pkg/extensions" 16 "github.com/ungtb10d/cli/v2/pkg/httpmock" 17 "github.com/ungtb10d/cli/v2/pkg/search" 18 "github.com/rivo/tview" 19 "github.com/stretchr/testify/assert" 20 ) 21 22 func Test_getSelectedReadme(t *testing.T) { 23 reg := httpmock.Registry{} 24 defer reg.Verify(t) 25 26 content := base64.StdEncoding.EncodeToString([]byte("lol")) 27 28 reg.Register( 29 httpmock.REST("GET", "repos/cli/gh-cool/readme"), 30 httpmock.JSONResponse(view.RepoReadme{Content: content})) 31 32 client := &http.Client{Transport: ®} 33 34 rg := newReadmeGetter(client, time.Second) 35 opts := ExtBrowseOpts{ 36 Rg: rg, 37 } 38 readme := tview.NewTextView() 39 ui := uiRegistry{ 40 List: tview.NewList(), 41 } 42 extEntries := []extEntry{ 43 { 44 Name: "gh-cool", 45 FullName: "cli/gh-cool", 46 Installed: false, 47 Official: true, 48 description: "it's just cool ok", 49 }, 50 { 51 Name: "gh-screensaver", 52 FullName: "vilmibm/gh-screensaver", 53 Installed: true, 54 Official: false, 55 description: "animations in your terminal", 56 }, 57 } 58 el := newExtList(opts, ui, extEntries) 59 60 content, err := getSelectedReadme(opts, readme, el) 61 assert.NoError(t, err) 62 assert.Contains(t, content, "lol") 63 } 64 65 func Test_getExtensionRepos(t *testing.T) { 66 reg := httpmock.Registry{} 67 defer reg.Verify(t) 68 69 client := &http.Client{Transport: ®} 70 71 values := url.Values{ 72 "page": []string{"1"}, 73 "per_page": []string{"100"}, 74 "q": []string{"topic:gh-extension"}, 75 } 76 cfg := config.NewBlankConfig() 77 78 cfg.DefaultHostFunc = func() (string, string) { return "github.com", "" } 79 80 reg.Register( 81 httpmock.QueryMatcher("GET", "search/repositories", values), 82 httpmock.JSONResponse(search.RepositoriesResult{ 83 IncompleteResults: false, 84 Items: []search.Repository{ 85 { 86 FullName: "vilmibm/gh-screensaver", 87 Name: "gh-screensaver", 88 Description: "terminal animations", 89 Owner: search.User{ 90 Login: "vilmibm", 91 }, 92 }, 93 { 94 FullName: "cli/gh-cool", 95 Name: "gh-cool", 96 Description: "it's just cool ok", 97 Owner: search.User{ 98 Login: "cli", 99 }, 100 }, 101 { 102 FullName: "samcoe/gh-triage", 103 Name: "gh-triage", 104 Description: "helps with triage", 105 Owner: search.User{ 106 Login: "samcoe", 107 }, 108 }, 109 { 110 FullName: "github/gh-gei", 111 Name: "gh-gei", 112 Description: "something something enterprise", 113 Owner: search.User{ 114 Login: "github", 115 }, 116 }, 117 }, 118 Total: 4, 119 }), 120 ) 121 122 searcher := search.NewSearcher(client, "github.com") 123 emMock := &extensions.ExtensionManagerMock{} 124 emMock.ListFunc = func() []extensions.Extension { 125 return []extensions.Extension{ 126 &extensions.ExtensionMock{ 127 URLFunc: func() string { 128 return "https://github.com/vilmibm/gh-screensaver" 129 }, 130 }, 131 &extensions.ExtensionMock{ 132 URLFunc: func() string { 133 return "https://github.com/github/gh-gei" 134 }, 135 }, 136 } 137 } 138 139 opts := ExtBrowseOpts{ 140 Searcher: searcher, 141 Em: emMock, 142 Cfg: cfg, 143 } 144 145 extEntries, err := getExtensions(opts) 146 assert.NoError(t, err) 147 148 expectedEntries := []extEntry{ 149 { 150 URL: "https://github.com/vilmibm/gh-screensaver", 151 Name: "gh-screensaver", 152 FullName: "vilmibm/gh-screensaver", 153 Installed: true, 154 Official: false, 155 description: "terminal animations", 156 }, 157 { 158 URL: "https://github.com/cli/gh-cool", 159 Name: "gh-cool", 160 FullName: "cli/gh-cool", 161 Installed: false, 162 Official: true, 163 description: "it's just cool ok", 164 }, 165 { 166 URL: "https://github.com/samcoe/gh-triage", 167 Name: "gh-triage", 168 FullName: "samcoe/gh-triage", 169 Installed: false, 170 Official: false, 171 description: "helps with triage", 172 }, 173 { 174 URL: "https://github.com/github/gh-gei", 175 Name: "gh-gei", 176 FullName: "github/gh-gei", 177 Installed: true, 178 Official: true, 179 description: "something something enterprise", 180 }, 181 } 182 183 assert.Equal(t, expectedEntries, extEntries) 184 } 185 186 func Test_extEntry(t *testing.T) { 187 cases := []struct { 188 name string 189 ee extEntry 190 expectedTitle string 191 expectedDesc string 192 }{ 193 { 194 name: "official", 195 ee: extEntry{ 196 Name: "gh-cool", 197 FullName: "cli/gh-cool", 198 Installed: false, 199 Official: true, 200 description: "it's just cool ok", 201 }, 202 expectedTitle: "cli/gh-cool [yellow](official)", 203 expectedDesc: "it's just cool ok", 204 }, 205 { 206 name: "no description", 207 ee: extEntry{ 208 Name: "gh-nodesc", 209 FullName: "barryburton/gh-nodesc", 210 Installed: false, 211 Official: false, 212 description: "", 213 }, 214 expectedTitle: "barryburton/gh-nodesc", 215 expectedDesc: "no description provided", 216 }, 217 { 218 name: "installed", 219 ee: extEntry{ 220 Name: "gh-screensaver", 221 FullName: "vilmibm/gh-screensaver", 222 Installed: true, 223 Official: false, 224 description: "animations in your terminal", 225 }, 226 expectedTitle: "vilmibm/gh-screensaver [green](installed)", 227 expectedDesc: "animations in your terminal", 228 }, 229 { 230 name: "neither", 231 ee: extEntry{ 232 Name: "gh-triage", 233 FullName: "samcoe/gh-triage", 234 Installed: false, 235 Official: false, 236 description: "help with triage", 237 }, 238 expectedTitle: "samcoe/gh-triage", 239 expectedDesc: "help with triage", 240 }, 241 { 242 name: "both", 243 ee: extEntry{ 244 Name: "gh-gei", 245 FullName: "github/gh-gei", 246 Installed: true, 247 Official: true, 248 description: "something something enterprise", 249 }, 250 expectedTitle: "github/gh-gei [yellow](official) [green](installed)", 251 expectedDesc: "something something enterprise", 252 }, 253 } 254 255 for _, tt := range cases { 256 t.Run(tt.name, func(t *testing.T) { 257 assert.Equal(t, tt.expectedTitle, tt.ee.Title()) 258 assert.Equal(t, tt.expectedDesc, tt.ee.Description()) 259 }) 260 } 261 } 262 263 func Test_extList(t *testing.T) { 264 opts := ExtBrowseOpts{ 265 Logger: log.New(io.Discard, "", 0), 266 Em: &extensions.ExtensionManagerMock{ 267 InstallFunc: func(repo ghrepo.Interface, _ string) error { 268 assert.Equal(t, "cli/gh-cool", ghrepo.FullName(repo)) 269 return nil 270 }, 271 RemoveFunc: func(name string) error { 272 assert.Equal(t, "cool", name) 273 return nil 274 }, 275 }, 276 } 277 app := tview.NewApplication() 278 list := tview.NewList() 279 ui := uiRegistry{ 280 List: list, 281 App: app, 282 } 283 extEntries := []extEntry{ 284 { 285 Name: "gh-cool", 286 FullName: "cli/gh-cool", 287 Installed: false, 288 Official: true, 289 description: "it's just cool ok", 290 }, 291 { 292 Name: "gh-screensaver", 293 FullName: "vilmibm/gh-screensaver", 294 Installed: true, 295 Official: false, 296 description: "animations in your terminal", 297 }, 298 { 299 Name: "gh-triage", 300 FullName: "samcoe/gh-triage", 301 Installed: false, 302 Official: false, 303 description: "help with triage", 304 }, 305 { 306 Name: "gh-gei", 307 FullName: "github/gh-gei", 308 Installed: true, 309 Official: true, 310 description: "something something enterprise", 311 }, 312 } 313 314 extList := newExtList(opts, ui, extEntries) 315 316 extList.Filter("cool") 317 assert.Equal(t, 1, extList.ui.List.GetItemCount()) 318 319 title, _ := extList.ui.List.GetItemText(0) 320 assert.Equal(t, "cli/gh-cool [yellow](official)", title) 321 322 extList.InstallSelected() 323 assert.True(t, extList.extEntries[0].Installed) 324 325 extList.Refresh() 326 assert.Equal(t, 1, extList.ui.List.GetItemCount()) 327 328 title, _ = extList.ui.List.GetItemText(0) 329 assert.Equal(t, "cli/gh-cool [yellow](official) [green](installed)", title) 330 331 extList.RemoveSelected() 332 assert.False(t, extList.extEntries[0].Installed) 333 334 extList.Refresh() 335 assert.Equal(t, 1, extList.ui.List.GetItemCount()) 336 337 title, _ = extList.ui.List.GetItemText(0) 338 assert.Equal(t, "cli/gh-cool [yellow](official)", title) 339 340 extList.Reset() 341 assert.Equal(t, 4, extList.ui.List.GetItemCount()) 342 343 ee, ix := extList.FindSelected() 344 assert.Equal(t, 0, ix) 345 assert.Equal(t, "cli/gh-cool [yellow](official)", ee.Title()) 346 347 extList.ScrollDown() 348 ee, ix = extList.FindSelected() 349 assert.Equal(t, 1, ix) 350 assert.Equal(t, "vilmibm/gh-screensaver [green](installed)", ee.Title()) 351 352 extList.ScrollUp() 353 ee, ix = extList.FindSelected() 354 assert.Equal(t, 0, ix) 355 assert.Equal(t, "cli/gh-cool [yellow](official)", ee.Title()) 356 357 extList.PageDown() 358 ee, ix = extList.FindSelected() 359 assert.Equal(t, 3, ix) 360 assert.Equal(t, "github/gh-gei [yellow](official) [green](installed)", ee.Title()) 361 362 extList.PageUp() 363 ee, ix = extList.FindSelected() 364 assert.Equal(t, 0, ix) 365 assert.Equal(t, "cli/gh-cool [yellow](official)", ee.Title()) 366 }