Browse Source

Add tests for all webhooks (#16214)

* Added tests for MS Teams.

* Added tests for Dingtalk.

* Added tests for Telegram.

* Added tests for Feishu.

* Added tests for Discord.

* Added tests for closed issue and pullrequest comment.

* Added tests for Matrix.

* Trim all spaces.

* Added tests for Slack.

* Added JSONPayload tests.

* Added general tests.

* Replaced duplicated code.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
master
KN4CK3R 1 year ago
committed by GitHub
parent
commit
4fcae3d06d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 123
      services/webhook/dingtalk.go
  2. 201
      services/webhook/dingtalk_test.go
  3. 202
      services/webhook/discord.go
  4. 245
      services/webhook/discord_test.go
  5. 23
      services/webhook/feishu.go
  6. 172
      services/webhook/feishu_test.go
  7. 11
      services/webhook/general.go
  8. 464
      services/webhook/general_test.go
  9. 198
      services/webhook/matrix_test.go
  10. 479
      services/webhook/msteams.go
  11. 374
      services/webhook/msteams_test.go
  12. 114
      services/webhook/slack.go
  13. 186
      services/webhook/slack_test.go
  14. 51
      services/webhook/telegram.go
  15. 158
      services/webhook/telegram_test.go

123
services/webhook/dingtalk.go

@ -44,16 +44,7 @@ func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
refName := git.RefEndName(p.Ref)
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName,
},
}, nil
return createDingtalkPayload(title, title, fmt.Sprintf("view ref %s", refName), p.Repo.HTMLURL+"/src/"+refName), nil
}
// Delete implements PayloadConvertor Delete method
@ -62,32 +53,14 @@ func (d *DingtalkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
refName := git.RefEndName(p.Ref)
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName,
},
}, nil
return createDingtalkPayload(title, title, fmt.Sprintf("view ref %s", refName), p.Repo.HTMLURL+"/src/"+refName), nil
}
// Fork implements PayloadConvertor Fork method
func (d *DingtalkPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: fmt.Sprintf("view forked repo %s", p.Repo.FullName),
SingleURL: p.Repo.HTMLURL,
},
}, nil
return createDingtalkPayload(title, title, fmt.Sprintf("view forked repo %s", p.Repo.FullName), p.Repo.HTMLURL), nil
}
// Push implements PayloadConvertor Push method
@ -124,70 +97,32 @@ func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
strings.TrimRight(commit.Message, "\r\n")) + authorName
// add linebreak to each commit but the last
if i < len(p.Commits)-1 {
text += "\n"
text += "\r\n"
}
}
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text,
Title: title,
HideAvatar: "0",
SingleTitle: linkText,
SingleURL: titleLink,
},
}, nil
return createDingtalkPayload(title, text, linkText, titleLink), nil
}
// Issue implements PayloadConvertor Issue method
func (d *DingtalkPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true)
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text + "\r\n\r\n" + attachmentText,
//Markdown: "# " + title + "\n" + text,
Title: issueTitle,
HideAvatar: "0",
SingleTitle: "view issue",
SingleURL: p.Issue.HTMLURL,
},
}, nil
return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+attachmentText, "view issue", p.Issue.HTMLURL), nil
}
// IssueComment implements PayloadConvertor IssueComment method
func (d *DingtalkPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true)
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text + "\r\n\r\n" + p.Comment.Body,
Title: issueTitle,
HideAvatar: "0",
SingleTitle: "view issue comment",
SingleURL: p.Comment.HTMLURL,
},
}, nil
return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+p.Comment.Body, "view issue comment", p.Comment.HTMLURL), nil
}
// PullRequest implements PayloadConvertor PullRequest method
func (d *DingtalkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true)
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text + "\r\n\r\n" + attachmentText,
//Markdown: "# " + title + "\n" + text,
Title: issueTitle,
HideAvatar: "0",
SingleTitle: "view pull request",
SingleURL: p.PullRequest.HTMLURL,
},
}, nil
return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+attachmentText, "view pull request", p.PullRequest.HTMLURL), nil
}
// Review implements PayloadConvertor Review method
@ -205,37 +140,17 @@ func (d *DingtalkPayload) Review(p *api.PullRequestPayload, event models.HookEve
}
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title + "\r\n\r\n" + text,
Title: title,
HideAvatar: "0",
SingleTitle: "view pull request",
SingleURL: p.PullRequest.HTMLURL,
},
}, nil
return createDingtalkPayload(title, title+"\r\n\r\n"+text, "view pull request", p.PullRequest.HTMLURL), nil
}
// Repository implements PayloadConvertor Repository method
func (d *DingtalkPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
var title, url string
switch p.Action {
case api.HookRepoCreated:
title = fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
url = p.Repository.HTMLURL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view repository",
SingleURL: url,
},
}, nil
title := fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
return createDingtalkPayload(title, title, "view repository", p.Repository.HTMLURL), nil
case api.HookRepoDeleted:
title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
title := fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
return &DingtalkPayload{
MsgType: "text",
Text: struct {
@ -253,16 +168,20 @@ func (d *DingtalkPayload) Repository(p *api.RepositoryPayload) (api.Payloader, e
func (d *DingtalkPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true)
return createDingtalkPayload(text, text, "view release", p.Release.URL), nil
}
func createDingtalkPayload(title, text, singleTitle, singleURL string) *DingtalkPayload {
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text,
Title: text,
Text: strings.TrimSpace(text),
Title: strings.TrimSpace(title),
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: p.Release.URL,
SingleTitle: singleTitle,
SingleURL: singleURL,
},
}, nil
}
}
// GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload

