fix(scm): paginate issue listings
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
6233664c5d
commit
8021e5e2cb
4 changed files with 127 additions and 19 deletions
|
|
@ -39,19 +39,32 @@ func (c *Client) ListIssues(owner, repo string, opts ListIssuesOpts) ([]*forgejo
|
|||
page = 1
|
||||
}
|
||||
|
||||
listOpt := forgejo.ListIssueOption{
|
||||
ListOptions: forgejo.ListOptions{Page: page, PageSize: limit},
|
||||
State: state,
|
||||
Type: forgejo.IssueTypeIssue,
|
||||
Labels: opts.Labels,
|
||||
var all []*forgejo.Issue
|
||||
|
||||
for {
|
||||
listOpt := forgejo.ListIssueOption{
|
||||
ListOptions: forgejo.ListOptions{Page: page, PageSize: limit},
|
||||
State: state,
|
||||
Type: forgejo.IssueTypeIssue,
|
||||
Labels: opts.Labels,
|
||||
}
|
||||
|
||||
issues, resp, err := c.api.ListRepoIssues(owner, repo, listOpt)
|
||||
if err != nil {
|
||||
return nil, log.E("forge.ListIssues", "failed to list issues", err)
|
||||
}
|
||||
|
||||
all = append(all, issues...)
|
||||
if len(issues) < limit || len(issues) == 0 {
|
||||
break
|
||||
}
|
||||
if resp != nil && resp.LastPage > 0 && page >= resp.LastPage {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
issues, _, err := c.api.ListRepoIssues(owner, repo, listOpt)
|
||||
if err != nil {
|
||||
return nil, log.E("forge.ListIssues", "failed to list issues", err)
|
||||
}
|
||||
|
||||
return issues, nil
|
||||
return all, nil
|
||||
}
|
||||
|
||||
// GetIssue returns a single issue by number.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
package forge
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
forgejo "codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2"
|
||||
|
|
@ -11,6 +13,34 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func newPaginatedIssuesClient(t *testing.T) (*Client, *httptest.Server) {
|
||||
t.Helper()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/v1/version", func(w http.ResponseWriter, r *http.Request) {
|
||||
jsonResponse(w, map[string]string{"version": "1.21.0"})
|
||||
})
|
||||
mux.HandleFunc("/api/v1/repos/test-org/org-repo/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Query().Get("page") {
|
||||
case "2":
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 2, "number": 2, "title": "Issue 2", "state": "open", "body": "Second issue"},
|
||||
})
|
||||
case "3":
|
||||
jsonResponse(w, []map[string]any{})
|
||||
default:
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 1, "number": 1, "title": "Issue 1", "state": "open", "body": "First issue"},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
srv := httptest.NewServer(mux)
|
||||
client, err := New(srv.URL, "test-token")
|
||||
require.NoError(t, err)
|
||||
return client, srv
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
|
@ -21,6 +51,17 @@ func TestClient_ListIssues_Good(t *testing.T) {
|
|||
assert.Equal(t, "Issue 1", issues[0].Title)
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good_Paginates_Good(t *testing.T) {
|
||||
client, srv := newPaginatedIssuesClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
issues, err := client.ListIssues("test-org", "org-repo", ListIssuesOpts{Limit: 1})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, issues, 2)
|
||||
assert.Equal(t, "Issue 1", issues[0].Title)
|
||||
assert.Equal(t, "Issue 2", issues[1].Title)
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good_StateMapping_Good(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -38,16 +38,29 @@ func (c *Client) ListIssues(owner, repo string, opts ListIssuesOpts) ([]*gitea.I
|
|||
page = 1
|
||||
}
|
||||
|
||||
issues, _, err := c.api.ListRepoIssues(owner, repo, gitea.ListIssueOption{
|
||||
ListOptions: gitea.ListOptions{Page: page, PageSize: limit},
|
||||
State: state,
|
||||
Type: gitea.IssueTypeIssue,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, log.E("gitea.ListIssues", "failed to list issues", err)
|
||||
var all []*gitea.Issue
|
||||
|
||||
for {
|
||||
issues, resp, err := c.api.ListRepoIssues(owner, repo, gitea.ListIssueOption{
|
||||
ListOptions: gitea.ListOptions{Page: page, PageSize: limit},
|
||||
State: state,
|
||||
Type: gitea.IssueTypeIssue,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, log.E("gitea.ListIssues", "failed to list issues", err)
|
||||
}
|
||||
|
||||
all = append(all, issues...)
|
||||
if len(issues) < limit || len(issues) == 0 {
|
||||
break
|
||||
}
|
||||
if resp != nil && resp.LastPage > 0 && page >= resp.LastPage {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
return issues, nil
|
||||
return all, nil
|
||||
}
|
||||
|
||||
// GetIssue returns a single issue by number.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
package gitea
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
giteaSDK "code.gitea.io/sdk/gitea"
|
||||
|
|
@ -11,6 +13,34 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func newPaginatedIssuesClient(t *testing.T) (*Client, *httptest.Server) {
|
||||
t.Helper()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/v1/version", func(w http.ResponseWriter, r *http.Request) {
|
||||
jsonResponse(w, map[string]string{"version": "1.21.0"})
|
||||
})
|
||||
mux.HandleFunc("/api/v1/repos/test-org/org-repo/issues", func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Query().Get("page") {
|
||||
case "2":
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 2, "number": 2, "title": "Issue 2", "state": "open", "body": "Second issue"},
|
||||
})
|
||||
case "3":
|
||||
jsonResponse(w, []map[string]any{})
|
||||
default:
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 1, "number": 1, "title": "Issue 1", "state": "open", "body": "First issue"},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
srv := httptest.NewServer(mux)
|
||||
client, err := New(srv.URL, "test-token")
|
||||
require.NoError(t, err)
|
||||
return client, srv
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
|
@ -21,6 +51,17 @@ func TestClient_ListIssues_Good(t *testing.T) {
|
|||
assert.Equal(t, "Issue 1", issues[0].Title)
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good_Paginates_Good(t *testing.T) {
|
||||
client, srv := newPaginatedIssuesClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
issues, err := client.ListIssues("test-org", "org-repo", ListIssuesOpts{Limit: 1})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, issues, 2)
|
||||
assert.Equal(t, "Issue 1", issues[0].Title)
|
||||
assert.Equal(t, "Issue 2", issues[1].Title)
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good_StateMapping_Good(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue