From 469a6d3466e82aca43ab5f1d76aa075395ccffc3 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 20 Apr 2026 12:19:36 -0700 Subject: [PATCH] Fix webhook --- cmd/webhooks/create.go | 28 ++++++------ cmd/webhooks/create_test.go | 62 ++++++++------------------- cmd/webhooks/update.go | 23 ++++++---- cmd/webhooks/update_test.go | 80 ++++++++++++++++++++++++----------- modules/print/webhook.go | 12 +++++- modules/print/webhook_test.go | 16 +++---- 6 files changed, 117 insertions(+), 104 deletions(-) diff --git a/cmd/webhooks/create.go b/cmd/webhooks/create.go index 57eb468..d669436 100644 --- a/cmd/webhooks/create.go +++ b/cmd/webhooks/create.go @@ -89,30 +89,26 @@ func runWebhooksCreate(ctx stdctx.Context, cmd *cli.Command) error { config["secret"] = secret } - if branchFilter != "" { - config["branch_filter"] = branchFilter - } - - if authHeader != "" { - config["authorization_header"] = authHeader - } - var hook *gitea.Hook if c.IsGlobal { return fmt.Errorf("global webhooks not yet supported in this version") } else if len(c.Org) > 0 { hook, _, err = client.CreateOrgHook(c.Org, gitea.CreateHookOption{ - Type: webhookType, - Config: config, - Events: events, - Active: active, + Type: webhookType, + Config: config, + Events: events, + Active: active, + BranchFilter: branchFilter, + AuthorizationHeader: authHeader, }) } else { hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{ - Type: webhookType, - Config: config, - Events: events, - Active: active, + Type: webhookType, + Config: config, + Events: events, + Active: active, + BranchFilter: branchFilter, + AuthorizationHeader: authHeader, }) } if err != nil { diff --git a/cmd/webhooks/create_test.go b/cmd/webhooks/create_test.go index c2ee9d2..10f8bde 100644 --- a/cmd/webhooks/create_test.go +++ b/cmd/webhooks/create_test.go @@ -79,8 +79,6 @@ func TestWebhookConfigConstruction(t *testing.T) { name string url string secret string - branchFilter string - authHeader string expectedKeys []string expectedValues map[string]string }{ @@ -106,44 +104,16 @@ func TestWebhookConfigConstruction(t *testing.T) { "secret": "my-secret", }, }, - { - name: "Config with branch filter", - url: "https://example.com/webhook", - branchFilter: "main,develop", - expectedKeys: []string{"url", "http_method", "content_type", "branch_filter"}, - expectedValues: map[string]string{ - "url": "https://example.com/webhook", - "http_method": "post", - "content_type": "json", - "branch_filter": "main,develop", - }, - }, - { - name: "Config with auth header", - url: "https://example.com/webhook", - authHeader: "Bearer token123", - expectedKeys: []string{"url", "http_method", "content_type", "authorization_header"}, - expectedValues: map[string]string{ - "url": "https://example.com/webhook", - "http_method": "post", - "content_type": "json", - "authorization_header": "Bearer token123", - }, - }, { name: "Complete config", url: "https://example.com/webhook", secret: "secret123", - branchFilter: "main", - authHeader: "X-Token: abc", - expectedKeys: []string{"url", "http_method", "content_type", "secret", "branch_filter", "authorization_header"}, + expectedKeys: []string{"url", "http_method", "content_type", "secret"}, expectedValues: map[string]string{ - "url": "https://example.com/webhook", - "http_method": "post", - "content_type": "json", - "secret": "secret123", - "branch_filter": "main", - "authorization_header": "X-Token: abc", + "url": "https://example.com/webhook", + "http_method": "post", + "content_type": "json", + "secret": "secret123", }, }, } @@ -159,12 +129,6 @@ func TestWebhookConfigConstruction(t *testing.T) { if tt.secret != "" { config["secret"] = tt.secret } - if tt.branchFilter != "" { - config["branch_filter"] = tt.branchFilter - } - if tt.authHeader != "" { - config["authorization_header"] = tt.authHeader - } // Check all expected keys exist for _, key := range tt.expectedKeys { @@ -189,6 +153,8 @@ func TestWebhookCreateOptions(t *testing.T) { events []string active bool config map[string]string + branchFilter string + authHeader string }{ { name: "Gitea webhook", @@ -200,6 +166,8 @@ func TestWebhookCreateOptions(t *testing.T) { "http_method": "post", "content_type": "json", }, + branchFilter: "main", + authHeader: "X-Token: abc", }, { name: "Slack webhook", @@ -228,16 +196,20 @@ func TestWebhookCreateOptions(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { option := gitea.CreateHookOption{ - Type: gitea.HookType(tt.webhookType), - Config: tt.config, - Events: tt.events, - Active: tt.active, + Type: gitea.HookType(tt.webhookType), + Config: tt.config, + Events: tt.events, + Active: tt.active, + BranchFilter: tt.branchFilter, + AuthorizationHeader: tt.authHeader, } assert.Equal(t, gitea.HookType(tt.webhookType), option.Type) assert.Equal(t, tt.events, option.Events) assert.Equal(t, tt.active, option.Active) assert.Equal(t, tt.config, option.Config) + assert.Equal(t, tt.branchFilter, option.BranchFilter) + assert.Equal(t, tt.authHeader, option.AuthorizationHeader) }) } } diff --git a/cmd/webhooks/update.go b/cmd/webhooks/update.go index 256f2a9..e37fcb4 100644 --- a/cmd/webhooks/update.go +++ b/cmd/webhooks/update.go @@ -97,11 +97,14 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error { if cmd.IsSet("secret") { config["secret"] = cmd.String("secret") } + branchFilter := hook.BranchFilter if cmd.IsSet("branch-filter") { - config["branch_filter"] = cmd.String("branch-filter") + branchFilter = cmd.String("branch-filter") } + + authHeader := hook.AuthorizationHeader if cmd.IsSet("authorization-header") { - config["authorization_header"] = cmd.String("authorization-header") + authHeader = cmd.String("authorization-header") } // Update events if specified @@ -126,15 +129,19 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error { return fmt.Errorf("global webhooks not yet supported in this version") } else if len(c.Org) > 0 { _, err = client.EditOrgHook(c.Org, int64(webhookID), gitea.EditHookOption{ - Config: config, - Events: events, - Active: &active, + Config: config, + Events: events, + Active: &active, + BranchFilter: branchFilter, + AuthorizationHeader: authHeader, }) } else { _, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{ - Config: config, - Events: events, - Active: &active, + Config: config, + Events: events, + Active: &active, + BranchFilter: branchFilter, + AuthorizationHeader: authHeader, }) } if err != nil { diff --git a/cmd/webhooks/update_test.go b/cmd/webhooks/update_test.go index bc50574..7f55909 100644 --- a/cmd/webhooks/update_test.go +++ b/cmd/webhooks/update_test.go @@ -130,8 +130,6 @@ func TestUpdateConfigPreservation(t *testing.T) { originalConfig := map[string]string{ "url": "https://old.example.com/webhook", "secret": "old-secret", - "branch_filter": "main", - "authorization_header": "Bearer old-token", "http_method": "post", "content_type": "json", } @@ -149,37 +147,18 @@ func TestUpdateConfigPreservation(t *testing.T) { expectedConfig: map[string]string{ "url": "https://new.example.com/webhook", "secret": "old-secret", - "branch_filter": "main", - "authorization_header": "Bearer old-token", "http_method": "post", "content_type": "json", }, }, { - name: "Update secret and auth header", + name: "Update secret", updates: map[string]string{ "secret": "new-secret", - "authorization_header": "X-Token: new-token", }, expectedConfig: map[string]string{ "url": "https://old.example.com/webhook", "secret": "new-secret", - "branch_filter": "main", - "authorization_header": "X-Token: new-token", - "http_method": "post", - "content_type": "json", - }, - }, - { - name: "Clear branch filter", - updates: map[string]string{ - "branch_filter": "", - }, - expectedConfig: map[string]string{ - "url": "https://old.example.com/webhook", - "secret": "old-secret", - "branch_filter": "", - "authorization_header": "Bearer old-token", "http_method": "post", "content_type": "json", }, @@ -190,8 +169,6 @@ func TestUpdateConfigPreservation(t *testing.T) { expectedConfig: map[string]string{ "url": "https://old.example.com/webhook", "secret": "old-secret", - "branch_filter": "main", - "authorization_header": "Bearer old-token", "http_method": "post", "content_type": "json", }, @@ -217,6 +194,61 @@ func TestUpdateConfigPreservation(t *testing.T) { } } +func TestUpdateBranchFilterAndAuthHeaderHandling(t *testing.T) { + tests := []struct { + name string + originalBranchFilter string + originalAuthHeader string + setBranchFilter bool + newBranchFilter string + setAuthorizationHeader bool + newAuthHeader string + expectedBranchFilter string + expectedAuthHeader string + }{ + { + name: "Preserve values", + originalBranchFilter: "main", + originalAuthHeader: "Bearer old-token", + expectedBranchFilter: "main", + expectedAuthHeader: "Bearer old-token", + }, + { + name: "Update branch filter", + originalBranchFilter: "main", + setBranchFilter: true, + newBranchFilter: "develop", + expectedBranchFilter: "develop", + expectedAuthHeader: "", + }, + { + name: "Update authorization header", + originalAuthHeader: "Bearer old-token", + setAuthorizationHeader: true, + newAuthHeader: "X-Token: new-token", + expectedBranchFilter: "", + expectedAuthHeader: "X-Token: new-token", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + branchFilter := tt.originalBranchFilter + if tt.setBranchFilter { + branchFilter = tt.newBranchFilter + } + + authHeader := tt.originalAuthHeader + if tt.setAuthorizationHeader { + authHeader = tt.newAuthHeader + } + + assert.Equal(t, tt.expectedBranchFilter, branchFilter) + assert.Equal(t, tt.expectedAuthHeader, authHeader) + }) + } +} + func TestUpdateEventsHandling(t *testing.T) { tests := []struct { name string diff --git a/modules/print/webhook.go b/modules/print/webhook.go index 6193e21..577bddc 100644 --- a/modules/print/webhook.go +++ b/modules/print/webhook.go @@ -67,13 +67,21 @@ func WebhookDetails(hook *gitea.Hook) { if method, ok := hook.Config["http_method"]; ok { fmt.Printf("- **HTTP Method**: %s\n", method) } - if branchFilter, ok := hook.Config["branch_filter"]; ok && branchFilter != "" { + branchFilter := hook.BranchFilter + if branchFilter == "" { + branchFilter = hook.Config["branch_filter"] + } + if branchFilter != "" { fmt.Printf("- **Branch Filter**: %s\n", branchFilter) } if _, hasSecret := hook.Config["secret"]; hasSecret { fmt.Printf("- **Secret**: (configured)\n") } - if _, hasAuth := hook.Config["authorization_header"]; hasAuth { + hasAuth := hook.AuthorizationHeader != "" + if !hasAuth { + _, hasAuth = hook.Config["authorization_header"] + } + if hasAuth { fmt.Printf("- **Authorization Header**: (configured)\n") } } diff --git a/modules/print/webhook_test.go b/modules/print/webhook_test.go index 83963a1..f54d006 100644 --- a/modules/print/webhook_test.go +++ b/modules/print/webhook_test.go @@ -84,10 +84,10 @@ func TestWebhookDetails(t *testing.T) { "url": "https://example.com/webhook", "content_type": "json", "http_method": "post", - "branch_filter": "main,develop", "secret": "secret-value", - "authorization_header": "Bearer token123", }, + BranchFilter: "main,develop", + AuthorizationHeader: "Bearer token123", Events: []string{"push", "pull_request", "issues"}, Active: true, Created: now.Add(-24 * time.Hour), @@ -240,14 +240,12 @@ func TestWebhookConfigHandling(t *testing.T) { config: map[string]string{ "url": "https://example.com/webhook", "secret": "my-secret", - "authorization_header": "Bearer token", "content_type": "json", "http_method": "post", - "branch_filter": "main", }, expectedURL: "https://example.com/webhook", hasSecret: true, - hasAuthHeader: true, + hasAuthHeader: false, }, { name: "Config with minimal fields", @@ -344,10 +342,10 @@ func TestWebhookDetailsFormatting(t *testing.T) { "url": "https://example.com/webhook", "content_type": "json", "http_method": "post", - "branch_filter": "main,develop", "secret": "secret-value", - "authorization_header": "Bearer token123", }, + BranchFilter: "main,develop", + AuthorizationHeader: "Bearer token123", Events: []string{"push", "pull_request", "issues"}, Active: true, Created: now.Add(-24 * time.Hour), @@ -379,8 +377,8 @@ func TestWebhookDetailsFormatting(t *testing.T) { assert.Equal(t, "https://example.com/webhook", hook.Config["url"]) assert.Equal(t, "json", hook.Config["content_type"]) assert.Equal(t, "post", hook.Config["http_method"]) - assert.Equal(t, "main,develop", hook.Config["branch_filter"]) + assert.Equal(t, "main,develop", hook.BranchFilter) assert.Contains(t, hook.Config, "secret") - assert.Contains(t, hook.Config, "authorization_header") + assert.Equal(t, "Bearer token123", hook.AuthorizationHeader) assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events) }