201
services/webhook/dingtalk_test.go

@ -7,25 +7,202 @@ package webhook
import (
"testing"
"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetDingTalkIssuesPayload(t *testing.T) {
p := issueTestPayload()
d := new(DingtalkPayload)
p.Action = api.HookIssueOpened
pl, err := d.Issue(p)
func TestDingTalkPayload(t *testing.T) {
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
d := new(DingtalkPayload)
pl, err := d.Create(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] branch test created", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "[test/repo] branch test created", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view ref test", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
d := new(DingtalkPayload)
pl, err := d.Delete(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] branch test deleted", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "[test/repo] branch test deleted", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view ref test", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
d := new(DingtalkPayload)
pl, err := d.Fork(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view forked repo test/repo", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
d := new(DingtalkPayload)
pl, err := d.Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view commit 2020558...2020558", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
d := new(DingtalkPayload)
p.Action = api.HookIssueOpened
pl, err := d.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view issue", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*DingtalkPayload).ActionCard.SingleURL)
p.Action = api.HookIssueClosed
pl, err = d.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] Issue closed: #2 crash by user1", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view issue", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
d := new(DingtalkPayload)
pl, err := d.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view issue comment", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
d := new(DingtalkPayload)
pl, err := d.PullRequest(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "#12 Fix bug", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view pull request", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
d := new(DingtalkPayload)
pl, err := d.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "#12 Fix bug", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view issue comment", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
d := new(DingtalkPayload)
pl, err := d.Review(p, models.HookEventPullRequestReviewApproved)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view pull request", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
d := new(DingtalkPayload)
pl, err := d.Repository(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] Repository created", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "[test/repo] Repository created", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view repository", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/test/repo", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
d := new(DingtalkPayload)
pl, err := d.Release(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl)
assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.(*DingtalkPayload).ActionCard.Text)
assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "view release", pl.(*DingtalkPayload).ActionCard.SingleTitle)
assert.Equal(t, "http://localhost:3000/api/v1/repos/test/repo/releases/2", pl.(*DingtalkPayload).ActionCard.SingleURL)
})
}
func TestDingTalkJSONPayload(t *testing.T) {
p := pushTestPayload()
pl, err := new(DingtalkPayload).Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\r\n\r\n", pl.(*DingtalkPayload).ActionCard.Text)
require.IsType(t, &DingtalkPayload{}, pl)
p.Action = api.HookIssueClosed
pl, err = d.Issue(p)
json, err := pl.JSONPayload()
require.NoError(t, err)
require.NotNil(t, pl)
assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
assert.Equal(t, "[test/repo] Issue closed: #2 crash by user1\r\n\r\n", pl.(*DingtalkPayload).ActionCard.Text)
assert.NotEmpty(t, json)
}

202
services/webhook/discord.go

