Implement create and get incoming webhook endpoints for APIv4 (#5407)

* Implement POST /hooks/incoming endpoint for APIv4

* Implement GET /hooks/incoming endpoint for APIv4

* Updates per feedback
Этот коммит содержится в:
Joram Wilander
2017-02-21 19:42:34 -05:00
коммит произвёл GitHub
родитель b61115df55
Коммит 69cac604e0
11 изменённых файлов: 414 добавлений и 51 удалений

Просмотреть файл

@@ -37,37 +37,23 @@ func InitWebhook() {
} }
func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
c.Err = model.NewLocAppError("createIncomingHook", "api.webhook.create_incoming.disabled.app_errror", nil, "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
c.LogAudit("attempt")
hook := model.IncomingWebhookFromJson(r.Body) hook := model.IncomingWebhookFromJson(r.Body)
if hook == nil { if hook == nil {
c.SetInvalidParam("createIncomingHook", "webhook") c.SetInvalidParam("createIncomingHook", "webhook")
return return
} }
cchan := app.Srv.Store.Channel().Get(hook.ChannelId, true) channel, err := app.GetChannel(hook.ChannelId)
if err != nil {
hook.UserId = c.Session.UserId c.Err = err
hook.TeamId = c.TeamId return
}
var channel *model.Channel
if result := <-cchan; result.Err != nil { c.LogAudit("attempt")
c.Err = result.Err
if !app.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return return
} else {
channel = result.Data.(*model.Channel)
} }
if channel.Type != model.CHANNEL_OPEN && !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) { if channel.Type != model.CHANNEL_OPEN && !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
@@ -76,13 +62,12 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
if result := <-app.Srv.Store.Webhook().SaveIncoming(hook); result.Err != nil { if incomingHook, err := app.CreateIncomingWebhookForChannel(c.Session.UserId, channel, hook); err != nil {
c.Err = result.Err c.Err = err
return return
} else { } else {
c.LogAudit("success") c.LogAudit("success")
rhook := result.Data.(*model.IncomingWebhook) w.Write([]byte(incomingHook.ToJson()))
w.Write([]byte(rhook.ToJson()))
} }
} }
@@ -132,23 +117,15 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
} }
func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) { func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
c.Err = model.NewLocAppError("getIncomingHooks", "api.webhook.get_incoming.disabled.app_error", nil, "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("getIncomingHooks", "api.command.admin_only.app_error", nil, "") c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
c.Err.StatusCode = http.StatusForbidden
return return
} }
if result := <-app.Srv.Store.Webhook().GetIncomingByTeam(c.TeamId); result.Err != nil { if hooks, err := app.GetIncomingWebhooksForTeamPage(c.TeamId, 0, 100); err != nil {
c.Err = result.Err c.Err = err
return return
} else { } else {
hooks := result.Data.([]*model.IncomingWebhook)
w.Write([]byte(model.IncomingWebhookListToJson(hooks))) w.Write([]byte(model.IncomingWebhookListToJson(hooks)))
} }
} }

Просмотреть файл

