Skip to content

Commit 7779786

Browse files
authored
Adding pagination to list codespaces
1 parent 3652307 commit 7779786

File tree

2 files changed

+85
-36
lines changed

2 files changed

+85
-36
lines changed

internal/codespaces/api/api.go

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -189,36 +189,54 @@ type CodespaceEnvironmentConnection struct {
189189

190190
// ListCodespaces returns a list of codespaces for the user.
191191
func (a *API) ListCodespaces(ctx context.Context) ([]*Codespace, error) {
192-
req, err := http.NewRequest(
193-
http.MethodGet, a.githubAPI+"/user/codespaces", nil,
194-
)
195-
if err != nil {
196-
return nil, fmt.Errorf("error creating request: %w", err)
197-
}
192+
page := 1
193+
per_page := 50
194+
codespaces := []*Codespace{}
198195

199-
a.setHeaders(req)
200-
resp, err := a.do(ctx, req, "/user/codespaces")
201-
if err != nil {
202-
return nil, fmt.Errorf("error making request: %w", err)
203-
}
204-
defer resp.Body.Close()
196+
for {
197+
req, err := http.NewRequest(
198+
http.MethodGet, a.githubAPI+"/user/codespaces", nil,
199+
)
200+
if err != nil {
201+
return nil, fmt.Errorf("error creating request: %w", err)
202+
}
203+
a.setHeaders(req)
204+
q := req.URL.Query()
205+
q.Add("page", strconv.Itoa(page))
206+
q.Add("per_page", strconv.Itoa(per_page))
205207

206-
b, err := ioutil.ReadAll(resp.Body)
207-
if err != nil {
208-
return nil, fmt.Errorf("error reading response body: %w", err)
209-
}
208+
req.URL.RawQuery = q.Encode()
209+
resp, err := a.do(ctx, req, "/user/codespaces")
210+
if err != nil {
211+
return nil, fmt.Errorf("error making request: %w", err)
212+
}
213+
defer resp.Body.Close()
210214

211-
if resp.StatusCode != http.StatusOK {
212-
return nil, jsonErrorResponse(b)
213-
}
215+
b, err := ioutil.ReadAll(resp.Body)
216+
if err != nil {
217+
return nil, fmt.Errorf("error reading response body: %w", err)
218+
}
214219

215-
var response struct {
216-
Codespaces []*Codespace `json:"codespaces"`
217-
}
218-
if err := json.Unmarshal(b, &response); err != nil {
219-
return nil, fmt.Errorf("error unmarshaling response: %w", err)
220+
if resp.StatusCode != http.StatusOK {
221+
return nil, jsonErrorResponse(b)
222+
}
223+
224+
var response struct {
225+
Codespaces []*Codespace `json:"codespaces"`
226+
}
227+
if err := json.Unmarshal(b, &response); err != nil {
228+
return nil, fmt.Errorf("error unmarshaling response: %w", err)
229+
}
230+
231+
if len(response.Codespaces) > 0 {
232+
codespaces = append(codespaces, response.Codespaces...)
233+
page++
234+
} else {
235+
break
236+
}
220237
}
221-
return response.Codespaces, nil
238+
239+
return codespaces, nil
222240
}
223241

224242
// getCodespaceTokenRequest is the request body for the get codespace token endpoint.

internal/codespaces/api/api_test.go

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,50 @@ import (
66
"fmt"
77
"net/http"
88
"net/http/httptest"
9+
"strconv"
910
"testing"
1011
)
1112

12-
func TestListCodespaces(t *testing.T) {
13-
codespaces := []*Codespace{
14-
{
15-
Name: "testcodespace",
16-
CreatedAt: "2021-08-09T10:10:24+02:00",
17-
LastUsedAt: "2021-08-09T13:10:24+02:00",
18-
},
13+
func generateCodespaceList(start int, end int) []*Codespace {
14+
codespacesList := []*Codespace{}
15+
for i := start; i < end; i++ {
16+
codespacesList = append(codespacesList, &Codespace{
17+
Name: fmt.Sprintf("codespace-%d", i),
18+
})
1919
}
20+
return codespacesList
21+
}
22+
23+
func TestListCodespaces(t *testing.T) {
24+
2025
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
26+
if r.URL.Path != "/user/codespaces" {
27+
t.Fatal("Incorrect path")
28+
}
29+
30+
page := 1
31+
if r.URL.Query().Has("page") {
32+
page, _ = strconv.Atoi(r.URL.Query()["page"][0])
33+
}
34+
35+
per_page := 0
36+
if r.URL.Query().Has("per_page") {
37+
per_page, _ = strconv.Atoi(r.URL.Query()["per_page"][0])
38+
}
39+
40+
codespaces := []*Codespace{}
41+
if page == 1 {
42+
codespaces = generateCodespaceList(0, per_page)
43+
} else if page == 2 {
44+
codespaces = generateCodespaceList(per_page, per_page*2)
45+
}
46+
2147
response := struct {
2248
Codespaces []*Codespace `json:"codespaces"`
49+
TotalCount int `json:"total_count"`
2350
}{
2451
Codespaces: codespaces,
52+
TotalCount: 100,
2553
}
2654
data, _ := json.Marshal(response)
2755
fmt.Fprint(w, string(data))
@@ -38,13 +66,16 @@ func TestListCodespaces(t *testing.T) {
3866
if err != nil {
3967
t.Fatal(err)
4068
}
69+
if len(codespaces) != 100 {
70+
t.Fatalf("expected 100 codespace, got %d", len(codespaces))
71+
}
4172

42-
if len(codespaces) != 1 {
43-
t.Fatalf("expected 1 codespace, got %d", len(codespaces))
73+
if codespaces[0].Name != "codespace-0" {
74+
t.Fatalf("expected codespace-0, got %s", codespaces[0].Name)
4475
}
4576

46-
if codespaces[0].Name != "testcodespace" {
47-
t.Fatalf("expected testcodespace, got %s", codespaces[0].Name)
77+
if codespaces[99].Name != "codespace-99" {
78+
t.Fatalf("expected codespace-99, got %s", codespaces[0].Name)
4879
}
4980

5081
}

0 commit comments

Comments
 (0)