mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 05:25:15 +01: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:
		
							parent
							
								
									256b94e9e9
								
							
						
					
					
						commit
						75940a0191
					
				@ -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,10 +921,16 @@ 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,
 | 
			
		||||
		Sender:  convert.ToUser(ctx, sender, nil),
 | 
			
		||||
		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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user