@@ -52,11 +52,11 @@ type Routes struct {
Command *mux.Router // 'api/v4/commands/{command_id:[A-Za-z0-9]+}' Command *mux.Router // 'api/v4/commands/{command_id:[A-Za-z0-9]+}'
CommandsForTeam *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}/commands' CommandsForTeam *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}/commands'
Hooks *mux.Router // 'api/v4/teams/hooks' Hooks *mux.Router // 'api/v4/hooks'
IncomingHooks *mux.Router // 'api/v4/teams/hooks/incoming' IncomingHooks *mux.Router // 'api/v4/hooks/incoming'
IncomingHook *mux.Router // 'api/v4/teams/hooks/incoming/{hook_id:[A-Za-z0-9]+}' IncomingHook *mux.Router // 'api/v4/hooks/incoming/{hook_id:[A-Za-z0-9]+}'
OutgoingHooks *mux.Router // 'api/v4/teams/hooks/outgoing' OutgoingHooks *mux.Router // 'api/v4/hooks/outgoing'
OutgoingHook *mux.Router // 'api/v4/teams/hooks/outgoing/{hook_id:[A-Za-z0-9]+}' OutgoingHook *mux.Router // 'api/v4/hooks/outgoing/{hook_id:[A-Za-z0-9]+}'
OAuth *mux.Router // 'api/v4/oauth' OAuth *mux.Router // 'api/v4/oauth'
@@ -145,6 +145,7 @@ func InitApi(full bool) {
InitPost() InitPost()
InitFile() InitFile()
InitSystem() InitSystem()
InitWebhook()
app.Srv.Router.Handle("/api/v4/{anything:.*}", http.HandlerFunc(Handle404)) app.Srv.Router.Handle("/api/v4/{anything:.*}", http.HandlerFunc(Handle404))

Просмотреть файл

@@ -422,6 +422,21 @@ func CheckBadRequestStatus(t *testing.T, resp *model.Response) {
} }
} }
func CheckNotImplementedStatus(t *testing.T, resp *model.Response) {
if resp.Error == nil {
debug.PrintStack()
t.Fatal("should have errored with status:" + strconv.Itoa(http.StatusNotImplemented))
return
}
if resp.StatusCode != http.StatusNotImplemented {
debug.PrintStack()
t.Log("actual: " + strconv.Itoa(resp.StatusCode))
t.Log("expected: " + strconv.Itoa(http.StatusNotImplemented))
t.Fatal("wrong status code")
}
}
func CheckErrorMessage(t *testing.T, resp *model.Response, errorId string) { func CheckErrorMessage(t *testing.T, resp *model.Response, errorId string) {
if resp.Error == nil { if resp.Error == nil {
debug.PrintStack() debug.PrintStack()

85
api4/webhook.go Обычный файл
Просмотреть файл

@@ -0,0 +1,85 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api4
import (
"net/http"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func InitWebhook() {
l4g.Debug(utils.T("api.webhook.init.debug"))
BaseRoutes.IncomingHooks.Handle("", ApiSessionRequired(createIncomingHook)).Methods("POST")
BaseRoutes.IncomingHooks.Handle("", ApiSessionRequired(getIncomingHooks)).Methods("GET")
}
func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
hook := model.IncomingWebhookFromJson(r.Body)
if hook == nil {
c.SetInvalidParam("webhook")
return
}
channel, err := app.GetChannel(hook.ChannelId)
if err != nil {
c.Err = err
return
}
c.LogAudit("attempt")
if !app.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
if channel.Type != model.CHANNEL_OPEN && !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
c.LogAudit("fail - bad channel permissions")
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}
if incomingHook, err := app.CreateIncomingWebhookForChannel(c.Session.UserId, channel, hook); err != nil {
c.Err = err
return
} else {
c.LogAudit("success")
w.Write([]byte(incomingHook.ToJson()))
}
}
func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
teamId := r.URL.Query().Get("team_id")
var hooks []*model.IncomingWebhook
var err *model.AppError
if len(teamId) > 0 {
if !app.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
hooks, err = app.GetIncomingWebhooksForTeamPage(teamId, c.Params.Page, c.Params.PerPage)
} else {
if !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
hooks, err = app.GetIncomingWebhooksPage(c.Params.Page, c.Params.PerPage)
}
if err != nil {
c.Err = err
return
}
w.Write([]byte(model.IncomingWebhookListToJson(hooks)))
}

150
api4/webhook_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,150 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api4
import (
"testing"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func TestCreateIncomingWebhook(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
CheckNoError(t, resp)
if rhook.ChannelId != hook.ChannelId {
t.Fatal("channel ids didn't match")
}
if rhook.UserId != th.SystemAdminUser.Id {
t.Fatal("user ids didn't match")
}
if rhook.TeamId != th.BasicTeam.Id {
t.Fatal("team ids didn't match")
}
hook.ChannelId = "junk"
_, resp = th.SystemAdminClient.CreateIncomingWebhook(hook)
CheckNotFoundStatus(t, resp)
hook.ChannelId = th.BasicChannel.Id
th.LoginTeamAdmin()
_, resp = Client.CreateIncomingWebhook(hook)
CheckNoError(t, resp)
th.LoginBasic()
_, resp = Client.CreateIncomingWebhook(hook)
CheckForbiddenStatus(t, resp)
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
_, resp = Client.CreateIncomingWebhook(hook)
CheckNoError(t, resp)
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = false
_, resp = Client.CreateIncomingWebhook(hook)
CheckNotImplementedStatus(t, resp)
}
func TestGetIncomingWebhooks(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
enableIncomingHooks := utils.Cfg.ServiceSettings.EnableIncomingWebhooks
enableAdminOnlyHooks := utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
CheckNoError(t, resp)
hooks, resp := th.SystemAdminClient.GetIncomingWebhooks(0, 1000, "")
CheckNoError(t, resp)
found := false
for _, h := range hooks {
if rhook.Id == h.Id {
found = true
}
}
if !found {
t.Fatal("missing hook")
}
hooks, resp = th.SystemAdminClient.GetIncomingWebhooks(0, 1, "")
CheckNoError(t, resp)
if len(hooks) != 1 {
t.Fatal("should only be 1")
}
hooks, resp = th.SystemAdminClient.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
CheckNoError(t, resp)
found = false
for _, h := range hooks {
if rhook.Id == h.Id {
found = true
}
}
if !found {
t.Fatal("missing hook")
}
hooks, resp = th.SystemAdminClient.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
CheckNoError(t, resp)
if len(hooks) != 0 {
t.Fatal("no hooks should be returned")
}
_, resp = Client.GetIncomingWebhooks(0, 1000, "")
CheckForbiddenStatus(t, resp)
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
_, resp = Client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
CheckNoError(t, resp)
_, resp = Client.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
CheckForbiddenStatus(t, resp)
_, resp = Client.GetIncomingWebhooks(0, 1000, "")
CheckForbiddenStatus(t, resp)
Client.Logout()
_, resp = Client.GetIncomingWebhooks(0, 1000, "")
CheckUnauthorizedStatus(t, resp)
}

Просмотреть файл

@@ -192,3 +192,42 @@ func CreateWebhookPost(userId, teamId, channelId, text, overrideUsername, overri
return post, nil return post, nil
} }
func CreateIncomingWebhookForChannel(userId string, channel *model.Channel, hook *model.IncomingWebhook) (*model.IncomingWebhook, *model.AppError) {
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
return nil, model.NewAppError("CreateIncomingWebhookForChannel", "api.webhook.create_incoming.disabled.app_errror", nil, "", http.StatusNotImplemented)
}
hook.UserId = userId
hook.TeamId = channel.TeamId
if result := <-Srv.Store.Webhook().SaveIncoming(hook); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.IncomingWebhook), nil
}
}
func GetIncomingWebhooksForTeamPage(teamId string, page, perPage int) ([]*model.IncomingWebhook, *model.AppError) {
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
return nil, model.NewAppError("GetIncomingWebhooksForTeamPage", "api.webhook.get_incoming.disabled.app_error", nil, "", http.StatusNotImplemented)
}
if result := <-Srv.Store.Webhook().GetIncomingByTeam(teamId, page*perPage, perPage); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.IncomingWebhook), nil
}
}
func GetIncomingWebhooksPage(page, perPage int) ([]*model.IncomingWebhook, *model.AppError) {
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
return nil, model.NewAppError("GetIncomingWebhooksPage", "api.webhook.get_incoming.disabled.app_error", nil, "", http.StatusNotImplemented)
}
if result := <-Srv.Store.Webhook().GetIncomingList(page*perPage, perPage); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.IncomingWebhook), nil
}
}