@ -120,22 +120,7 @@ func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
refName := git.RefEndName(p.Ref)
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
URL: p.Repo.HTMLURL + "/src/" + refName,
Color: greenColor,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, "", p.Repo.HTMLURL+"/src/"+refName, greenColor), nil
}
// Delete implements PayloadConvertor Delete method
@ -144,44 +129,14 @@ func (d *DiscordPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
refName := git.RefEndName(p.Ref)
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
URL: p.Repo.HTMLURL + "/src/" + refName,
Color: redColor,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, "", p.Repo.HTMLURL+"/src/"+refName, redColor), nil
}
// Fork implements PayloadConvertor Fork method
func (d *DiscordPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
URL: p.Repo.HTMLURL,
Color: greenColor,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, "", p.Repo.HTMLURL, greenColor), nil
}
// Push implements PayloadConvertor Push method
@ -216,92 +171,28 @@ func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
}
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
Description: text,
URL: titleLink,
Color: greenColor,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, text, titleLink, greenColor), nil
}
// Issue implements PayloadConvertor Issue method
func (d *DiscordPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
text, _, attachmentText, color := getIssuesPayloadInfo(p, noneLinkFormatter, false)
title, _, text, color := getIssuesPayloadInfo(p, noneLinkFormatter, false)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: text,
Description: attachmentText,
URL: p.Issue.HTMLURL,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, text, p.Issue.HTMLURL, color), nil
}
// IssueComment implements PayloadConvertor IssueComment method
func (d *DiscordPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
text, _, color := getIssueCommentPayloadInfo(p, noneLinkFormatter, false)
title, _, color := getIssueCommentPayloadInfo(p, noneLinkFormatter, false)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: text,
Description: p.Comment.Body,
URL: p.Comment.HTMLURL,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, p.Comment.Body, p.Comment.HTMLURL, color), nil
}
// PullRequest implements PayloadConvertor PullRequest method
func (d *DiscordPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
text, _, attachmentText, color := getPullRequestPayloadInfo(p, noneLinkFormatter, false)
title, _, text, color := getPullRequestPayloadInfo(p, noneLinkFormatter, false)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: text,
Description: attachmentText,
URL: p.PullRequest.HTMLURL,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, text, p.PullRequest.HTMLURL, color), nil
}
// Review implements PayloadConvertor Review method
@ -330,23 +221,7 @@ func (d *DiscordPayload) Review(p *api.PullRequestPayload, event models.HookEven
}
}
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
Description: text,
URL: p.PullRequest.HTMLURL,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, text, p.PullRequest.HTMLURL, color), nil
}
// Repository implements PayloadConvertor Repository method
@ -363,45 +238,14 @@ func (d *DiscordPayload) Repository(p *api.RepositoryPayload) (api.Payloader, er
color = redColor
}
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
URL: url,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, title, "", url, color), nil
}
// Release implements PayloadConvertor Release method
func (d *DiscordPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
text, color := getReleasePayloadInfo(p, noneLinkFormatter, false)
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: text,
Description: p.Release.Note,
URL: p.Release.URL,
Color: color,
Author: DiscordEmbedAuthor{
Name: p.Sender.UserName,
URL: setting.AppURL + p.Sender.UserName,
IconURL: p.Sender.AvatarURL,
},
},
},
}, nil
return d.createPayload(p.Sender, text, p.Release.Note, p.Release.URL, color), nil
}
// GetDiscordPayload converts a discord webhook into a DiscordPayload
@ -433,3 +277,23 @@ func parseHookPullRequestEventType(event models.HookEventType) (string, error) {
return "", errors.New("unknown event type")
}
}
func (d *DiscordPayload) createPayload(s *api.User, title, text, url string, color int) *DiscordPayload {
return &DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
{
Title: title,
Description: text,
URL: url,
Color: color,
Author: DiscordEmbedAuthor{
Name: s.UserName,
URL: setting.AppURL + s.UserName,
IconURL: s.AvatarURL,
},
},
},
}
}

245
services/webhook/discord_test.go

