diff --git a/client.go b/client.go index 499d3f9..fb5e288 100644 --- a/client.go +++ b/client.go @@ -150,6 +150,15 @@ func (c *Client) UserAgent() string { return c.userAgent } +// HTTPClient returns the configured underlying HTTP client. +// +// Usage: +// +// hc := client.HTTPClient() +func (c *Client) HTTPClient() *http.Client { + return c.httpClient +} + // HasToken reports whether the client was configured with an API token. // // Usage: diff --git a/client_test.go b/client_test.go index 7edb888..fbae590 100644 --- a/client_test.go +++ b/client_test.go @@ -220,6 +220,9 @@ func TestClient_WithHTTPClient_Good(t *testing.T) { if c.httpClient != custom { t.Error("expected custom HTTP client to be set") } + if got := c.HTTPClient(); got != custom { + t.Error("expected HTTPClient() to return the configured HTTP client") + } } func TestAPIError_Error_Good(t *testing.T) { diff --git a/docs/api-contract.md b/docs/api-contract.md index e898e9f..0f56abc 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -94,6 +94,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r | method | Client.Get | `func (c *Client) Get(ctx context.Context, path string, out any) error` | Get performs a GET request. | `TestClient_Bad_Forbidden`, `TestClient_Bad_NotFound`, `TestClient_Bad_ServerError` (+3 more) | | method | Client.GetRaw | `func (c *Client) GetRaw(ctx context.Context, path string) ([]byte, error)` | GetRaw performs a GET request and returns the raw response body as bytes instead of JSON-decoding. Useful for endpoints that return raw file content. | No direct tests. | | method | Client.HasToken | `func (c *Client) HasToken() bool` | HasToken reports whether the client was configured with an API token. | `TestClient_HasToken_Bad`, `TestClient_HasToken_Good` | +| method | Client.HTTPClient | `func (c *Client) HTTPClient() *http.Client` | HTTPClient returns the configured underlying HTTP client. | `TestClient_Good_WithHTTPClient` | | method | Client.Patch | `func (c *Client) Patch(ctx context.Context, path string, body, out any) error` | Patch performs a PATCH request. | No direct tests. | | method | Client.Post | `func (c *Client) Post(ctx context.Context, path string, body, out any) error` | Post performs a POST request. | `TestClient_Bad_Conflict`, `TestClient_Good_Post` | | method | Client.PostRaw | `func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, error)` | PostRaw performs a POST request with a JSON body and returns the raw response body as bytes instead of JSON-decoding. Useful for endpoints such as /markdown that return raw HTML text. | No direct tests. | @@ -115,6 +116,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r | method | ContentService.UpdateFile | `func (s *ContentService) UpdateFile(ctx context.Context, owner, repo, filepath string, opts *types.UpdateFileOptions) (*types.FileResponse, error)` | UpdateFile updates an existing file in a repository. | `TestContentService_Good_UpdateFile` | | method | Forge.Client | `func (f *Forge) Client() *Client` | Client returns the underlying HTTP client. | `TestForge_Good_Client` | | method | Forge.HasToken | `func (f *Forge) HasToken() bool` | HasToken reports whether the Forge client was configured with an API token. | `TestForge_HasToken_Bad`, `TestForge_HasToken_Good` | +| method | Forge.HTTPClient | `func (f *Forge) HTTPClient() *http.Client` | HTTPClient returns the configured underlying HTTP client. | `TestForge_HTTPClient_Good` | | method | Forge.RateLimit | `func (f *Forge) RateLimit() RateLimit` | RateLimit returns the last known rate limit information. | `TestForge_Good_RateLimit` | | method | Forge.UserAgent | `func (f *Forge) UserAgent() string` | UserAgent returns the configured User-Agent header value. | `TestForge_Good_UserAgent` | | method | IssueService.AddLabels | `func (s *IssueService) AddLabels(ctx context.Context, owner, repo string, index int64, labelIDs []int64) error` | AddLabels adds labels to an issue. | No direct tests. | diff --git a/docs/architecture.md b/docs/architecture.md index 557820c..ee9c270 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -49,6 +49,7 @@ func (c *Client) Delete(ctx context.Context, path string) error func (c *Client) DeleteWithBody(ctx context.Context, path string, body any) error func (c *Client) GetRaw(ctx context.Context, path string) ([]byte, error) func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, error) +func (c *Client) HTTPClient() *http.Client ``` The `Raw` variants return the response body as `[]byte` instead of decoding JSON. This is used by endpoints that return non-JSON content (e.g. the markdown rendering endpoint returns raw HTML). diff --git a/forge.go b/forge.go index 6e9f9b8..c3a3e34 100644 --- a/forge.go +++ b/forge.go @@ -1,5 +1,7 @@ package forge +import "net/http" + // Forge is the top-level client for the Forgejo API. // // Usage: @@ -93,6 +95,13 @@ func (f *Forge) RateLimit() RateLimit { return f.client.RateLimit() } // ua := f.UserAgent() func (f *Forge) UserAgent() string { return f.client.UserAgent() } +// HTTPClient returns the configured underlying HTTP client. +// +// Usage: +// +// hc := f.HTTPClient() +func (f *Forge) HTTPClient() *http.Client { return f.client.HTTPClient() } + // HasToken reports whether the Forge client was configured with an API token. // // Usage: diff --git a/forge_test.go b/forge_test.go index d25b155..89968c7 100644 --- a/forge_test.go +++ b/forge_test.go @@ -59,6 +59,14 @@ func TestForge_UserAgent_Good(t *testing.T) { } } +func TestForge_HTTPClient_Good(t *testing.T) { + custom := &http.Client{} + f := NewForge("https://forge.lthn.ai", "tok", WithHTTPClient(custom)) + if got := f.HTTPClient(); got != custom { + t.Fatal("expected HTTPClient() to return the configured HTTP client") + } +} + func TestForge_HasToken_Good(t *testing.T) { f := NewForge("https://forge.lthn.ai", "tok") if !f.HasToken() {