Просмотреть файл

@@ -133,6 +133,10 @@ func (c *Client4) GetSystemRoute() string {
return fmt.Sprintf("/system") return fmt.Sprintf("/system")
} }
func (c *Client4) GetIncomingWebhooksRoute() string {
return fmt.Sprintf("/hooks/incoming")
}
func (c *Client4) DoApiGet(url string, etag string) (*http.Response, *AppError) { func (c *Client4) DoApiGet(url string, etag string) (*http.Response, *AppError) {
return c.DoApiRequest(http.MethodGet, url, "", etag) return c.DoApiRequest(http.MethodGet, url, "", etag)
} }
@@ -775,3 +779,37 @@ func (c *Client4) GetPing() (bool, *Response) {
return CheckStatusOK(r), BuildResponse(r) return CheckStatusOK(r), BuildResponse(r)
} }
} }
// Webhooks Section
// CreateIncomingWebhook creates an incoming webhook for a channel.
func (c *Client4) CreateIncomingWebhook(hook *IncomingWebhook) (*IncomingWebhook, *Response) {
if r, err := c.DoApiPost(c.GetIncomingWebhooksRoute(), hook.ToJson()); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return IncomingWebhookFromJson(r.Body), BuildResponse(r)
}
}
// GetIncomingWebhooks returns a page of incoming webhooks on the system. Page counting starts at 0.
func (c *Client4) GetIncomingWebhooks(page int, perPage int, etag string) ([]*IncomingWebhook, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
if r, err := c.DoApiGet(c.GetIncomingWebhooksRoute()+query, etag); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return IncomingWebhookListFromJson(r.Body), BuildResponse(r)
}
}
// GetIncomingWebhooksForTeam returns a page of incoming webhooks for a team. Page counting starts at 0.
func (c *Client4) GetIncomingWebhooksForTeam(teamId string, page int, perPage int, etag string) ([]*IncomingWebhook, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v&team_id=%v", page, perPage, teamId)
if r, err := c.DoApiGet(c.GetIncomingWebhooksRoute()+query, etag); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return IncomingWebhookListFromJson(r.Body), BuildResponse(r)
}
}