@ -0,0 +1,245 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package webhook
import (
"testing"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDiscordPayload(t *testing.T) {
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
d := new(DiscordPayload)
pl, err := d.Create(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] branch test created", pl.(*DiscordPayload).Embeds[0].Title)
assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
d := new(DiscordPayload)
pl, err := d.Delete(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] branch test deleted", pl.(*DiscordPayload).Embeds[0].Title)
assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
d := new(DiscordPayload)
pl, err := d.Fork(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*DiscordPayload).Embeds[0].Title)
assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
d := new(DiscordPayload)
pl, err := d.Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
d := new(DiscordPayload)
p.Action = api.HookIssueOpened
pl, err := d.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "issue body", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
p.Action = api.HookIssueClosed
pl, err = d.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.(*DiscordPayload).Embeds[0].Title)
assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
d := new(DiscordPayload)
pl, err := d.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "more info needed", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
d := new(DiscordPayload)
pl, err := d.PullRequest(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "fixes bug #2", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
d := new(DiscordPayload)
pl, err := d.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "changes requested", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
d := new(DiscordPayload)
pl, err := d.Review(p, models.HookEventPullRequestReviewApproved)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "good job", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
d := new(DiscordPayload)
pl, err := d.Repository(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] Repository created", pl.(*DiscordPayload).Embeds[0].Title)
assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/test/repo", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
d := new(DiscordPayload)
pl, err := d.Release(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
assert.Equal(t, "[test/repo] Release created: v1.0", pl.(*DiscordPayload).Embeds[0].Title)
assert.Equal(t, "Note of first stable release", pl.(*DiscordPayload).Embeds[0].Description)
assert.Equal(t, "http://localhost:3000/api/v1/repos/test/repo/releases/2", pl.(*DiscordPayload).Embeds[0].URL)
assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
})
}
func TestDiscordJSONPayload(t *testing.T) {
p := pushTestPayload()
pl, err := new(DiscordPayload).Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl)
json, err := pl.JSONPayload()
require.NoError(t, err)
assert.NotEmpty(t, json)
}

23
services/webhook/feishu.go

@ -30,7 +30,7 @@ func newFeishuTextPayload(text string) *FeishuPayload {
Content: struct {
Text string `json:"text"`
}{
Text: text,
Text: strings.TrimSpace(text),
},
}
}
@ -84,7 +84,7 @@ func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) {
commitDesc string
)
var text = fmt.Sprintf("[%s:%s] %s\n", p.Repo.FullName, branchName, commitDesc)
var text = fmt.Sprintf("[%s:%s] %s\r\n", p.Repo.FullName, branchName, commitDesc)
// for each commit, generate attachment text
for i, commit := range p.Commits {
var authorName string
@ -95,7 +95,7 @@ func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) {
strings.TrimRight(commit.Message, "\r\n")) + authorName
// add linebreak to each commit but the last
if i < len(p.Commits)-1 {
text += "\n"
text += "\r\n"
}
}
@ -125,19 +125,14 @@ func (f *FeishuPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, e
// Review implements PayloadConvertor Review method
func (f *FeishuPayload) Review(p *api.PullRequestPayload, event models.HookEventType) (api.Payloader, error) {
var text, title string
switch p.Action {
case api.HookIssueSynchronized:
action, err := parseHookPullRequestEventType(event)
if err != nil {
return nil, err
}
title = fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
text = p.Review.Content
action, err := parseHookPullRequestEventType(event)
if err != nil {
return nil, err
}
title := fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
text := p.Review.Content
return newFeishuTextPayload(title + "\r\n\r\n" + text), nil
}

172
services/webhook/feishu_test.go

@ -0,0 +1,172 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package webhook
import (
"testing"
"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFeishuPayload(t *testing.T) {
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
d := new(FeishuPayload)
pl, err := d.Create(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, `[test/repo] branch test created`, pl.(*FeishuPayload).Content.Text)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
d := new(FeishuPayload)
pl, err := d.Delete(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, `[test/repo] branch test deleted`, pl.(*FeishuPayload).Content.Text)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
d := new(FeishuPayload)
pl, err := d.Fork(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, `test/repo2 is forked to test/repo`, pl.(*FeishuPayload).Content.Text)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
d := new(FeishuPayload)
pl, err := d.Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "[test/repo:test] \r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*FeishuPayload).Content.Text)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
d := new(FeishuPayload)
p.Action = api.HookIssueOpened
pl, err := d.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "#2 crash\r\n[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", pl.(*FeishuPayload).Content.Text)
p.Action = api.HookIssueClosed
pl, err = d.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "#2 crash\r\n[test/repo] Issue closed: #2 crash by user1", pl.(*FeishuPayload).Content.Text)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
d := new(FeishuPayload)
pl, err := d.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "#2 crash\r\n[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", pl.(*FeishuPayload).Content.Text)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
d := new(FeishuPayload)
pl, err := d.PullRequest(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "#12 Fix bug\r\n[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", pl.(*FeishuPayload).Content.Text)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
d := new(FeishuPayload)
pl, err := d.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "#12 Fix bug\r\n[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", pl.(*FeishuPayload).Content.Text)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
d := new(FeishuPayload)
pl, err := d.Review(p, models.HookEventPullRequestReviewApproved)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.(*FeishuPayload).Content.Text)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
d := new(FeishuPayload)
pl, err := d.Repository(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "[test/repo] Repository created", pl.(*FeishuPayload).Content.Text)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
d := new(FeishuPayload)
pl, err := d.Release(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.(*FeishuPayload).Content.Text)
})
}
func TestFeishuJSONPayload(t *testing.T) {
p := pushTestPayload()
pl, err := new(FeishuPayload).Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl)
json, err := pl.JSONPayload()
require.NoError(t, err)
assert.NotEmpty(t, json)
}

