Merge pull request '[BUG] fix webhook creation payload ref' (#3055) from oliverpool/forgejo:webhook_fix_create_payload_ref into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3055 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
This commit is contained in:
		
				commit
				
					
						a015ada29a
					
				
			
		
					 4 changed files with 76 additions and 5 deletions
				
			
		| 
						 | 
					@ -106,7 +106,7 @@ func (t *HookTask) simpleMarshalJSON(v any) string {
 | 
				
			||||||
	return string(p)
 | 
						return string(p)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HookTasks returns a list of hook tasks by given conditions.
 | 
					// HookTasks returns a list of hook tasks by given conditions, order by ID desc.
 | 
				
			||||||
func HookTasks(ctx context.Context, hookID int64, page int) ([]*HookTask, error) {
 | 
					func HookTasks(ctx context.Context, hookID int64, page int) ([]*HookTask, error) {
 | 
				
			||||||
	tasks := make([]*HookTask, 0, setting.Webhook.PagingNum)
 | 
						tasks := make([]*HookTask, 0, setting.Webhook.PagingNum)
 | 
				
			||||||
	return tasks, db.GetEngine(ctx).
 | 
						return tasks, db.GetEngine(ctx).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -748,10 +748,9 @@ func (m *webhookNotifier) PullRequestReviewRequest(ctx context.Context, doer *us
 | 
				
			||||||
func (m *webhookNotifier) CreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) {
 | 
					func (m *webhookNotifier) CreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) {
 | 
				
			||||||
	apiPusher := convert.ToUser(ctx, pusher, nil)
 | 
						apiPusher := convert.ToUser(ctx, pusher, nil)
 | 
				
			||||||
	apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeNone})
 | 
						apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeNone})
 | 
				
			||||||
	refName := refFullName.ShortName()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventCreate, &api.CreatePayload{
 | 
						if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventCreate, &api.CreatePayload{
 | 
				
			||||||
		Ref:     refName, // FIXME: should it be a full ref name?
 | 
							Ref:     refFullName.String(),
 | 
				
			||||||
		Sha:     refID,
 | 
							Sha:     refID,
 | 
				
			||||||
		RefType: refFullName.RefType(),
 | 
							RefType: refFullName.RefType(),
 | 
				
			||||||
		Repo:    apiRepo,
 | 
							Repo:    apiRepo,
 | 
				
			||||||
| 
						 | 
					@ -785,10 +784,9 @@ func (m *webhookNotifier) PullRequestSynchronized(ctx context.Context, doer *use
 | 
				
			||||||
func (m *webhookNotifier) DeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) {
 | 
					func (m *webhookNotifier) DeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) {
 | 
				
			||||||
	apiPusher := convert.ToUser(ctx, pusher, nil)
 | 
						apiPusher := convert.ToUser(ctx, pusher, nil)
 | 
				
			||||||
	apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner})
 | 
						apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner})
 | 
				
			||||||
	refName := refFullName.ShortName()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventDelete, &api.DeletePayload{
 | 
						if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventDelete, &api.DeletePayload{
 | 
				
			||||||
		Ref:        refName, // FIXME: should it be a full ref name?
 | 
							Ref:        refFullName.String(),
 | 
				
			||||||
		RefType:    refFullName.RefType(),
 | 
							RefType:    refFullName.RefType(),
 | 
				
			||||||
		PusherType: api.PusherTypeUser,
 | 
							PusherType: api.PusherTypeUser,
 | 
				
			||||||
		Repo:       apiRepo,
 | 
							Repo:       apiRepo,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,7 @@ func testPullCleanUp(t *testing.T, session *TestSession, user, repo, pullnum str
 | 
				
			||||||
	return resp
 | 
						return resp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// returns the hook tasks, order by ID desc.
 | 
				
			||||||
func retrieveHookTasks(t *testing.T, hookID int64, activateWebhook bool) []*webhook.HookTask {
 | 
					func retrieveHookTasks(t *testing.T, hookID int64, activateWebhook bool) []*webhook.HookTask {
 | 
				
			||||||
	t.Helper()
 | 
						t.Helper()
 | 
				
			||||||
	if activateWebhook {
 | 
						if activateWebhook {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										72
									
								
								tests/integration/webhook_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								tests/integration/webhook_test.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package integration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models/unittest"
 | 
				
			||||||
 | 
						webhook_model "code.gitea.io/gitea/models/webhook"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/json"
 | 
				
			||||||
 | 
						webhook_module "code.gitea.io/gitea/modules/webhook"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestWebhookPayloadRef(t *testing.T) {
 | 
				
			||||||
 | 
						onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
 | 
				
			||||||
 | 
							w := unittest.AssertExistsAndLoadBean(t, &webhook_model.Webhook{ID: 1})
 | 
				
			||||||
 | 
							w.HookEvent = &webhook_module.HookEvent{
 | 
				
			||||||
 | 
								SendEverything: true,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							assert.NoError(t, w.UpdateEvent())
 | 
				
			||||||
 | 
							assert.NoError(t, webhook_model.UpdateWebhook(db.DefaultContext, w))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hookTasks := retrieveHookTasks(t, w.ID, true)
 | 
				
			||||||
 | 
							hookTasksLenBefore := len(hookTasks)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							session := loginUser(t, "user2")
 | 
				
			||||||
 | 
							// create new branch
 | 
				
			||||||
 | 
							csrf := GetCSRF(t, session, "user2/repo1")
 | 
				
			||||||
 | 
							req := NewRequestWithValues(t, "POST", "user2/repo1/branches/_new/branch/master",
 | 
				
			||||||
 | 
								map[string]string{
 | 
				
			||||||
 | 
									"_csrf":           csrf,
 | 
				
			||||||
 | 
									"new_branch_name": "arbre",
 | 
				
			||||||
 | 
									"create_tag":      "false",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							session.MakeRequest(t, req, http.StatusSeeOther)
 | 
				
			||||||
 | 
							// delete the created branch
 | 
				
			||||||
 | 
							req = NewRequestWithValues(t, "POST", "user2/repo1/branches/delete?name=arbre",
 | 
				
			||||||
 | 
								map[string]string{
 | 
				
			||||||
 | 
									"_csrf": csrf,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// check the newly created hooktasks
 | 
				
			||||||
 | 
							hookTasks = retrieveHookTasks(t, w.ID, false)
 | 
				
			||||||
 | 
							expected := map[webhook_module.HookEventType]bool{
 | 
				
			||||||
 | 
								webhook_module.HookEventCreate: true,
 | 
				
			||||||
 | 
								webhook_module.HookEventPush:   true, // the branch creation also creates a push event
 | 
				
			||||||
 | 
								webhook_module.HookEventDelete: true,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, hookTask := range hookTasks[:len(hookTasks)-hookTasksLenBefore] {
 | 
				
			||||||
 | 
								if !expected[hookTask.EventType] {
 | 
				
			||||||
 | 
									t.Errorf("unexpected (or duplicated) event %q", hookTask.EventType)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var payload struct {
 | 
				
			||||||
 | 
									Ref string `json:"ref"`
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								assert.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payload))
 | 
				
			||||||
 | 
								assert.Equal(t, "refs/heads/arbre", payload.Ref, "unexpected ref for %q event", hookTask.EventType)
 | 
				
			||||||
 | 
								delete(expected, hookTask.EventType)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							assert.Empty(t, expected)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue