Add test for webhook (#29755)

Follow #29690
pull/29709/head^2
wxiaoguang 11 months ago committed by GitHub
parent 83ba882bab
commit 43de021ac1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -212,3 +212,12 @@ func ToFloat64(number any) (float64, error) {
func ToPointer[T any](val T) *T { func ToPointer[T any](val T) *T {
return &val return &val
} }
// IfZero returns "def" if "v" is a zero value, otherwise "v"
func IfZero[T comparable](v, def T) T {
var zero T
if v == zero {
return def
}
return v
}

@ -18,6 +18,7 @@ import (
webhook_model "code.gitea.io/gitea/models/webhook" webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/hostmatcher" "code.gitea.io/gitea/modules/hostmatcher"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook" webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -227,48 +228,28 @@ func TestWebhookDeliverSpecificTypes(t *testing.T) {
type hookCase struct { type hookCase struct {
gotBody chan []byte gotBody chan []byte
httpMethod string // default to POST
} }
cases := map[string]hookCase{ cases := map[string]*hookCase{
webhook_module.SLACK: { webhook_module.SLACK: {},
gotBody: make(chan []byte, 1), webhook_module.DISCORD: {},
}, webhook_module.DINGTALK: {},
webhook_module.DISCORD: { webhook_module.TELEGRAM: {},
gotBody: make(chan []byte, 1), webhook_module.MSTEAMS: {},
}, webhook_module.FEISHU: {},
webhook_module.DINGTALK: { webhook_module.MATRIX: {httpMethod: "PUT"},
gotBody: make(chan []byte, 1), webhook_module.WECHATWORK: {},
}, webhook_module.PACKAGIST: {},
webhook_module.TELEGRAM: {
gotBody: make(chan []byte, 1),
},
webhook_module.MSTEAMS: {
gotBody: make(chan []byte, 1),
},
webhook_module.FEISHU: {
gotBody: make(chan []byte, 1),
},
webhook_module.MATRIX: {
gotBody: make(chan []byte, 1),
},
webhook_module.WECHATWORK: {
gotBody: make(chan []byte, 1),
},
webhook_module.PACKAGIST: {
gotBody: make(chan []byte, 1),
},
} }
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
typ := strings.Split(r.URL.Path, "/")[1] // URL: "/{webhook_type}/other-path"
assert.Equal(t, "application/json", r.Header.Get("Content-Type"), r.URL.Path) assert.Equal(t, "application/json", r.Header.Get("Content-Type"), r.URL.Path)
assert.Equal(t, util.IfZero(cases[typ].httpMethod, "POST"), r.Method, "webhook test request %q", r.URL.Path)
typ := strings.Split(r.URL.Path, "/")[1] // take first segment (after skipping leading slash) body, _ := io.ReadAll(r.Body) // read request and send it back to the test by testcase's chan
hc := cases[typ] cases[typ].gotBody <- body
require.NotNil(t, hc.gotBody, r.URL.Path) w.WriteHeader(http.StatusNoContent)
body, err := io.ReadAll(r.Body)
assert.NoError(t, err)
w.WriteHeader(200)
hc.gotBody <- body
})) }))
t.Cleanup(s.Close) t.Cleanup(s.Close)
@ -276,9 +257,9 @@ func TestWebhookDeliverSpecificTypes(t *testing.T) {
data, err := p.JSONPayload() data, err := p.JSONPayload()
assert.NoError(t, err) assert.NoError(t, err)
for typ, hc := range cases { for typ := range cases {
typ := typ cases[typ].gotBody = make(chan []byte, 1)
hc := hc typ := typ // TODO: remove this workaround when Go >= 1.22
t.Run(typ, func(t *testing.T) { t.Run(typ, func(t *testing.T) {
t.Parallel() t.Parallel()
hook := &webhook_model.Webhook{ hook := &webhook_model.Webhook{
@ -286,8 +267,6 @@ func TestWebhookDeliverSpecificTypes(t *testing.T) {
IsActive: true, IsActive: true,
Type: typ, Type: typ,
URL: s.URL + "/" + typ, URL: s.URL + "/" + typ,
HTTPMethod: "POST",
ContentType: 0, // set to 0 so that falling back to default request fails with "invalid content type"
Meta: "{}", Meta: "{}",
} }
assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook)) assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook))
@ -304,10 +283,11 @@ func TestWebhookDeliverSpecificTypes(t *testing.T) {
assert.NotNil(t, hookTask) assert.NotNil(t, hookTask)
assert.NoError(t, Deliver(context.Background(), hookTask)) assert.NoError(t, Deliver(context.Background(), hookTask))
select { select {
case gotBody := <-hc.gotBody: case gotBody := <-cases[typ].gotBody:
assert.NotEqual(t, string(data), string(gotBody), "request body must be different from the event payload") assert.NotEqual(t, string(data), string(gotBody), "request body must be different from the event payload")
assert.Equal(t, hookTask.RequestInfo.Body, string(gotBody), "request body was not saved") assert.Equal(t, hookTask.RequestInfo.Body, string(gotBody), "delivered webhook payload doesn't match saved request")
case <-time.After(5 * time.Second): case <-time.After(5 * time.Second):
t.Fatal("waited to long for request to happen") t.Fatal("waited to long for request to happen")
} }

Loading…
Cancel
Save