feat(forge): add repo webhook iterator
Some checks failed
Security Scan / security (push) Failing after 13s
Test / test (push) Successful in 2m27s

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 07:35:26 +00:00
parent 0193bd50ea
commit 94c5870c46
2 changed files with 67 additions and 0 deletions

View file

@ -3,6 +3,8 @@
package forge
import (
"iter"
forgejo "codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2"
"dappco.re/go/core/log"
@ -43,3 +45,29 @@ func (c *Client) ListRepoWebhooks(owner, repo string) ([]*forgejo.Hook, error) {
return all, nil
}
// ListRepoWebhooksIter returns an iterator over webhooks for a repository.
// Usage: ListRepoWebhooksIter(...)
func (c *Client) ListRepoWebhooksIter(owner, repo string) iter.Seq2[*forgejo.Hook, error] {
return func(yield func(*forgejo.Hook, error) bool) {
page := 1
for {
hooks, resp, err := c.api.ListRepoHooks(owner, repo, forgejo.ListHooksOptions{
ListOptions: forgejo.ListOptions{Page: page, PageSize: 50},
})
if err != nil {
yield(nil, log.E("forge.ListRepoWebhooks", "failed to list repo webhooks", err))
return
}
for _, hook := range hooks {
if !yield(hook, nil) {
return
}
}
if resp == nil || page >= resp.LastPage {
break
}
page++
}
}
}

View file

@ -3,6 +3,8 @@
package forge
import (
"net/http"
"net/http/httptest"
"testing"
forgejo "codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2"
@ -53,3 +55,40 @@ func TestClient_ListRepoWebhooks_Bad_ServerError_Good(t *testing.T) {
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to list repo webhooks")
}
func TestClient_ListRepoWebhooksIter_Good_Paginates_Good(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/api/v1/version", func(w http.ResponseWriter, r *http.Request) {
jsonResponse(w, map[string]string{"version": "1.21.0"})
})
mux.HandleFunc("/api/v1/repos/test-org/org-repo/hooks", func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Query().Get("page") {
case "2":
jsonResponse(w, []map[string]any{
{"id": 2, "type": "forgejo", "active": true, "config": map[string]any{"url": "https://example.com/second"}},
})
case "3":
jsonResponse(w, []map[string]any{})
default:
w.Header().Set("Link", "<http://"+r.Host+"/api/v1/repos/test-org/org-repo/hooks?page=2>; rel=\"next\", <http://"+r.Host+"/api/v1/repos/test-org/org-repo/hooks?page=2>; rel=\"last\"")
jsonResponse(w, []map[string]any{
{"id": 1, "type": "forgejo", "active": true, "config": map[string]any{"url": "https://example.com/hook"}},
})
}
})
srv := httptest.NewServer(mux)
defer srv.Close()
client, err := New(srv.URL, "test-token")
require.NoError(t, err)
var urls []string
for hook, err := range client.ListRepoWebhooksIter("test-org", "org-repo") {
require.NoError(t, err)
urls = append(urls, hook.Config["url"])
}
require.Len(t, urls, 2)
assert.Equal(t, []string{"https://example.com/hook", "https://example.com/second"}, urls)
}