diff --git a/client.go b/client.go index e3c2230..499d3f9 100644 --- a/client.go +++ b/client.go @@ -150,6 +150,17 @@ func (c *Client) UserAgent() string { return c.userAgent } +// HasToken reports whether the client was configured with an API token. +// +// Usage: +// +// if c.HasToken() { +// _ = "authenticated" +// } +func (c *Client) HasToken() bool { + return c.token != "" +} + // NewClient creates a new Forgejo API client. // // Usage: diff --git a/client_test.go b/client_test.go index 1f3b6e3..7edb888 100644 --- a/client_test.go +++ b/client_test.go @@ -200,6 +200,20 @@ func TestClient_Options_Good(t *testing.T) { } } +func TestClient_HasToken_Good(t *testing.T) { + c := NewClient("https://forge.lthn.ai", "tok") + if !c.HasToken() { + t.Fatal("expected HasToken to report configured token") + } +} + +func TestClient_HasToken_Bad(t *testing.T) { + c := NewClient("https://forge.lthn.ai", "") + if c.HasToken() { + t.Fatal("expected HasToken to report missing token") + } +} + func TestClient_WithHTTPClient_Good(t *testing.T) { custom := &http.Client{} c := NewClient("https://forge.lthn.ai", "tok", WithHTTPClient(custom)) diff --git a/docs/api-contract.md b/docs/api-contract.md index c135ef0..e898e9f 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -93,6 +93,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r | method | Client.DeleteWithBody | `func (c *Client) DeleteWithBody(ctx context.Context, path string, body any) error` | DeleteWithBody performs a DELETE request with a JSON body. | No direct tests. | | 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.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. | @@ -113,6 +114,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r | method | ContentService.GetRawFile | `func (s *ContentService) GetRawFile(ctx context.Context, owner, repo, filepath string) ([]byte, error)` | GetRawFile returns the raw file content as bytes. | `TestContentService_Bad_GetRawNotFound`, `TestContentService_Good_GetRawFile` | | 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.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/forge.go b/forge.go index f8ca6be..6e9f9b8 100644 --- a/forge.go +++ b/forge.go @@ -92,3 +92,12 @@ func (f *Forge) RateLimit() RateLimit { return f.client.RateLimit() } // // ua := f.UserAgent() func (f *Forge) UserAgent() string { return f.client.UserAgent() } + +// HasToken reports whether the Forge client was configured with an API token. +// +// Usage: +// +// if f.HasToken() { +// _ = "authenticated" +// } +func (f *Forge) HasToken() bool { return f.client.HasToken() } diff --git a/forge_test.go b/forge_test.go index f47bac9..d25b155 100644 --- a/forge_test.go +++ b/forge_test.go @@ -59,6 +59,20 @@ func TestForge_UserAgent_Good(t *testing.T) { } } +func TestForge_HasToken_Good(t *testing.T) { + f := NewForge("https://forge.lthn.ai", "tok") + if !f.HasToken() { + t.Fatal("expected HasToken to report configured token") + } +} + +func TestForge_HasToken_Bad(t *testing.T) { + f := NewForge("https://forge.lthn.ai", "") + if f.HasToken() { + t.Fatal("expected HasToken to report missing token") + } +} + func TestRepoService_ListOrgRepos_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet {