[PLT-6676] Make OutgoingWebhook to fire when post has no text content but only attachment (#6935)
* make OutgoingWebhook to fire when post has no text content but only attachment * update per comment and modify payload & test
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
8fb58b1fc9
Коммит
21a3219b9b
@@ -4,9 +4,13 @@
|
||||
package api4
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -101,6 +105,158 @@ func TestCreatePost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testCreatePostWithOutgoingHook(
|
||||
t *testing.T,
|
||||
hookContentType, expectedContentType, message, triggerWord string,
|
||||
fileIds []string,
|
||||
triggerWhen int,
|
||||
) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
defer TearDown()
|
||||
user := th.SystemAdminUser
|
||||
team := th.BasicTeam
|
||||
channel := th.BasicChannel
|
||||
|
||||
enableOutgoingHooks := utils.Cfg.ServiceSettings.EnableOutgoingWebhooks
|
||||
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
|
||||
defer func() {
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
|
||||
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
|
||||
utils.SetDefaultRolesBasedOnConfig()
|
||||
}()
|
||||
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
|
||||
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
|
||||
utils.SetDefaultRolesBasedOnConfig()
|
||||
|
||||
var hook *model.OutgoingWebhook
|
||||
var post *model.Post
|
||||
|
||||
// Create a test server that is the target of the outgoing webhook. It will
|
||||
// validate the webhook body fields and write to the success channel on
|
||||
// success/failure.
|
||||
success := make(chan bool)
|
||||
wait := make(chan bool, 1)
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
<-wait
|
||||
|
||||
requestContentType := r.Header.Get("Content-Type")
|
||||
if requestContentType != expectedContentType {
|
||||
t.Logf("Content-Type is %s, should be %s", requestContentType, expectedContentType)
|
||||
success <- false
|
||||
return
|
||||
}
|
||||
|
||||
expectedPayload := &model.OutgoingWebhookPayload{
|
||||
Token: hook.Token,
|
||||
TeamId: hook.TeamId,
|
||||
TeamDomain: team.Name,
|
||||
ChannelId: post.ChannelId,
|
||||
ChannelName: channel.Name,
|
||||
Timestamp: post.CreateAt,
|
||||
UserId: post.UserId,
|
||||
UserName: user.Username,
|
||||
PostId: post.Id,
|
||||
Text: post.Message,
|
||||
TriggerWord: triggerWord,
|
||||
FileIds: strings.Join(post.FileIds, ","),
|
||||
}
|
||||
|
||||
// depending on the Content-Type, we expect to find a JSON or form encoded payload
|
||||
if requestContentType == "application/json" {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
o := &model.OutgoingWebhookPayload{}
|
||||
decoder.Decode(&o)
|
||||
|
||||
if !reflect.DeepEqual(expectedPayload, o) {
|
||||
t.Logf("JSON payload is %+v, should be %+v", o, expectedPayload)
|
||||
success <- false
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
t.Logf("Error parsing form: %q", err)
|
||||
success <- false
|
||||
return
|
||||
}
|
||||
|
||||
expectedFormValues, _ := url.ParseQuery(expectedPayload.ToFormValues())
|
||||
if !reflect.DeepEqual(expectedFormValues, r.Form) {
|
||||
t.Logf("Form values are: %q\n, should be: %q\n", r.Form, expectedFormValues)
|
||||
success <- false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
success <- true
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
// create an outgoing webhook, passing it the test server URL
|
||||
var triggerWords []string
|
||||
if triggerWord != "" {
|
||||
triggerWords = []string{triggerWord}
|
||||
}
|
||||
|
||||
hook = &model.OutgoingWebhook{
|
||||
ChannelId: channel.Id,
|
||||
TeamId: team.Id,
|
||||
ContentType: hookContentType,
|
||||
TriggerWords: triggerWords,
|
||||
TriggerWhen: triggerWhen,
|
||||
CallbackURLs: []string{ts.URL},
|
||||
}
|
||||
|
||||
hook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
// create a post to trigger the webhook
|
||||
post = &model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: message,
|
||||
FileIds: fileIds,
|
||||
}
|
||||
|
||||
post, resp = th.SystemAdminClient.CreatePost(post)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
wait <- true
|
||||
|
||||
// We wait for the test server to write to the success channel and we make
|
||||
// the test fail if that doesn't happen before the timeout.
|
||||
select {
|
||||
case ok := <-success:
|
||||
if !ok {
|
||||
t.Fatal("Test server did send an invalid webhook.")
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("Timeout, test server did not send the webhook.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreatePostWithOutgoingHook_form_urlencoded(t *testing.T) {
|
||||
testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH)
|
||||
testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH)
|
||||
testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "", "", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH)
|
||||
testCreatePostWithOutgoingHook(t, "application/x-www-form-urlencoded", "application/x-www-form-urlencoded", "", "", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH)
|
||||
}
|
||||
|
||||
func TestCreatePostWithOutgoingHook_json(t *testing.T) {
|
||||
testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerword lorem ipsum", "triggerword", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_EXACT_MATCH)
|
||||
testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_STARTS_WITH)
|
||||
testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerword lorem ipsum", "", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH)
|
||||
testCreatePostWithOutgoingHook(t, "application/json", "application/json", "triggerwordaaazzz lorem ipsum", "", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH)
|
||||
}
|
||||
|
||||
// hooks created before we added the ContentType field should be considered as
|
||||
// application/x-www-form-urlencoded
|
||||
func TestCreatePostWithOutgoingHook_no_content_type(t *testing.T) {
|
||||
testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_EXACT_MATCH)
|
||||
testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "triggerword", []string{"file_id_1"}, app.TRIGGERWORDS_STARTS_WITH)
|
||||
testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerword lorem ipsum", "", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_EXACT_MATCH)
|
||||
testCreatePostWithOutgoingHook(t, "", "application/x-www-form-urlencoded", "triggerwordaaazzz lorem ipsum", "", []string{"file_id_1, file_id_2"}, app.TRIGGERWORDS_STARTS_WITH)
|
||||
}
|
||||
|
||||
func TestUpdatePost(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
defer TearDown()
|
||||
|
||||
Ссылка в новой задаче
Block a user