diff --git a/commits.go b/commits.go index 5f448a6..e257db9 100644 --- a/commits.go +++ b/commits.go @@ -50,7 +50,7 @@ func (s *CommitService) Get(ctx context.Context, params Params) (*types.Commit, // GetCombinedStatus returns the combined status for a given ref (branch, tag, or SHA). func (s *CommitService) GetCombinedStatus(ctx context.Context, owner, repo, ref string) (*types.CombinedStatus, error) { - path := escapePathSegments("/api/v1/repos", owner, repo, "statuses", ref) + path := escapePathSegments("/api/v1/repos", owner, repo, "commits", ref, "status") var out types.CombinedStatus if err := s.client.Get(ctx, path, &out); err != nil { return nil, err diff --git a/commits_test.go b/commits_test.go index 82043f8..e9491f9 100644 --- a/commits_test.go +++ b/commits_test.go @@ -204,7 +204,7 @@ func TestCommitService_Good_GetCombinedStatus(t *testing.T) { if r.Method != http.MethodGet { t.Errorf("expected GET, got %s", r.Method) } - if r.URL.Path != "/api/v1/repos/core/go-forge/statuses/main" { + if r.URL.Path != "/api/v1/repos/core/go-forge/commits/main/status" { t.Errorf("wrong path: %s", r.URL.Path) } json.NewEncoder(w).Encode(types.CombinedStatus{ diff --git a/path_escape_test.go b/path_escape_test.go index a8de45f..6e422cf 100644 --- a/path_escape_test.go +++ b/path_escape_test.go @@ -2,9 +2,12 @@ package forge import ( "context" + "encoding/json" "net/http" "net/http/httptest" "testing" + + "dappco.re/go/core/forge/types" ) func TestServicePathEscaping_Good(t *testing.T) { @@ -72,6 +75,16 @@ func TestServicePathEscaping_Good(t *testing.T) { return f.Branches.DeleteBranchProtection(ctx, "core/team", "go forge", "main/release") }, }, + { + name: "commits combined status", + method: http.MethodGet, + wantPath: "/api/v1/repos/core%2Fteam/go%20forge/commits/main%2Frelease/status", + body: `{"sha":"abc123","total_count":0,"statuses":[]}`, + call: func(ctx context.Context, f *Forge) error { + _, err := f.Commits.GetCombinedStatus(ctx, "core/team", "go forge", "main/release") + return err + }, + }, { name: "commits list statuses", method: http.MethodGet, @@ -255,3 +268,99 @@ func TestServicePathEscaping_Good(t *testing.T) { }) } } + +func TestServicePathEscaping_Good_RouterIntegration(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + pattern string + wantEscapedPath string + wantVars map[string]string + call func(context.Context, *Forge) error + handle func(*testing.T, http.ResponseWriter, *http.Request) + }{ + { + name: "commits combined status", + pattern: "GET /api/v1/repos/{owner}/{repo}/commits/{ref}/status", + wantEscapedPath: "/api/v1/repos/core%2Fteam/go%20forge/commits/main%2Frelease/status", + wantVars: map[string]string{ + "owner": "core/team", + "repo": "go forge", + "ref": "main/release", + }, + call: func(ctx context.Context, f *Forge) error { + _, err := f.Commits.GetCombinedStatus(ctx, "core/team", "go forge", "main/release") + return err + }, + handle: func(t *testing.T, w http.ResponseWriter, r *http.Request) { + if err := json.NewEncoder(w).Encode(types.CombinedStatus{ + SHA: "abc123", + TotalCount: 0, + Statuses: []*types.CommitStatus{}, + }); err != nil { + t.Fatalf("encode response: %v", err) + } + }, + }, + { + name: "contents raw file", + pattern: "GET /api/v1/repos/{owner}/{repo}/raw/{filepath}", + wantEscapedPath: "/api/v1/repos/core%2Fteam/go%20forge/raw/docs%2Fread%20me.md", + wantVars: map[string]string{ + "owner": "core/team", + "repo": "go forge", + "filepath": "docs/read me.md", + }, + call: func(ctx context.Context, f *Forge) error { + _, err := f.Contents.GetRawFile(ctx, "core/team", "go forge", "docs/read me.md") + return err + }, + handle: func(t *testing.T, w http.ResponseWriter, r *http.Request) { + if _, err := w.Write([]byte("raw data")); err != nil { + t.Fatalf("write response: %v", err) + } + }, + }, + { + name: "orgs add member", + pattern: "PUT /api/v1/orgs/{org}/members/{username}", + wantEscapedPath: "/api/v1/orgs/ops%2Fsec/members/alice%2Fbob", + wantVars: map[string]string{ + "org": "ops/sec", + "username": "alice/bob", + }, + call: func(ctx context.Context, f *Forge) error { + return f.Orgs.AddMember(ctx, "ops/sec", "alice/bob") + }, + handle: func(t *testing.T, w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNoContent) + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc(tc.pattern, func(w http.ResponseWriter, r *http.Request) { + if r.URL.EscapedPath() != tc.wantEscapedPath { + t.Errorf("wrong escaped path: %s", r.URL.EscapedPath()) + } + for name, want := range tc.wantVars { + if got := r.PathValue(name); got != want { + t.Errorf("got %s=%q, want %q", name, got, want) + } + } + tc.handle(t, w, r) + }) + + srv := httptest.NewServer(mux) + defer srv.Close() + + f := NewForge(srv.URL, "tok") + if err := tc.call(ctx, f); err != nil { + t.Fatal(err) + } + }) + } +}