Add PipelineListsOptions to woodpecker-go

This commit is contained in:
Robert Kaussow 2024-04-26 21:32:00 +02:00
parent faf6b33140
commit 27f1cd30f1
No known key found for this signature in database
GPG key ID: 4E692A2EAECC03C0
7 changed files with 189 additions and 7 deletions

View file

@ -78,7 +78,7 @@ func deploy(c *cli.Context) error {
var number int64
if pipelineArg == "last" {
// Fetch the pipeline number from the last pipeline
pipelines, berr := client.PipelineList(repoID)
pipelines, berr := client.PipelineList(repoID, woodpecker.PipelineListsOptions{})
if berr != nil {
return berr
}

View file

@ -70,7 +70,7 @@ func pipelineList(c *cli.Context, client woodpecker.Client) ([]woodpecker.Pipeli
return resources, err
}
pipelines, err := client.PipelineList(repoID)
pipelines, err := client.PipelineList(repoID, woodpecker.PipelineListsOptions{})
if err != nil {
return resources, err
}

View file

@ -87,7 +87,7 @@ type Client interface {
// PipelineList returns a list of recent pipelines for the
// the specified repository.
PipelineList(repoID int64) ([]*Pipeline, error)
PipelineList(repoID int64, opt PipelineListsOptions) ([]*Pipeline, error)
// PipelineQueue returns a list of enqueued pipelines.
PipelineQueue() ([]*Feed, error)

View file

@ -0,0 +1,25 @@
package woodpecker
import (
"fmt"
"net/url"
)
// ListOptions represents the options for the Woodpecker API pagination.
type ListOptions struct {
Page int
PerPage int
}
// getURLQuery returns the query string for the ListOptions.
func (o ListOptions) getURLQuery() url.Values {
query := make(url.Values)
if o.Page > 0 {
query.Add("page", fmt.Sprintf("%d", o.Page))
}
if o.PerPage > 0 {
query.Add("perPage", fmt.Sprintf("%d", o.PerPage))
}
return query
}

View file

@ -0,0 +1,44 @@
package woodpecker
import (
"net/url"
"testing"
"github.com/stretchr/testify/assert"
)
func TestListOptions_getURLQuery(t *testing.T) {
tests := []struct {
name string
opts ListOptions
expected url.Values
}{
{
name: "no options",
opts: ListOptions{},
expected: url.Values{},
},
{
name: "with page",
opts: ListOptions{Page: 2},
expected: url.Values{"page": {"2"}},
},
{
name: "with per page",
opts: ListOptions{PerPage: 10},
expected: url.Values{"perPage": {"10"}},
},
{
name: "with page and per page",
opts: ListOptions{Page: 3, PerPage: 20},
expected: url.Values{"page": {"3"}, "perPage": {"20"}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := tt.opts.getURLQuery()
assert.Equal(t, tt.expected, actual)
})
}
}

View file

@ -1,6 +1,10 @@
package woodpecker
import "fmt"
import (
"fmt"
"net/url"
"time"
)
const (
pathRepoPost = "%s/api/repos?forge_remote_id=%d"
@ -24,6 +28,24 @@ const (
pathRepoCron = "%s/api/repos/%d/cron/%d"
)
type PipelineListsOptions struct {
ListOptions
Before time.Time
After time.Time
}
// QueryEncode returns the URL query parameters for the PipelineListsOptions.
func (opt *PipelineListsOptions) QueryEncode() string {
query := opt.getURLQuery()
if !opt.Before.IsZero() {
query.Add("before", opt.Before.Format(time.RFC3339))
}
if !opt.After.IsZero() {
query.Add("after", opt.After.Format(time.RFC3339))
}
return query.Encode()
}
// Repo returns a repository by id.
func (c *client) Repo(repoID int64) (*Repo, error) {
out := new(Repo)
@ -215,10 +237,13 @@ func (c *client) PipelineLast(repoID int64, branch string) (*Pipeline, error) {
// PipelineList returns a list of recent pipelines for the
// the specified repository.
func (c *client) PipelineList(repoID int64) ([]*Pipeline, error) {
func (c *client) PipelineList(repoID int64, opt PipelineListsOptions) ([]*Pipeline, error) {
var out []*Pipeline
uri := fmt.Sprintf(pathPipelines, c.addr, repoID)
err := c.get(uri, &out)
uri, _ := url.Parse(fmt.Sprintf(pathPipelines, c.addr, repoID))
uri.RawQuery = opt.QueryEncode()
err := c.get(uri.String(), &out)
return out, err
}

View file

@ -0,0 +1,88 @@
package woodpecker
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestPipelineList(t *testing.T) {
tests := []struct {
name string
fixtureHandler http.HandlerFunc
opts PipelineListsOptions
wantErr bool
expectedLength int
expectedIDs []int64
}{
{
name: "success",
fixtureHandler: func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "/api/repos/123/pipelines?after=2023-01-15T00%3A00%3A00Z&before=2023-01-16T00%3A00%3A00Z&page=2&perPage=10", r.URL.RequestURI())
w.WriteHeader(http.StatusOK)
_, err := fmt.Fprint(w, `[{"id":1},{"id":2}]`)
assert.NoError(t, err)
},
opts: PipelineListsOptions{
ListOptions: ListOptions{
Page: 2,
PerPage: 10,
},
Before: time.Date(2023, 1, 16, 0, 0, 0, 0, time.UTC),
After: time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
},
expectedLength: 2,
expectedIDs: []int64{1, 2},
},
{
name: "empty ListOptions",
fixtureHandler: func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "/api/repos/123/pipelines", r.URL.RequestURI())
w.WriteHeader(http.StatusOK)
_, err := fmt.Fprint(w, `[{"id":1},{"id":2}]`)
assert.NoError(t, err)
},
opts: PipelineListsOptions{},
expectedLength: 2,
expectedIDs: []int64{1, 2},
},
{
name: "error",
fixtureHandler: func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
},
opts: PipelineListsOptions{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ts := httptest.NewServer(tt.fixtureHandler)
defer ts.Close()
client := NewClient(ts.URL, http.DefaultClient)
pipelines, err := client.PipelineList(123, tt.opts)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, pipelines)
return
}
assert.NoError(t, err)
assert.Len(t, pipelines, tt.expectedLength)
for i, id := range tt.expectedIDs {
assert.Equal(t, id, pipelines[i].ID)
}
})
}
}