Просмотреть файл

@@ -357,7 +357,7 @@ func (s SqlChannelStore) get(id string, master bool, allowFromCache bool) StoreC
if obj, err := db.Get(model.Channel{}, id); err != nil { if obj, err := db.Get(model.Channel{}, id); err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.Get", "store.sql_channel.get.find.app_error", nil, "id="+id+", "+err.Error()) result.Err = model.NewLocAppError("SqlChannelStore.Get", "store.sql_channel.get.find.app_error", nil, "id="+id+", "+err.Error())
} else if obj == nil { } else if obj == nil {
result.Err = model.NewLocAppError("SqlChannelStore.Get", "store.sql_channel.get.existing.app_error", nil, "id="+id) result.Err = model.NewAppError("SqlChannelStore.Get", "store.sql_channel.get.existing.app_error", nil, "id="+id, http.StatusBadRequest)
} else { } else {
result.Data = obj.(*model.Channel) result.Data = obj.(*model.Channel)
channelCache.AddWithExpiresInSecs(id, obj.(*model.Channel), CHANNEL_CACHE_SEC) channelCache.AddWithExpiresInSecs(id, obj.(*model.Channel), CHANNEL_CACHE_SEC)

Просмотреть файл

@@ -4,6 +4,8 @@
package store package store
import ( import (
"net/http"
"github.com/mattermost/platform/einterfaces" "github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model" "github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils" "github.com/mattermost/platform/utils"
@@ -183,7 +185,7 @@ func (s SqlWebhookStore) PermanentDeleteIncomingByUser(userId string) StoreChann
return storeChannel return storeChannel
} }
func (s SqlWebhookStore) GetIncomingByTeam(teamId string) StoreChannel { func (s SqlWebhookStore) GetIncomingList(offset, limit int) StoreChannel {
storeChannel := make(StoreChannel, 1) storeChannel := make(StoreChannel, 1)
go func() { go func() {
@@ -191,8 +193,29 @@ func (s SqlWebhookStore) GetIncomingByTeam(teamId string) StoreChannel {
var webhooks []*model.IncomingWebhook var webhooks []*model.IncomingWebhook
if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE TeamId = :TeamId AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId}); err != nil { if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Limit": limit, "Offset": offset}); err != nil {
result.Err = model.NewLocAppError("SqlWebhookStore.GetIncomingByUser", "store.sql_webhooks.get_incoming_by_user.app_error", nil, "teamId="+teamId+", err="+err.Error()) result.Err = model.NewAppError("SqlWebhookStore.GetIncomingList", "store.sql_webhooks.get_incoming_by_user.app_error", nil, "err="+err.Error(), http.StatusInternalServerError)
}
result.Data = webhooks
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlWebhookStore) GetIncomingByTeam(teamId string, offset, limit int) StoreChannel {
storeChannel := make(StoreChannel, 1)
go func() {
result := StoreResult{}
var webhooks []*model.IncomingWebhook
if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE TeamId = :TeamId AND DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"TeamId": teamId, "Limit": limit, "Offset": offset}); err != nil {
result.Err = model.NewAppError("SqlWebhookStore.GetIncomingByUser", "store.sql_webhooks.get_incoming_by_user.app_error", nil, "teamId="+teamId+", err="+err.Error(), http.StatusInternalServerError)
} }
result.Data = webhooks result.Data = webhooks

Просмотреть файл

@@ -60,6 +60,40 @@ func TestWebhookStoreGetIncoming(t *testing.T) {
} }
} }
func TestWebhookStoreGetIncomingList(t *testing.T) {
Setup()
o1 := &model.IncomingWebhook{}
o1.ChannelId = model.NewId()
o1.UserId = model.NewId()
o1.TeamId = model.NewId()
o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook)
if r1 := <-store.Webhook().GetIncomingList(0, 1000); r1.Err != nil {
t.Fatal(r1.Err)
} else {
found := false
hooks := r1.Data.([]*model.IncomingWebhook)
for _, hook := range hooks {
if hook.Id == o1.Id {
found = true
}
}
if !found {
t.Fatal("missing webhook")
}
}
if result := <-store.Webhook().GetIncomingList(0, 1); result.Err != nil {
t.Fatal(result.Err)
} else {
if len(result.Data.([]*model.IncomingWebhook)) != 1 {
t.Fatal("only 1 should be returned")
}
}
}
func TestWebhookStoreGetIncomingByTeam(t *testing.T) { func TestWebhookStoreGetIncomingByTeam(t *testing.T) {
Setup() Setup()
@@ -70,7 +104,7 @@ func TestWebhookStoreGetIncomingByTeam(t *testing.T) {
o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook) o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook)
if r1 := <-store.Webhook().GetIncomingByTeam(o1.TeamId); r1.Err != nil { if r1 := <-store.Webhook().GetIncomingByTeam(o1.TeamId, 0, 100); r1.Err != nil {
t.Fatal(r1.Err) t.Fatal(r1.Err)
} else { } else {
if r1.Data.([]*model.IncomingWebhook)[0].CreateAt != o1.CreateAt { if r1.Data.([]*model.IncomingWebhook)[0].CreateAt != o1.CreateAt {
@@ -78,7 +112,7 @@ func TestWebhookStoreGetIncomingByTeam(t *testing.T) {
} }
} }
if result := <-store.Webhook().GetIncomingByTeam("123"); result.Err != nil { if result := <-store.Webhook().GetIncomingByTeam("123", 0, 100); result.Err != nil {
t.Fatal(result.Err) t.Fatal(result.Err)
} else { } else {
if len(result.Data.([]*model.IncomingWebhook)) != 0 { if len(result.Data.([]*model.IncomingWebhook)) != 0 {

Просмотреть файл

@@ -252,7 +252,8 @@ type SystemStore interface {
type WebhookStore interface { type WebhookStore interface {
SaveIncoming(webhook *model.IncomingWebhook) StoreChannel SaveIncoming(webhook *model.IncomingWebhook) StoreChannel
GetIncoming(id string, allowFromCache bool) StoreChannel GetIncoming(id string, allowFromCache bool) StoreChannel
GetIncomingByTeam(teamId string) StoreChannel GetIncomingList(offset, limit int) StoreChannel
GetIncomingByTeam(teamId string, offset, limit int) StoreChannel
GetIncomingByChannel(channelId string) StoreChannel GetIncomingByChannel(channelId string) StoreChannel
DeleteIncoming(webhookId string, time int64) StoreChannel DeleteIncoming(webhookId string, time int64) StoreChannel
PermanentDeleteIncomingByUser(userId string) StoreChannel PermanentDeleteIncomingByUser(userId string) StoreChannel