mirror of
https://github.com/go-gitea/gitea.git
synced 2025-04-22 01:18:45 +03:00
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 also corrected an error on the package webhook. The previous implementation uses a `User` struct as an organization, now it has been corrected but it will not be consistent with the previous implementation, some fields which not belong to the organization have been removed. Backport #33396 Backport part of #33337
This commit is contained in:
@ -299,6 +299,11 @@ func (w *Webhook) HasPackageEvent() bool {
|
|||||||
(w.ChooseEvents && w.HookEvents.Package)
|
(w.ChooseEvents && w.HookEvents.Package)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Webhook) HasStatusEvent() bool {
|
||||||
|
return w.SendEverything ||
|
||||||
|
(w.ChooseEvents && w.HookEvents.Status)
|
||||||
|
}
|
||||||
|
|
||||||
// HasPullRequestReviewRequestEvent returns true if hook enabled pull request review request event.
|
// HasPullRequestReviewRequestEvent returns true if hook enabled pull request review request event.
|
||||||
func (w *Webhook) HasPullRequestReviewRequestEvent() bool {
|
func (w *Webhook) HasPullRequestReviewRequestEvent() bool {
|
||||||
return w.SendEverything ||
|
return w.SendEverything ||
|
||||||
@ -337,6 +342,7 @@ func (w *Webhook) EventCheckers() []struct {
|
|||||||
{w.HasReleaseEvent, webhook_module.HookEventRelease},
|
{w.HasReleaseEvent, webhook_module.HookEventRelease},
|
||||||
{w.HasPackageEvent, webhook_module.HookEventPackage},
|
{w.HasPackageEvent, webhook_module.HookEventPackage},
|
||||||
{w.HasPullRequestReviewRequestEvent, webhook_module.HookEventPullRequestReviewRequest},
|
{w.HasPullRequestReviewRequestEvent, webhook_module.HookEventPullRequestReviewRequest},
|
||||||
|
{w.HasStatusEvent, webhook_module.HookEventStatus},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ func TestWebhook_EventsArray(t *testing.T) {
|
|||||||
"pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone",
|
"pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone",
|
||||||
"pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected",
|
"pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected",
|
||||||
"pull_request_review_comment", "pull_request_sync", "wiki", "repository", "release",
|
"pull_request_review_comment", "pull_request_sync", "wiki", "repository", "release",
|
||||||
"package", "pull_request_review_request",
|
"package", "pull_request_review_request", "status",
|
||||||
},
|
},
|
||||||
(&Webhook{
|
(&Webhook{
|
||||||
HookEvent: &webhook_module.HookEvent{SendEverything: true},
|
HookEvent: &webhook_module.HookEvent{SendEverything: true},
|
||||||
|
@ -116,14 +116,7 @@ var (
|
|||||||
_ Payloader = &PackagePayload{}
|
_ Payloader = &PackagePayload{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// _________ __
|
// CreatePayload represents a payload information of create event.
|
||||||
// \_ ___ \_______ ____ _____ _/ |_ ____
|
|
||||||
// / \ \/\_ __ \_/ __ \\__ \\ __\/ __ \
|
|
||||||
// \ \____| | \/\ ___/ / __ \| | \ ___/
|
|
||||||
// \______ /|__| \___ >____ /__| \___ >
|
|
||||||
// \/ \/ \/ \/
|
|
||||||
|
|
||||||
// CreatePayload FIXME
|
|
||||||
type CreatePayload struct {
|
type CreatePayload struct {
|
||||||
Sha string `json:"sha"`
|
Sha string `json:"sha"`
|
||||||
Ref string `json:"ref"`
|
Ref string `json:"ref"`
|
||||||
@ -157,13 +150,6 @@ func ParseCreateHook(raw []byte) (*CreatePayload, error) {
|
|||||||
return hook, nil
|
return hook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ________ .__ __
|
|
||||||
// \______ \ ____ | | _____/ |_ ____
|
|
||||||
// | | \_/ __ \| | _/ __ \ __\/ __ \
|
|
||||||
// | ` \ ___/| |_\ ___/| | \ ___/
|
|
||||||
// /_______ /\___ >____/\___ >__| \___ >
|
|
||||||
// \/ \/ \/ \/
|
|
||||||
|
|
||||||
// PusherType define the type to push
|
// PusherType define the type to push
|
||||||
type PusherType string
|
type PusherType string
|
||||||
|
|
||||||
@ -186,13 +172,6 @@ func (p *DeletePayload) JSONPayload() ([]byte, error) {
|
|||||||
return json.MarshalIndent(p, "", " ")
|
return json.MarshalIndent(p, "", " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ___________ __
|
|
||||||
// \_ _____/__________| | __
|
|
||||||
// | __)/ _ \_ __ \ |/ /
|
|
||||||
// | \( <_> ) | \/ <
|
|
||||||
// \___ / \____/|__| |__|_ \
|
|
||||||
// \/ \/
|
|
||||||
|
|
||||||
// ForkPayload represents fork payload
|
// ForkPayload represents fork payload
|
||||||
type ForkPayload struct {
|
type ForkPayload struct {
|
||||||
Forkee *Repository `json:"forkee"`
|
Forkee *Repository `json:"forkee"`
|
||||||
@ -232,13 +211,6 @@ func (p *IssueCommentPayload) JSONPayload() ([]byte, error) {
|
|||||||
return json.MarshalIndent(p, "", " ")
|
return json.MarshalIndent(p, "", " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________ .__
|
|
||||||
// \______ \ ____ | | ____ _____ ______ ____
|
|
||||||
// | _// __ \| | _/ __ \\__ \ / ___// __ \
|
|
||||||
// | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
|
|
||||||
// |____|_ /\___ >____/\___ >____ /____ >\___ >
|
|
||||||
// \/ \/ \/ \/ \/ \/
|
|
||||||
|
|
||||||
// HookReleaseAction defines hook release action type
|
// HookReleaseAction defines hook release action type
|
||||||
type HookReleaseAction string
|
type HookReleaseAction string
|
||||||
|
|
||||||
@ -302,13 +274,6 @@ func (p *PushPayload) Branch() string {
|
|||||||
return strings.ReplaceAll(p.Ref, "refs/heads/", "")
|
return strings.ReplaceAll(p.Ref, "refs/heads/", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// .___
|
|
||||||
// | | ______ ________ __ ____
|
|
||||||
// | |/ ___// ___/ | \_/ __ \
|
|
||||||
// | |\___ \ \___ \| | /\ ___/
|
|
||||||
// |___/____ >____ >____/ \___ >
|
|
||||||
// \/ \/ \/
|
|
||||||
|
|
||||||
// HookIssueAction FIXME
|
// HookIssueAction FIXME
|
||||||
type HookIssueAction string
|
type HookIssueAction string
|
||||||
|
|
||||||
@ -371,13 +336,6 @@ type ChangesPayload struct {
|
|||||||
Ref *ChangesFromPayload `json:"ref,omitempty"`
|
Ref *ChangesFromPayload `json:"ref,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________ .__ .__ __________ __
|
|
||||||
// \______ \__ __| | | | \______ \ ____ ________ __ ____ _______/ |_
|
|
||||||
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
|
|
||||||
// | | | | / |_| |__ | | \ ___< <_| | | /\ ___/ \___ \ | |
|
|
||||||
// |____| |____/|____/____/ |____|_ /\___ >__ |____/ \___ >____ > |__|
|
|
||||||
// \/ \/ |__| \/ \/
|
|
||||||
|
|
||||||
// PullRequestPayload represents a payload information of pull request event.
|
// PullRequestPayload represents a payload information of pull request event.
|
||||||
type PullRequestPayload struct {
|
type PullRequestPayload struct {
|
||||||
Action HookIssueAction `json:"action"`
|
Action HookIssueAction `json:"action"`
|
||||||
@ -402,13 +360,6 @@ type ReviewPayload struct {
|
|||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// __ __.__ __ .__
|
|
||||||
// / \ / \__| | _|__|
|
|
||||||
// \ \/\/ / | |/ / |
|
|
||||||
// \ /| | <| |
|
|
||||||
// \__/\ / |__|__|_ \__|
|
|
||||||
// \/ \/
|
|
||||||
|
|
||||||
// HookWikiAction an action that happens to a wiki page
|
// HookWikiAction an action that happens to a wiki page
|
||||||
type HookWikiAction string
|
type HookWikiAction string
|
||||||
|
|
||||||
@ -435,13 +386,6 @@ func (p *WikiPayload) JSONPayload() ([]byte, error) {
|
|||||||
return json.MarshalIndent(p, "", " ")
|
return json.MarshalIndent(p, "", " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
//__________ .__ __
|
|
||||||
//\______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
|
|
||||||
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
|
|
||||||
// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ |
|
|
||||||
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
|
|
||||||
// \/ \/|__| \/ \/
|
|
||||||
|
|
||||||
// HookRepoAction an action that happens to a repo
|
// HookRepoAction an action that happens to a repo
|
||||||
type HookRepoAction string
|
type HookRepoAction string
|
||||||
|
|
||||||
@ -480,7 +424,7 @@ type PackagePayload struct {
|
|||||||
Action HookPackageAction `json:"action"`
|
Action HookPackageAction `json:"action"`
|
||||||
Repository *Repository `json:"repository"`
|
Repository *Repository `json:"repository"`
|
||||||
Package *Package `json:"package"`
|
Package *Package `json:"package"`
|
||||||
Organization *User `json:"organization"`
|
Organization *Organization `json:"organization"`
|
||||||
Sender *User `json:"sender"`
|
Sender *User `json:"sender"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ type HookEvents struct {
|
|||||||
Repository bool `json:"repository"`
|
Repository bool `json:"repository"`
|
||||||
Release bool `json:"release"`
|
Release bool `json:"release"`
|
||||||
Package bool `json:"package"`
|
Package bool `json:"package"`
|
||||||
|
Status bool `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HookEvent represents events that will delivery hook.
|
// HookEvent represents events that will delivery hook.
|
||||||
|
@ -38,14 +38,6 @@ const (
|
|||||||
// Event returns the HookEventType as an event string
|
// Event returns the HookEventType as an event string
|
||||||
func (h HookEventType) Event() string {
|
func (h HookEventType) Event() string {
|
||||||
switch h {
|
switch h {
|
||||||
case HookEventCreate:
|
|
||||||
return "create"
|
|
||||||
case HookEventDelete:
|
|
||||||
return "delete"
|
|
||||||
case HookEventFork:
|
|
||||||
return "fork"
|
|
||||||
case HookEventPush:
|
|
||||||
return "push"
|
|
||||||
case HookEventIssues, HookEventIssueAssign, HookEventIssueLabel, HookEventIssueMilestone:
|
case HookEventIssues, HookEventIssueAssign, HookEventIssueLabel, HookEventIssueMilestone:
|
||||||
return "issues"
|
return "issues"
|
||||||
case HookEventPullRequest, HookEventPullRequestAssign, HookEventPullRequestLabel, HookEventPullRequestMilestone,
|
case HookEventPullRequest, HookEventPullRequestAssign, HookEventPullRequestLabel, HookEventPullRequestMilestone,
|
||||||
@ -59,14 +51,9 @@ func (h HookEventType) Event() string {
|
|||||||
return "pull_request_rejected"
|
return "pull_request_rejected"
|
||||||
case HookEventPullRequestReviewComment:
|
case HookEventPullRequestReviewComment:
|
||||||
return "pull_request_comment"
|
return "pull_request_comment"
|
||||||
case HookEventWiki:
|
default:
|
||||||
return "wiki"
|
return string(h)
|
||||||
case HookEventRepository:
|
|
||||||
return "repository"
|
|
||||||
case HookEventRelease:
|
|
||||||
return "release"
|
|
||||||
}
|
}
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HookType is the type of a webhook
|
// HookType is the type of a webhook
|
||||||
|
@ -205,6 +205,8 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI
|
|||||||
Wiki: util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true),
|
Wiki: util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true),
|
||||||
Repository: util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true),
|
Repository: util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true),
|
||||||
Release: util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true),
|
Release: util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true),
|
||||||
|
Package: util.SliceContainsString(form.Events, string(webhook_module.HookEventPackage), true),
|
||||||
|
Status: util.SliceContainsString(form.Events, string(webhook_module.HookEventStatus), true),
|
||||||
},
|
},
|
||||||
BranchFilter: form.BranchFilter,
|
BranchFilter: form.BranchFilter,
|
||||||
},
|
},
|
||||||
|
@ -190,3 +190,7 @@ func newDingtalkRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_
|
|||||||
var pc payloadConvertor[DingtalkPayload] = dingtalkConvertor{}
|
var pc payloadConvertor[DingtalkPayload] = dingtalkConvertor{}
|
||||||
return newJSONRequest(pc, w, t, true)
|
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)
|
return newJSONRequest(pc, w, t, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterWebhookRequester(webhook_module.DISCORD, newDiscordRequest)
|
||||||
|
}
|
||||||
|
|
||||||
func parseHookPullRequestEventType(event webhook_module.HookEventType) (string, error) {
|
func parseHookPullRequestEventType(event webhook_module.HookEventType) (string, error) {
|
||||||
switch event {
|
switch event {
|
||||||
case webhook_module.HookEventPullRequestReviewApproved:
|
case webhook_module.HookEventPullRequestReviewApproved:
|
||||||
|
@ -170,3 +170,7 @@ func newFeishuRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_mo
|
|||||||
var pc payloadConvertor[FeishuPayload] = feishuConvertor{}
|
var pc payloadConvertor[FeishuPayload] = feishuConvertor{}
|
||||||
return newJSONRequest(pc, w, t, true)
|
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",
|
AvatarURL: "http://localhost:3000/user1/avatar",
|
||||||
},
|
},
|
||||||
Repository: nil,
|
Repository: nil,
|
||||||
Organization: &api.User{
|
Organization: &api.Organization{
|
||||||
UserName: "org1",
|
Name: "org1",
|
||||||
AvatarURL: "http://localhost:3000/org1/avatar",
|
AvatarURL: "http://localhost:3000/org1/avatar",
|
||||||
},
|
},
|
||||||
Package: &api.Package{
|
Package: &api.Package{
|
||||||
|
@ -24,6 +24,10 @@ import (
|
|||||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
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) {
|
func newMatrixRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
|
||||||
meta := &MatrixMeta{}
|
meta := &MatrixMeta{}
|
||||||
if err := json.Unmarshal([]byte(w.Meta), meta); err != nil {
|
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{}
|
var pc payloadConvertor[MSTeamsPayload] = msteamsConvertor{}
|
||||||
return newJSONRequest(pc, w, t, true)
|
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"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
|
"code.gitea.io/gitea/models/organization"
|
||||||
packages_model "code.gitea.io/gitea/models/packages"
|
packages_model "code.gitea.io/gitea/models/packages"
|
||||||
"code.gitea.io/gitea/models/perm"
|
"code.gitea.io/gitea/models/perm"
|
||||||
access_model "code.gitea.io/gitea/models/perm/access"
|
access_model "code.gitea.io/gitea/models/perm/access"
|
||||||
@ -924,9 +925,15 @@ func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_mo
|
|||||||
return
|
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{
|
if err := PrepareWebhooks(ctx, source, webhook_module.HookEventPackage, &api.PackagePayload{
|
||||||
Action: action,
|
Action: action,
|
||||||
Package: apiPackage,
|
Package: apiPackage,
|
||||||
|
Organization: org,
|
||||||
Sender: convert.ToUser(ctx, sender, nil),
|
Sender: convert.ToUser(ctx, sender, nil),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("PrepareWebhooks: %v", err)
|
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)
|
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)
|
return newJSONRequest(pc, w, t, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterWebhookRequester(webhook_module.SLACK, newSlackRequest)
|
||||||
|
}
|
||||||
|
|
||||||
var slackChannel = regexp.MustCompile(`^#?[a-z0-9_-]{1,80}$`)
|
var slackChannel = regexp.MustCompile(`^#?[a-z0-9_-]{1,80}$`)
|
||||||
|
|
||||||
// IsValidSlackChannel validates a channel name conforms to what slack expects:
|
// 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{}
|
var pc payloadConvertor[TelegramPayload] = telegramConvertor{}
|
||||||
return newJSONRequest(pc, w, t, true)
|
return newJSONRequest(pc, w, t, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterWebhookRequester(webhook_module.TELEGRAM, newTelegramRequest)
|
||||||
|
}
|
||||||
|
@ -27,16 +27,12 @@ import (
|
|||||||
"github.com/gobwas/glob"
|
"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){
|
type Requester func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error)
|
||||||
webhook_module.SLACK: newSlackRequest,
|
|
||||||
webhook_module.DISCORD: newDiscordRequest,
|
var webhookRequesters = map[webhook_module.HookType]Requester{}
|
||||||
webhook_module.DINGTALK: newDingtalkRequest,
|
|
||||||
webhook_module.TELEGRAM: newTelegramRequest,
|
func RegisterWebhookRequester(hookType webhook_module.HookType, requester Requester) {
|
||||||
webhook_module.MSTEAMS: newMSTeamsRequest,
|
webhookRequesters[hookType] = requester
|
||||||
webhook_module.FEISHU: newFeishuRequest,
|
|
||||||
webhook_module.MATRIX: newMatrixRequest,
|
|
||||||
webhook_module.WECHATWORK: newWechatworkRequest,
|
|
||||||
webhook_module.PACKAGIST: newPackagistRequest,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidHookTaskType returns true if a webhook registered
|
// 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{}
|
var pc payloadConvertor[WechatworkPayload] = wechatworkConvertor{}
|
||||||
return newJSONRequest(pc, w, t, true)
|
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"])
|
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) {
|
func TestAPIOrgRepoCreate(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
ctxUserID int64
|
ctxUserID int64
|
||||||
@ -488,11 +497,7 @@ func TestAPIOrgRepoCreate(t *testing.T) {
|
|||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
|
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
|
||||||
session := loginUser(t, user.Name)
|
session := loginUser(t, user.Name)
|
||||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository)
|
testAPIOrgCreateRepo(t, session, testCase.orgName, testCase.repoName, testCase.expectedStatus)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +172,19 @@ func TestAPIListWikiPages(t *testing.T) {
|
|||||||
assert.Equal(t, dummymeta, meta)
|
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) {
|
func TestAPINewWikiPage(t *testing.T) {
|
||||||
for _, title := range []string{
|
for _, title := range []string{
|
||||||
"New page",
|
"New page",
|
||||||
@ -180,16 +193,7 @@ func TestAPINewWikiPage(t *testing.T) {
|
|||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
username := "user2"
|
username := "user2"
|
||||||
session := loginUser(t, username)
|
session := loginUser(t, username)
|
||||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
testAPICreateWikiPage(t, session, username, "repo1", title, http.StatusCreated)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ func testIssueAddComment(t *testing.T, session *TestSession, issueURL, content,
|
|||||||
|
|
||||||
htmlDoc = NewHTMLParser(t, resp.Body)
|
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)
|
assert.Equal(t, content, val)
|
||||||
|
|
||||||
idAttr, has := htmlDoc.doc.Find(".comment-list .comment").Eq(commentCount).Attr("id")
|
idAttr, has := htmlDoc.doc.Find(".comment-list .comment").Eq(commentCount).Attr("id")
|
||||||
|
@ -4,10 +4,23 @@
|
|||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"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/models/webhook"
|
||||||
|
"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"
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
@ -39,3 +52,555 @@ 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 testCreateWebhookForRepo(t *testing.T, session *TestSession, webhookType, userName, repoName, url, eventKind string) {
|
||||||
|
csrf := GetUserCSRFToken(t, session)
|
||||||
|
req := NewRequestWithValues(t, "POST", "/"+userName+"/"+repoName+"/settings/hooks/"+webhookType+"/new", map[string]string{
|
||||||
|
"_csrf": csrf,
|
||||||
|
"payload_url": url,
|
||||||
|
"events": eventKind,
|
||||||
|
"active": "true",
|
||||||
|
"content_type": fmt.Sprintf("%d", webhook.ContentTypeJSON),
|
||||||
|
"http_method": "POST",
|
||||||
|
})
|
||||||
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
assert.Contains(t, r.Header["X-Github-Event"], "status", "X-GitHub-Event should contain status")
|
||||||
|
assert.Contains(t, r.Header["X-Gitea-Event"], "status", "X-Gitea-Event should contain status")
|
||||||
|
assert.Contains(t, r.Header["X-Gogs-Event"], "status", "X-Gogs-Event 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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_WebhookStatus_NoWrongTrigger(t *testing.T) {
|
||||||
|
var trigger string
|
||||||
|
provider := newMockWebhookProvider(func(r *http.Request) {
|
||||||
|
assert.NotContains(t, r.Header["X-Github-Event-Type"], "status", "X-GitHub-Event-Type should not contain status")
|
||||||
|
assert.NotContains(t, r.Header["X-Gitea-Event-Type"], "status", "X-Gitea-Event-Type should not contain status")
|
||||||
|
assert.NotContains(t, r.Header["X-Gogs-Event-Type"], "status", "X-Gogs-Event-Type should not contain status")
|
||||||
|
trigger = "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")
|
||||||
|
|
||||||
|
// create a push_only webhook from web UI
|
||||||
|
testCreateWebhookForRepo(t, session, "gitea", "user2", "repo1", provider.URL(), "push_only")
|
||||||
|
|
||||||
|
// 2. trigger the webhook with a push action
|
||||||
|
testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push")
|
||||||
|
|
||||||
|
// 3. validate the webhook is triggered with right event
|
||||||
|
assert.EqualValues(t, "push", trigger)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -26,6 +26,9 @@ TYPE = immediate
|
|||||||
[queue.push_update]
|
[queue.push_update]
|
||||||
TYPE = immediate
|
TYPE = immediate
|
||||||
|
|
||||||
|
[queue.webhook_sender]
|
||||||
|
TYPE = immediate
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/gitea-repositories
|
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mssql/gitea-repositories
|
||||||
|
|
||||||
@ -112,3 +115,6 @@ ENABLED = true
|
|||||||
|
|
||||||
[actions]
|
[actions]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
|
||||||
|
[webhook]
|
||||||
|
ALLOWED_HOST_LIST = 127.0.0.1
|
||||||
|
@ -28,6 +28,9 @@ TYPE = immediate
|
|||||||
[queue.push_update]
|
[queue.push_update]
|
||||||
TYPE = immediate
|
TYPE = immediate
|
||||||
|
|
||||||
|
[queue.webhook_sender]
|
||||||
|
TYPE = immediate
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/gitea-repositories
|
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/gitea-repositories
|
||||||
|
|
||||||
@ -119,3 +122,6 @@ REPLY_TO_ADDRESS = incoming+%{token}@localhost
|
|||||||
|
|
||||||
[actions]
|
[actions]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
|
||||||
|
[webhook]
|
||||||
|
ALLOWED_HOST_LIST = 127.0.0.1
|
||||||
|
@ -27,6 +27,9 @@ TYPE = immediate
|
|||||||
[queue.push_update]
|
[queue.push_update]
|
||||||
TYPE = immediate
|
TYPE = immediate
|
||||||
|
|
||||||
|
[queue.webhook_sender]
|
||||||
|
TYPE = immediate
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/gitea-repositories
|
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-pgsql/gitea-repositories
|
||||||
|
|
||||||
@ -128,3 +131,6 @@ ENABLED = true
|
|||||||
|
|
||||||
[actions]
|
[actions]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
|
||||||
|
[webhook]
|
||||||
|
ALLOWED_HOST_LIST = 127.0.0.1
|
||||||
|
@ -22,6 +22,9 @@ TYPE = immediate
|
|||||||
[queue.push_update]
|
[queue.push_update]
|
||||||
TYPE = immediate
|
TYPE = immediate
|
||||||
|
|
||||||
|
[queue.webhook_sender]
|
||||||
|
TYPE = immediate
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/gitea-repositories
|
ROOT = {{REPO_TEST_DIR}}tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/gitea-repositories
|
||||||
|
|
||||||
@ -117,3 +120,6 @@ RENDER_CONTENT_MODE=sanitized
|
|||||||
|
|
||||||
[actions]
|
[actions]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
|
||||||
|
[webhook]
|
||||||
|
ALLOWED_HOST_LIST = 127.0.0.1
|
||||||
|
Reference in New Issue
Block a user