From 932e128d2041d1d27d74061fdb1ade5aac484251 Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Sat, 27 Apr 2024 22:06:15 +0200 Subject: [PATCH] add RepoPostOptions --- cli/repo/repo_add.go | 7 ++- woodpecker-go/woodpecker/interface.go | 2 +- woodpecker-go/woodpecker/repo.go | 22 ++++++-- woodpecker-go/woodpecker/repo_test.go | 81 +++++++++++++++++++++++++-- 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/cli/repo/repo_add.go b/cli/repo/repo_add.go index 00094b40c..79f9c8450 100644 --- a/cli/repo/repo_add.go +++ b/cli/repo/repo_add.go @@ -21,6 +21,7 @@ import ( "github.com/urfave/cli/v2" "go.woodpecker-ci.org/woodpecker/v2/cli/internal" + "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" ) var repoAddCmd = &cli.Command{ @@ -42,7 +43,11 @@ func repoAdd(c *cli.Context) error { return err } - repo, err := client.RepoPost(int64(forgeRemoteID)) + opt := woodpecker.RepoPostOptions{ + ForgeRemoteID: int64(forgeRemoteID), + } + + repo, err := client.RepoPost(opt) if err != nil { return err } diff --git a/woodpecker-go/woodpecker/interface.go b/woodpecker-go/woodpecker/interface.go index c842a5f27..0ac1e890a 100644 --- a/woodpecker-go/woodpecker/interface.go +++ b/woodpecker-go/woodpecker/interface.go @@ -55,7 +55,7 @@ type Client interface { RepoList(opt RepoListOptions) ([]*Repo, error) // RepoPost activates a repository. - RepoPost(forgeRemoteID int64) (*Repo, error) + RepoPost(opt RepoPostOptions) (*Repo, error) // RepoPatch updates a repository. RepoPatch(repoID int64, repo *RepoPatch) (*Repo, error) diff --git a/woodpecker-go/woodpecker/repo.go b/woodpecker-go/woodpecker/repo.go index 276f60ac3..f19864759 100644 --- a/woodpecker-go/woodpecker/repo.go +++ b/woodpecker-go/woodpecker/repo.go @@ -3,11 +3,12 @@ package woodpecker import ( "fmt" "net/url" + "strconv" "time" ) const ( - pathRepoPost = "%s/api/repos?forge_remote_id=%d" + pathRepoPost = "%s/api/repos" pathRepo = "%s/api/repos/%d" pathRepoLookup = "%s/api/repos/lookup/%s" pathRepoMove = "%s/api/repos/%d/move?to=%s" @@ -47,6 +48,10 @@ type PipelineLastOptions struct { Branch string // last pipeline from given branch, an empty branch will result in the default branch } +type RepoPostOptions struct { + ForgeRemoteID int64 +} + // QueryEncode returns the URL query parameters for the PipelineListOptions. func (opt *PipelineListOptions) QueryEncode() string { query := opt.getURLQuery() @@ -84,6 +89,13 @@ func (opt *PipelineLastOptions) QueryEncode() string { return query.Encode() } +// QueryEncode returns the URL query parameters for the RepoPostOptions. +func (opt *RepoPostOptions) QueryEncode() string { + query := make(url.Values) + query.Add("forge_remote_id", strconv.FormatInt(opt.ForgeRemoteID, 10)) + return query.Encode() +} + // Repo returns a repository by id. func (c *client) Repo(repoID int64) (*Repo, error) { out := new(Repo) @@ -101,10 +113,12 @@ func (c *client) RepoLookup(fullName string) (*Repo, error) { } // RepoPost activates a repository. -func (c *client) RepoPost(forgeRemoteID int64) (*Repo, error) { +func (c *client) RepoPost(opt RepoPostOptions) (*Repo, error) { out := new(Repo) - uri := fmt.Sprintf(pathRepoPost, c.addr, forgeRemoteID) - err := c.post(uri, nil, out) + uri, _ := url.Parse(fmt.Sprintf(pathRepoPost, c.addr)) + uri.RawQuery = opt.QueryEncode() + fmt.Println("!!!!!!!!!!", uri.String()) + err := c.post(uri.String(), nil, out) return out, err } diff --git a/woodpecker-go/woodpecker/repo_test.go b/woodpecker-go/woodpecker/repo_test.go index c70680b04..a96df9f2a 100644 --- a/woodpecker-go/woodpecker/repo_test.go +++ b/woodpecker-go/woodpecker/repo_test.go @@ -246,7 +246,7 @@ func TestClient_PipelineLast(t *testing.T) { name string handler http.HandlerFunc repoID int64 - opt PipelineLastOptions + opts PipelineLastOptions expected *Pipeline wantErr bool }{ @@ -259,7 +259,7 @@ func TestClient_PipelineLast(t *testing.T) { assert.NoError(t, err) }, repoID: 1, - opt: PipelineLastOptions{Branch: "main"}, + opts: PipelineLastOptions{Branch: "main"}, expected: &Pipeline{ ID: 1, Number: 1, @@ -275,7 +275,7 @@ func TestClient_PipelineLast(t *testing.T) { w.WriteHeader(http.StatusInternalServerError) }, repoID: 1, - opt: PipelineLastOptions{}, + opts: PipelineLastOptions{}, expected: nil, wantErr: true, }, @@ -287,7 +287,7 @@ func TestClient_PipelineLast(t *testing.T) { assert.NoError(t, err) }, repoID: 1, - opt: PipelineLastOptions{}, + opts: PipelineLastOptions{}, expected: nil, wantErr: true, }, @@ -299,7 +299,7 @@ func TestClient_PipelineLast(t *testing.T) { defer ts.Close() client := NewClient(ts.URL, http.DefaultClient) - pipeline, err := client.PipelineLast(tt.repoID, tt.opt) + pipeline, err := client.PipelineLast(tt.repoID, tt.opts) if tt.wantErr { assert.Error(t, err) @@ -311,3 +311,74 @@ func TestClient_PipelineLast(t *testing.T) { }) } } + +func TestClientRepoPost(t *testing.T) { + tests := []struct { + name string + handler http.HandlerFunc + opts RepoPostOptions + expected *Repo + wantErr bool + }{ + { + name: "success", + handler: func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPost, r.Method) + assert.Equal(t, "/api/repos?forge_remote_id=10", r.URL.RequestURI()) + + w.WriteHeader(http.StatusOK) + _, err := fmt.Fprint(w, `{"id":1,"name":"test","owner":"owner","full_name":"owner/test","forge_remote_id":"10"}`) + assert.NoError(t, err) + }, + opts: RepoPostOptions{ + ForgeRemoteID: 10, + }, + expected: &Repo{ + ID: 1, + ForgeRemoteID: "10", + Name: "test", + Owner: "owner", + FullName: "owner/test", + }, + wantErr: false, + }, + { + name: "server error", + handler: func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + }, + opts: RepoPostOptions{}, + expected: nil, + wantErr: true, + }, + { + name: "invalid response", + handler: func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + _, err := fmt.Fprint(w, `invalid json`) + assert.NoError(t, err) + }, + opts: RepoPostOptions{}, + expected: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := httptest.NewServer(tt.handler) + defer ts.Close() + + client := NewClient(ts.URL, http.DefaultClient) + repo, err := client.RepoPost(tt.opts) + + if tt.wantErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, repo) + }) + } +}