11
services/webhook/general.go

@ -44,8 +44,11 @@ func getIssuesPayloadInfo(p *api.IssuePayload, linkFormatter linkFormatter, with
case api.HookIssueEdited:
text = fmt.Sprintf("[%s] Issue edited: %s", repoLink, titleLink)
case api.HookIssueAssigned:
text = fmt.Sprintf("[%s] Issue assigned to %s: %s", repoLink,
linkFormatter(setting.AppURL+p.Issue.Assignee.UserName, p.Issue.Assignee.UserName), titleLink)
list := make([]string, len(p.Issue.Assignees))
for i, user := range p.Issue.Assignees {
list[i] = linkFormatter(setting.AppURL+user.UserName, user.UserName)
}
text = fmt.Sprintf("[%s] Issue assigned to %s: %s", repoLink, strings.Join(list, ", "), titleLink)
color = greenColor
case api.HookIssueUnassigned:
text = fmt.Sprintf("[%s] Issue unassigned: %s", repoLink, titleLink)
@ -102,7 +105,7 @@ func getPullRequestPayloadInfo(p *api.PullRequestPayload, linkFormatter linkForm
for i, user := range p.PullRequest.Assignees {
list[i] = linkFormatter(setting.AppURL+user.UserName, user.UserName)
}
text = fmt.Sprintf("[%s] Pull request assigned: %s to %s", repoLink,
text = fmt.Sprintf("[%s] Pull request assigned to %s: %s", repoLink,
strings.Join(list, ", "), titleLink)
color = greenColor
case api.HookIssueUnassigned:
@ -115,7 +118,7 @@ func getPullRequestPayloadInfo(p *api.PullRequestPayload, linkFormatter linkForm
text = fmt.Sprintf("[%s] Pull request synchronized: %s", repoLink, titleLink)
case api.HookIssueMilestoned:
mileStoneLink := fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.PullRequest.Milestone.ID)
text = fmt.Sprintf("[%s] Pull request milestoned: %s to %s", repoLink,
text = fmt.Sprintf("[%s] Pull request milestoned to %s: %s", repoLink,
linkFormatter(mileStoneLink, p.PullRequest.Milestone.Title), titleLink)
case api.HookIssueDemilestoned:
text = fmt.Sprintf("[%s] Pull request milestone cleared: %s", repoLink, titleLink)

464
services/webhook/general_test.go

@ -5,14 +5,111 @@
package webhook
import (
"testing"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
)
func createTestPayload() *api.CreatePayload {
return &api.CreatePayload{
Sha: "2020558fe2e34debb818a514715839cabd25e777",
Ref: "refs/heads/test",
RefType: "branch",
Repo: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
Name: "repo",
FullName: "test/repo",
},
Sender: &api.User{
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
}
}
func deleteTestPayload() *api.DeletePayload {
return &api.DeletePayload{
Ref: "refs/heads/test",
RefType: "branch",
Repo: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
Name: "repo",
FullName: "test/repo",
},
Sender: &api.User{
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
}
}
func forkTestPayload() *api.ForkPayload {
return &api.ForkPayload{
Forkee: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo2",
Name: "repo2",
FullName: "test/repo2",
},
Repo: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
Name: "repo",
FullName: "test/repo",
},
Sender: &api.User{
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
}
}
func pushTestPayload() *api.PushPayload {
commit := &api.PayloadCommit{
ID: "2020558fe2e34debb818a514715839cabd25e778",
Message: "commit message",
URL: "http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778",
Author: &api.PayloadUser{
Name: "user1",
Email: "user1@localhost",
UserName: "user1",
},
Committer: &api.PayloadUser{
Name: "user1",
Email: "user1@localhost",
UserName: "user1",
},
}
return &api.PushPayload{
Ref: "refs/heads/test",
Before: "2020558fe2e34debb818a514715839cabd25e777",
After: "2020558fe2e34debb818a514715839cabd25e778",
CompareURL: "",
HeadCommit: commit,
Commits: []*api.PayloadCommit{commit, commit},
Repo: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
Name: "repo",
FullName: "test/repo",
},
Pusher: &api.User{
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
Sender: &api.User{
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
}
}
func issueTestPayload() *api.IssuePayload {
return &api.IssuePayload{
Index: 2,
Sender: &api.User{
UserName: "user1",
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
Repository: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
@ -20,10 +117,23 @@ func issueTestPayload() *api.IssuePayload {
FullName: "test/repo",
},
Issue: &api.Issue{
ID: 2,
Index: 2,
URL: "http://localhost:3000/api/v1/repos/test/repo/issues/2",
Title: "crash",
ID: 2,
Index: 2,
URL: "http://localhost:3000/api/v1/repos/test/repo/issues/2",
HTMLURL: "http://localhost:3000/test/repo/issues/2",
Title: "crash",
Body: "issue body",
Assignees: []*api.User{
{
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
},
Milestone: &api.Milestone{
ID: 1,
Title: "Milestone Title",
Description: "Milestone Description",
},
},
}
}
@ -32,7 +142,8 @@ func issueCommentTestPayload() *api.IssueCommentPayload {
return &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated,
Sender: &api.User{
UserName: "user1",
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
Repository: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
@ -45,11 +156,12 @@ func issueCommentTestPayload() *api.IssueCommentPayload {
Body: "more info needed",
},
Issue: &api.Issue{
ID: 2,
Index: 2,
URL: "http://localhost:3000/api/v1/repos/test/repo/issues/2",
Title: "crash",
Body: "this happened",
ID: 2,
Index: 2,
URL: "http://localhost:3000/api/v1/repos/test/repo/issues/2",
HTMLURL: "http://localhost:3000/test/repo/issues/2",
Title: "crash",
Body: "this happened",
},
}
}
@ -58,7 +170,8 @@ func pullRequestCommentTestPayload() *api.IssueCommentPayload {
return &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated,
Sender: &api.User{
UserName: "user1",
UserName: "user1",
AvatarURL: "http://localhost:3000/user1/avatar",
},
Repository: &api.Repository{
HTMLURL: "http://localhost:3000/test/repo",
@ -66,16 +179,17 @@ func pullRequestCommentTestPayload() *api.IssueCommentPayload {
FullName: "test/repo",
},
Comment: &api.Comment{
HTMLURL: "http://localhost:3000/test/repo/pulls/2#issuecomment-4",
PRURL: "http://localhost:3000/test/repo/pulls/2",
HTMLURL: "http://localhost:3000/test/repo/pulls/12#issuecomment-4",
PRURL: "http://localhost:3000/test/repo/pulls/12",
Body: "changes requested",
},
Issue: &api.Issue{
ID: 2,
Index: 2,
URL: "http://localhost:3000/api/v1/repos/test/repo/issues/2",
Title: "Fix bug",
Body: "fixes bug #2",
ID: 12,
Index: 12,
URL: "http://localhost:3000/api/v1/repos/test/repo/pulls/12",
HTMLURL: "http://localhost:3000/test/repo/pulls/12",
Title: "Fix bug",
Body: "fixes bug #2",
},
IsPull: true,
}
@ -85,7 +199,8 @@ func pullReleaseTestPayload() *api.ReleasePayload {
return &api.ReleasePayload{
Action: api.HookReleasePublished,
Sender: &api.User{
UserName: "user1",
UserName: "user1",