mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Add tests for webhook and fix some webhook bugs (#33396)
This PR created a mock webhook server in the tests and added integration tests for generic webhooks. It also fixes bugs in package webhooks and pull request comment webhooks.
This commit is contained in:
		| @@ -116,14 +116,7 @@ var ( | ||||
| 	_ Payloader = &PackagePayload{} | ||||
| ) | ||||
|  | ||||
| // _________                        __ | ||||
| // \_   ___ \_______   ____ _____ _/  |_  ____ | ||||
| // /    \  \/\_  __ \_/ __ \\__  \\   __\/ __ \ | ||||
| // \     \____|  | \/\  ___/ / __ \|  | \  ___/ | ||||
| //  \______  /|__|    \___  >____  /__|  \___  > | ||||
| //         \/             \/     \/          \/ | ||||
|  | ||||
| // CreatePayload FIXME | ||||
| // CreatePayload represents a payload information of create event. | ||||
| type CreatePayload struct { | ||||
| 	Sha     string      `json:"sha"` | ||||
| 	Ref     string      `json:"ref"` | ||||
| @@ -157,13 +150,6 @@ func ParseCreateHook(raw []byte) (*CreatePayload, error) { | ||||
| 	return hook, nil | ||||
| } | ||||
|  | ||||
| // ________         .__          __ | ||||
| // \______ \   ____ |  |   _____/  |_  ____ | ||||
| //  |    |  \_/ __ \|  | _/ __ \   __\/ __ \ | ||||
| //  |    `   \  ___/|  |_\  ___/|  | \  ___/ | ||||
| // /_______  /\___  >____/\___  >__|  \___  > | ||||
| //         \/     \/          \/          \/ | ||||
|  | ||||
| // PusherType define the type to push | ||||
| type PusherType string | ||||
|  | ||||
| @@ -186,13 +172,6 @@ func (p *DeletePayload) JSONPayload() ([]byte, error) { | ||||
| 	return json.MarshalIndent(p, "", "  ") | ||||
| } | ||||
|  | ||||
| // ___________           __ | ||||
| // \_   _____/__________|  | __ | ||||
| //  |    __)/  _ \_  __ \  |/ / | ||||
| //  |     \(  <_> )  | \/    < | ||||
| //  \___  / \____/|__|  |__|_ \ | ||||
| //      \/                   \/ | ||||
|  | ||||
| // ForkPayload represents fork payload | ||||
| type ForkPayload struct { | ||||
| 	Forkee *Repository `json:"forkee"` | ||||
| @@ -232,13 +211,6 @@ func (p *IssueCommentPayload) JSONPayload() ([]byte, error) { | ||||
| 	return json.MarshalIndent(p, "", "  ") | ||||
| } | ||||
|  | ||||
| // __________       .__ | ||||
| // \______   \ ____ |  |   ____ _____    ______ ____ | ||||
| //  |       _// __ \|  | _/ __ \\__  \  /  ___// __ \ | ||||
| //  |    |   \  ___/|  |_\  ___/ / __ \_\___ \\  ___/ | ||||
| //  |____|_  /\___  >____/\___  >____  /____  >\___  > | ||||
| //         \/     \/          \/     \/     \/     \/ | ||||
|  | ||||
| // HookReleaseAction defines hook release action type | ||||
| type HookReleaseAction string | ||||
|  | ||||
| @@ -302,13 +274,6 @@ func (p *PushPayload) Branch() string { | ||||
| 	return strings.ReplaceAll(p.Ref, "refs/heads/", "") | ||||
| } | ||||
|  | ||||
| // .___ | ||||
| // |   | ______ ________ __   ____ | ||||
| // |   |/  ___//  ___/  |  \_/ __ \ | ||||
| // |   |\___ \ \___ \|  |  /\  ___/ | ||||
| // |___/____  >____  >____/  \___  > | ||||
| //          \/     \/            \/ | ||||
|  | ||||
| // HookIssueAction FIXME | ||||
| type HookIssueAction string | ||||
|  | ||||
| @@ -371,13 +336,6 @@ type ChangesPayload struct { | ||||
| 	Ref   *ChangesFromPayload `json:"ref,omitempty"` | ||||
| } | ||||
|  | ||||
| // __________      .__  .__    __________                                     __ | ||||
| // \______   \__ __|  | |  |   \______   \ ____  ________ __   ____   _______/  |_ | ||||
| //  |     ___/  |  \  | |  |    |       _// __ \/ ____/  |  \_/ __ \ /  ___/\   __\ | ||||
| //  |    |   |  |  /  |_|  |__  |    |   \  ___< <_|  |  |  /\  ___/ \___ \  |  | | ||||
| //  |____|   |____/|____/____/  |____|_  /\___  >__   |____/  \___  >____  > |__| | ||||
| //                                     \/     \/   |__|           \/     \/ | ||||
|  | ||||
| // PullRequestPayload represents a payload information of pull request event. | ||||
| type PullRequestPayload struct { | ||||
| 	Action            HookIssueAction `json:"action"` | ||||
| @@ -402,13 +360,6 @@ type ReviewPayload struct { | ||||
| 	Content string `json:"content"` | ||||
| } | ||||
|  | ||||
| //  __      __.__ __   .__ | ||||
| // /  \    /  \__|  | _|__| | ||||
| // \   \/\/   /  |  |/ /  | | ||||
| //  \        /|  |    <|  | | ||||
| //   \__/\  / |__|__|_ \__| | ||||
| //        \/          \/ | ||||
|  | ||||
| // HookWikiAction an action that happens to a wiki page | ||||
| type HookWikiAction string | ||||
|  | ||||
| @@ -435,13 +386,6 @@ func (p *WikiPayload) JSONPayload() ([]byte, error) { | ||||
| 	return json.MarshalIndent(p, "", " ") | ||||
| } | ||||
|  | ||||
| //__________                           .__  __ | ||||
| //\______   \ ____ ______   ____  _____|__|/  |_  ___________ ___.__. | ||||
| // |       _// __ \\____ \ /  _ \/  ___/  \   __\/  _ \_  __ <   |  | | ||||
| // |    |   \  ___/|  |_> >  <_> )___ \|  ||  | (  <_> )  | \/\___  | | ||||
| // |____|_  /\___  >   __/ \____/____  >__||__|  \____/|__|   / ____| | ||||
| //        \/     \/|__|              \/                       \/ | ||||
|  | ||||
| // HookRepoAction an action that happens to a repo | ||||
| type HookRepoAction string | ||||
|  | ||||
| @@ -480,7 +424,7 @@ type PackagePayload struct { | ||||
| 	Action       HookPackageAction `json:"action"` | ||||
| 	Repository   *Repository       `json:"repository"` | ||||
| 	Package      *Package          `json:"package"` | ||||
| 	Organization *User             `json:"organization"` | ||||
| 	Organization *Organization     `json:"organization"` | ||||
| 	Sender       *User             `json:"sender"` | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -205,6 +205,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI | ||||
| 				webhook_module.HookEventWiki:                     util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true), | ||||
| 				webhook_module.HookEventRepository:               util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true), | ||||
| 				webhook_module.HookEventRelease:                  util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true), | ||||
| 				webhook_module.HookEventPackage:                  util.SliceContainsString(form.Events, string(webhook_module.HookEventPackage), true), | ||||
| 				webhook_module.HookEventStatus:                   util.SliceContainsString(form.Events, string(webhook_module.HookEventStatus), true), | ||||
| 			}, | ||||
| 			BranchFilter: form.BranchFilter, | ||||
| @@ -384,6 +385,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestAssign] = pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign)) | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestLabel] = pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel)) | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestMilestone] = pullHook(form.Events, string(webhook_module.HookEventPullRequestMilestone)) | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestComment] = pullHook(form.Events, string(webhook_module.HookEventPullRequestComment)) | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestReview] = pullHook(form.Events, "pull_request_review") | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestReviewRequest] = pullHook(form.Events, string(webhook_module.HookEventPullRequestReviewRequest)) | ||||
| 	w.HookEvents[webhook_module.HookEventPullRequestSync] = pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)) | ||||
|   | ||||
| @@ -190,3 +190,7 @@ func newDingtalkRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_ | ||||
| 	var pc payloadConvertor[DingtalkPayload] = dingtalkConvertor{} | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.DINGTALK, newDingtalkRequest) | ||||
| } | ||||
|   | ||||
| @@ -277,6 +277,10 @@ func newDiscordRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_m | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.DISCORD, newDiscordRequest) | ||||
| } | ||||
|  | ||||
| func parseHookPullRequestEventType(event webhook_module.HookEventType) (string, error) { | ||||
| 	switch event { | ||||
| 	case webhook_module.HookEventPullRequestReviewApproved: | ||||
|   | ||||
| @@ -170,3 +170,7 @@ func newFeishuRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_mo | ||||
| 	var pc payloadConvertor[FeishuPayload] = feishuConvertor{} | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.FEISHU, newFeishuRequest) | ||||
| } | ||||
|   | ||||
| @@ -319,8 +319,8 @@ func packageTestPayload() *api.PackagePayload { | ||||
| 			AvatarURL: "http://localhost:3000/user1/avatar", | ||||
| 		}, | ||||
| 		Repository: nil, | ||||
| 		Organization: &api.User{ | ||||
| 			UserName:  "org1", | ||||
| 		Organization: &api.Organization{ | ||||
| 			Name:      "org1", | ||||
| 			AvatarURL: "http://localhost:3000/org1/avatar", | ||||
| 		}, | ||||
| 		Package: &api.Package{ | ||||
|   | ||||
| @@ -24,6 +24,10 @@ import ( | ||||
| 	webhook_module "code.gitea.io/gitea/modules/webhook" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.MATRIX, newMatrixRequest) | ||||
| } | ||||
|  | ||||
| func newMatrixRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) { | ||||
| 	meta := &MatrixMeta{} | ||||
| 	if err := json.Unmarshal([]byte(w.Meta), meta); err != nil { | ||||
|   | ||||
| @@ -349,3 +349,7 @@ func newMSTeamsRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_m | ||||
| 	var pc payloadConvertor[MSTeamsPayload] = msteamsConvertor{} | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.MSTEAMS, newMSTeamsRequest) | ||||
| } | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import ( | ||||
|  | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	issues_model "code.gitea.io/gitea/models/issues" | ||||
| 	"code.gitea.io/gitea/models/organization" | ||||
| 	packages_model "code.gitea.io/gitea/models/packages" | ||||
| 	"code.gitea.io/gitea/models/perm" | ||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | ||||
| @@ -920,9 +921,15 @@ func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_mo | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	var org *api.Organization | ||||
| 	if pd.Owner.IsOrganization() { | ||||
| 		org = convert.ToOrganization(ctx, organization.OrgFromUser(pd.Owner)) | ||||
| 	} | ||||
|  | ||||
| 	if err := PrepareWebhooks(ctx, source, webhook_module.HookEventPackage, &api.PackagePayload{ | ||||
| 		Action:       action, | ||||
| 		Package:      apiPackage, | ||||
| 		Organization: org, | ||||
| 		Sender:       convert.ToUser(ctx, sender, nil), | ||||
| 	}); err != nil { | ||||
| 		log.Error("PrepareWebhooks: %v", err) | ||||
|   | ||||
| @@ -120,3 +120,7 @@ func newPackagistRequest(_ context.Context, w *webhook_model.Webhook, t *webhook | ||||
| 	} | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.PACKAGIST, newPackagistRequest) | ||||
| } | ||||
|   | ||||
| @@ -295,6 +295,10 @@ func newSlackRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_mod | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.SLACK, newSlackRequest) | ||||
| } | ||||
|  | ||||
| var slackChannel = regexp.MustCompile(`^#?[a-z0-9_-]{1,80}$`) | ||||
|  | ||||
| // IsValidSlackChannel validates a channel name conforms to what slack expects: | ||||
|   | ||||
| @@ -187,3 +187,7 @@ func newTelegramRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_ | ||||
| 	var pc payloadConvertor[TelegramPayload] = telegramConvertor{} | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.TELEGRAM, newTelegramRequest) | ||||
| } | ||||
|   | ||||
| @@ -27,16 +27,12 @@ import ( | ||||
| 	"github.com/gobwas/glob" | ||||
| ) | ||||
|  | ||||
| var webhookRequesters = map[webhook_module.HookType]func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error){ | ||||
| 	webhook_module.SLACK:      newSlackRequest, | ||||
| 	webhook_module.DISCORD:    newDiscordRequest, | ||||
| 	webhook_module.DINGTALK:   newDingtalkRequest, | ||||
| 	webhook_module.TELEGRAM:   newTelegramRequest, | ||||
| 	webhook_module.MSTEAMS:    newMSTeamsRequest, | ||||
| 	webhook_module.FEISHU:     newFeishuRequest, | ||||
| 	webhook_module.MATRIX:     newMatrixRequest, | ||||
| 	webhook_module.WECHATWORK: newWechatworkRequest, | ||||
| 	webhook_module.PACKAGIST:  newPackagistRequest, | ||||
| type Requester func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error) | ||||
|  | ||||
| var webhookRequesters = map[webhook_module.HookType]Requester{} | ||||
|  | ||||
| func RegisterWebhookRequester(hookType webhook_module.HookType, requester Requester) { | ||||
| 	webhookRequesters[hookType] = requester | ||||
| } | ||||
|  | ||||
| // IsValidHookTaskType returns true if a webhook registered | ||||
|   | ||||
| @@ -179,3 +179,7 @@ func newWechatworkRequest(_ context.Context, w *webhook_model.Webhook, t *webhoo | ||||
| 	var pc payloadConvertor[WechatworkPayload] = wechatworkConvertor{} | ||||
| 	return newJSONRequest(pc, w, t, true) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	RegisterWebhookRequester(webhook_module.WECHATWORK, newWechatworkRequest) | ||||
| } | ||||
|   | ||||
| @@ -471,6 +471,15 @@ func TestAPIMirrorSyncNonMirrorRepo(t *testing.T) { | ||||
| 	assert.Equal(t, "Repository is not a mirror", errRespJSON["message"]) | ||||
| } | ||||
|  | ||||
| func testAPIOrgCreateRepo(t *testing.T, session *TestSession, orgName, repoName string, status int) { | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository) | ||||
|  | ||||
| 	req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos", orgName), &api.CreateRepoOption{ | ||||
| 		Name: repoName, | ||||
| 	}).AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, status) | ||||
| } | ||||
|  | ||||
| func TestAPIOrgRepoCreate(t *testing.T) { | ||||
| 	testCases := []struct { | ||||
| 		ctxUserID         int64 | ||||
| @@ -488,11 +497,7 @@ func TestAPIOrgRepoCreate(t *testing.T) { | ||||
| 	for _, testCase := range testCases { | ||||
| 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}) | ||||
| 		session := loginUser(t, user.Name) | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository) | ||||
| 		req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos", testCase.orgName), &api.CreateRepoOption{ | ||||
| 			Name: testCase.repoName, | ||||
| 		}).AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, testCase.expectedStatus) | ||||
| 		testAPIOrgCreateRepo(t, session, testCase.orgName, testCase.repoName, testCase.expectedStatus) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -172,6 +172,19 @@ func TestAPIListWikiPages(t *testing.T) { | ||||
| 	assert.Equal(t, dummymeta, meta) | ||||
| } | ||||
|  | ||||
| func testAPICreateWikiPage(t *testing.T, session *TestSession, userName, repoName, title string, status int) { | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) | ||||
|  | ||||
| 	urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new", userName, repoName) | ||||
|  | ||||
| 	req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateWikiPageOptions{ | ||||
| 		Title:         title, | ||||
| 		ContentBase64: base64.StdEncoding.EncodeToString([]byte("Wiki page content for API unit tests")), | ||||
| 		Message:       "", | ||||
| 	}).AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, status) | ||||
| } | ||||
|  | ||||
| func TestAPINewWikiPage(t *testing.T) { | ||||
| 	for _, title := range []string{ | ||||
| 		"New page", | ||||
| @@ -180,16 +193,7 @@ func TestAPINewWikiPage(t *testing.T) { | ||||
| 		defer tests.PrepareTestEnv(t)() | ||||
| 		username := "user2" | ||||
| 		session := loginUser(t, username) | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) | ||||
|  | ||||
| 		urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new", username, "repo1") | ||||
|  | ||||
| 		req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateWikiPageOptions{ | ||||
| 			Title:         title, | ||||
| 			ContentBase64: base64.StdEncoding.EncodeToString([]byte("Wiki page content for API unit tests")), | ||||
| 			Message:       "", | ||||
| 		}).AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusCreated) | ||||
| 		testAPICreateWikiPage(t, session, username, "repo1", title, http.StatusCreated) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -174,7 +174,7 @@ func testIssueAddComment(t *testing.T, session *TestSession, issueURL, content, | ||||
|  | ||||
| 	htmlDoc = NewHTMLParser(t, resp.Body) | ||||
|  | ||||
| 	val := htmlDoc.doc.Find(".comment-list .comment .render-content p").Eq(commentCount).Text() | ||||
| 	val := strings.TrimSpace(htmlDoc.doc.Find(".comment-list .comment .render-content").Eq(commentCount).Text()) | ||||
| 	assert.Equal(t, content, val) | ||||
|  | ||||
| 	idAttr, has := htmlDoc.doc.Find(".comment-list .comment").Eq(commentCount).Attr("id") | ||||
|   | ||||
| @@ -4,10 +4,22 @@ | ||||
| package integration | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
|  | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
| 	"code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	"code.gitea.io/gitea/modules/gitrepo" | ||||
| 	"code.gitea.io/gitea/modules/json" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	webhook_module "code.gitea.io/gitea/modules/webhook" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
|  | ||||
| 	"github.com/PuerkitoBio/goquery" | ||||
| @@ -39,3 +51,514 @@ func TestNewWebHookLink(t *testing.T) { | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, repoName, url, event string) { | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll) | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+userName+"/"+repoName+"/hooks", api.CreateHookOption{ | ||||
| 		Type: "gitea", | ||||
| 		Config: api.CreateHookOptionConfig{ | ||||
| 			"content_type": "json", | ||||
| 			"url":          url, | ||||
| 		}, | ||||
| 		Events: []string{event}, | ||||
| 		Active: true, | ||||
| 	}).AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
| } | ||||
|  | ||||
| func testAPICreateWebhookForOrg(t *testing.T, session *TestSession, userName, url, event string) { | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll) | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/"+userName+"/hooks", api.CreateHookOption{ | ||||
| 		Type: "gitea", | ||||
| 		Config: api.CreateHookOptionConfig{ | ||||
| 			"content_type": "json", | ||||
| 			"url":          url, | ||||
| 		}, | ||||
| 		Events: []string{event}, | ||||
| 		Active: true, | ||||
| 	}).AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
| } | ||||
|  | ||||
| type mockWebhookProvider struct { | ||||
| 	server *httptest.Server | ||||
| } | ||||
|  | ||||
| func newMockWebhookProvider(callback func(r *http.Request), status int) *mockWebhookProvider { | ||||
| 	m := &mockWebhookProvider{} | ||||
| 	m.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		callback(r) | ||||
| 		w.WriteHeader(status) | ||||
| 	})) | ||||
| 	return m | ||||
| } | ||||
|  | ||||
| func (m *mockWebhookProvider) URL() string { | ||||
| 	if m.server == nil { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return m.server.URL | ||||
| } | ||||
|  | ||||
| // Close closes the mock webhook http server | ||||
| func (m *mockWebhookProvider) Close() { | ||||
| 	if m.server != nil { | ||||
| 		m.server.Close() | ||||
| 		m.server = nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_WebhookCreate(t *testing.T) { | ||||
| 	var payloads []api.CreatePayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.CreatePayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = string(webhook_module.HookEventCreate) | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "create") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, string(webhook_module.HookEventCreate), triggeredEvent) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) | ||||
| 		assert.EqualValues(t, "master2", payloads[0].Ref) | ||||
| 		assert.EqualValues(t, "branch", payloads[0].RefType) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookDelete(t *testing.T) { | ||||
| 	var payloads []api.DeletePayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.DeletePayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "delete" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "delete") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated) | ||||
| 		testAPIDeleteBranch(t, "master2", http.StatusNoContent) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "delete", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) | ||||
| 		assert.EqualValues(t, "master2", payloads[0].Ref) | ||||
| 		assert.EqualValues(t, "branch", payloads[0].RefType) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookFork(t *testing.T) { | ||||
| 	var payloads []api.ForkPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.ForkPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "fork" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user1") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "fork") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testRepoFork(t, session, "user2", "repo1", "user1", "repo1-fork", "master") | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "fork", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "repo1-fork", payloads[0].Repo.Name) | ||||
| 		assert.EqualValues(t, "user1/repo1-fork", payloads[0].Repo.FullName) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Forkee.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Forkee.FullName) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookIssueComment(t *testing.T) { | ||||
| 	var payloads []api.IssueCommentPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.IssueCommentPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "issue_comment" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_comment") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		issueURL := testNewIssue(t, session, "user2", "repo1", "Title2", "Description2") | ||||
| 		testIssueAddComment(t, session, issueURL, "issue title2 comment1", "") | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "issue_comment", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "created", payloads[0].Action) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Issue.Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Issue.Repo.FullName) | ||||
| 		assert.EqualValues(t, "Title2", payloads[0].Issue.Title) | ||||
| 		assert.EqualValues(t, "Description2", payloads[0].Issue.Body) | ||||
| 		assert.EqualValues(t, "issue title2 comment1", payloads[0].Comment.Body) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookRelease(t *testing.T) { | ||||
| 	var payloads []api.ReleasePayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.ReleasePayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "release" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "release") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		createNewRelease(t, session, "/user2/repo1", "v0.0.99", "v0.0.99", false, false) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "release", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Repository.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Repository.FullName) | ||||
| 		assert.EqualValues(t, "v0.0.99", payloads[0].Release.TagName) | ||||
| 		assert.False(t, payloads[0].Release.IsDraft) | ||||
| 		assert.False(t, payloads[0].Release.IsPrerelease) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookPush(t *testing.T) { | ||||
| 	var payloads []api.PushPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.PushPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "push" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push") | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "push", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) | ||||
| 		assert.Len(t, payloads[0].Commits, 1) | ||||
| 		assert.EqualValues(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookIssue(t *testing.T) { | ||||
| 	var payloads []api.IssuePayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.IssuePayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "issues" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issues") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testNewIssue(t, session, "user2", "repo1", "Title1", "Description1") | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "issues", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "opened", payloads[0].Action) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Issue.Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Issue.Repo.FullName) | ||||
| 		assert.EqualValues(t, "Title1", payloads[0].Issue.Title) | ||||
| 		assert.EqualValues(t, "Description1", payloads[0].Issue.Body) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookPullRequest(t *testing.T) { | ||||
| 	var payloads []api.PullRequestPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.PullRequestPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "pull_request" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "pull_request") | ||||
|  | ||||
| 		testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated) | ||||
| 		// 2. trigger the webhook | ||||
| 		repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1}) | ||||
| 		testCreatePullToDefaultBranch(t, session, repo1, repo1, "master2", "first pull request") | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "pull_request", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].PullRequest.Base.Repository.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].PullRequest.Base.Repository.FullName) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].PullRequest.Head.Repository.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].PullRequest.Head.Repository.FullName) | ||||
| 		assert.EqualValues(t, 0, payloads[0].PullRequest.Additions) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookPullRequestComment(t *testing.T) { | ||||
| 	var payloads []api.IssueCommentPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.IssueCommentPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "pull_request_comment" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "pull_request_comment") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testAPICreateBranch(t, session, "user2", "repo1", "master", "master2", http.StatusCreated) | ||||
| 		repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1}) | ||||
| 		prID := testCreatePullToDefaultBranch(t, session, repo1, repo1, "master2", "first pull request") | ||||
|  | ||||
| 		testIssueAddComment(t, session, "/user2/repo1/pulls/"+prID, "pull title2 comment1", "") | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "pull_request_comment", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "created", payloads[0].Action) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Issue.Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Issue.Repo.FullName) | ||||
| 		assert.EqualValues(t, "first pull request", payloads[0].Issue.Title) | ||||
| 		assert.EqualValues(t, "", payloads[0].Issue.Body) | ||||
| 		assert.EqualValues(t, "pull title2 comment1", payloads[0].Comment.Body) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookWiki(t *testing.T) { | ||||
| 	var payloads []api.WikiPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.WikiPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "wiki" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "wiki") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testAPICreateWikiPage(t, session, "user2", "repo1", "Test Wiki Page", http.StatusCreated) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "wiki", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "created", payloads[0].Action) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Repository.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Repository.FullName) | ||||
| 		assert.EqualValues(t, "Test-Wiki-Page", payloads[0].Page) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookRepository(t *testing.T) { | ||||
| 	var payloads []api.RepositoryPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.RepositoryPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "repository" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user1") | ||||
|  | ||||
| 		testAPICreateWebhookForOrg(t, session, "org3", provider.URL(), "repository") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testAPIOrgCreateRepo(t, session, "org3", "repo_new", http.StatusCreated) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "repository", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "created", payloads[0].Action) | ||||
| 		assert.EqualValues(t, "org3", payloads[0].Organization.UserName) | ||||
| 		assert.EqualValues(t, "repo_new", payloads[0].Repository.Name) | ||||
| 		assert.EqualValues(t, "org3/repo_new", payloads[0].Repository.FullName) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookPackage(t *testing.T) { | ||||
| 	var payloads []api.PackagePayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.PackagePayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "package" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user1") | ||||
|  | ||||
| 		testAPICreateWebhookForOrg(t, session, "org3", provider.URL(), "package") | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll) | ||||
| 		url := fmt.Sprintf("/api/packages/%s/generic/%s/%s", "org3", "gitea", "v1.24.0") | ||||
| 		req := NewRequestWithBody(t, "PUT", url+"/gitea", strings.NewReader("This is a dummy file")). | ||||
| 			AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusCreated) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "package", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, "created", payloads[0].Action) | ||||
| 		assert.EqualValues(t, "gitea", payloads[0].Package.Name) | ||||
| 		assert.EqualValues(t, "generic", payloads[0].Package.Type) | ||||
| 		assert.EqualValues(t, "org3", payloads[0].Organization.UserName) | ||||
| 		assert.EqualValues(t, "v1.24.0", payloads[0].Package.Version) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Test_WebhookStatus(t *testing.T) { | ||||
| 	var payloads []api.CommitStatusPayload | ||||
| 	var triggeredEvent string | ||||
| 	provider := newMockWebhookProvider(func(r *http.Request) { | ||||
| 		assert.Contains(t, r.Header["X-Github-Event-Type"], "status", "X-GitHub-Event-Type should contain status") | ||||
| 		assert.Contains(t, r.Header["X-Gitea-Event-Type"], "status", "X-Gitea-Event-Type should contain status") | ||||
| 		assert.Contains(t, r.Header["X-Gogs-Event-Type"], "status", "X-Gogs-Event-Type should contain status") | ||||
| 		content, _ := io.ReadAll(r.Body) | ||||
| 		var payload api.CommitStatusPayload | ||||
| 		err := json.Unmarshal(content, &payload) | ||||
| 		assert.NoError(t, err) | ||||
| 		payloads = append(payloads, payload) | ||||
| 		triggeredEvent = "status" | ||||
| 	}, http.StatusOK) | ||||
| 	defer provider.Close() | ||||
|  | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// 1. create a new webhook with special webhook for repo1 | ||||
| 		session := loginUser(t, "user2") | ||||
|  | ||||
| 		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "status") | ||||
|  | ||||
| 		repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1}) | ||||
|  | ||||
| 		gitRepo1, err := gitrepo.OpenRepository(context.Background(), repo1) | ||||
| 		assert.NoError(t, err) | ||||
| 		commitID, err := gitRepo1.GetBranchCommitID(repo1.DefaultBranch) | ||||
| 		assert.NoError(t, err) | ||||
|  | ||||
| 		// 2. trigger the webhook | ||||
| 		testCtx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeAll) | ||||
|  | ||||
| 		// update a status for a commit via API | ||||
| 		doAPICreateCommitStatus(testCtx, commitID, api.CreateStatusOption{ | ||||
| 			State:       api.CommitStatusSuccess, | ||||
| 			TargetURL:   "http://test.ci/", | ||||
| 			Description: "", | ||||
| 			Context:     "testci", | ||||
| 		})(t) | ||||
|  | ||||
| 		// 3. validate the webhook is triggered | ||||
| 		assert.EqualValues(t, "status", triggeredEvent) | ||||
| 		assert.Len(t, payloads, 1) | ||||
| 		assert.EqualValues(t, commitID, payloads[0].Commit.ID) | ||||
| 		assert.EqualValues(t, "repo1", payloads[0].Repo.Name) | ||||
| 		assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) | ||||
| 		assert.EqualValues(t, "testci", payloads[0].Context) | ||||
| 		assert.EqualValues(t, commitID, payloads[0].SHA) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -26,6 +26,9 @@ TYPE = immediate | ||||
| [queue.push_update] | ||||
| TYPE = immediate | ||||
|  | ||||
| [queue.webhook_sender] | ||||
| TYPE = immediate | ||||
|  | ||||
| [repository] | ||||
| ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/gitea-repositories | ||||
|  | ||||
| @@ -111,3 +114,6 @@ ENABLED = true | ||||
|  | ||||
| [actions] | ||||
| ENABLED = true | ||||
|  | ||||
| [webhook] | ||||
| ALLOWED_HOST_LIST = 127.0.0.1 | ||||
|   | ||||
| @@ -28,6 +28,9 @@ TYPE = immediate | ||||
| [queue.push_update] | ||||
| TYPE = immediate | ||||
|  | ||||
| [queue.webhook_sender] | ||||
| TYPE = immediate | ||||
|  | ||||
| [repository] | ||||
| ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/gitea-repositories | ||||
|  | ||||
| @@ -118,3 +121,6 @@ REPLY_TO_ADDRESS = incoming+%{token}@localhost | ||||
|  | ||||
| [actions] | ||||
| ENABLED = true | ||||
|  | ||||
| [webhook] | ||||
| ALLOWED_HOST_LIST = 127.0.0.1 | ||||
|   | ||||
| @@ -27,6 +27,9 @@ TYPE = immediate | ||||
| [queue.push_update] | ||||
| TYPE = immediate | ||||
|  | ||||
| [queue.webhook_sender] | ||||
| TYPE = immediate | ||||
|  | ||||
| [repository] | ||||
| ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/gitea-repositories | ||||
|  | ||||
| @@ -127,3 +130,6 @@ ENABLED = true | ||||
|  | ||||
| [actions] | ||||
| ENABLED = true | ||||
|  | ||||
| [webhook] | ||||
| ALLOWED_HOST_LIST = 127.0.0.1 | ||||
|   | ||||
| @@ -22,6 +22,9 @@ TYPE = immediate | ||||
| [queue.push_update] | ||||
| TYPE = immediate | ||||
|  | ||||
| [queue.webhook_sender] | ||||
| TYPE = immediate | ||||
|  | ||||
| [repository] | ||||
| ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/gitea-repositories | ||||
|  | ||||
| @@ -116,3 +119,6 @@ RENDER_CONTENT_MODE=sanitized | ||||
|  | ||||
| [actions] | ||||
| ENABLED = true | ||||
|  | ||||
| [webhook] | ||||
| ALLOWED_HOST_LIST = 127.0.0.1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lunny Xiao
					Lunny Xiao