Implement GET and POST /hooks/outgoing endpoints for APIv4 (#5645)

Этот коммит содержится в:
Joram Wilander
2017-03-13 10:40:43 -04:00
коммит произвёл GitHub
родитель 3ebfb36953
Коммит 19c67d7fe3
9 изменённых файлов: 409 добавлений и 19 удалений

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

@@ -17,15 +17,17 @@ func InitWebhook() {
BaseRoutes.IncomingHooks.Handle("", ApiSessionRequired(createIncomingHook)).Methods("POST") BaseRoutes.IncomingHooks.Handle("", ApiSessionRequired(createIncomingHook)).Methods("POST")
BaseRoutes.IncomingHooks.Handle("", ApiSessionRequired(getIncomingHooks)).Methods("GET") BaseRoutes.IncomingHooks.Handle("", ApiSessionRequired(getIncomingHooks)).Methods("GET")
BaseRoutes.IncomingHook.Handle("", ApiSessionRequired(getIncomingHook)).Methods("GET") BaseRoutes.IncomingHook.Handle("", ApiSessionRequired(getIncomingHook)).Methods("GET")
BaseRoutes.IncomingHook.Handle("", ApiSessionRequired(deleteIncomingHook)).Methods("DELETE") BaseRoutes.IncomingHook.Handle("", ApiSessionRequired(deleteIncomingHook)).Methods("DELETE")
BaseRoutes.OutgoingHooks.Handle("", ApiSessionRequired(createOutgoingHook)).Methods("POST")
BaseRoutes.OutgoingHooks.Handle("", ApiSessionRequired(getOutgoingHooks)).Methods("GET")
} }
func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
hook := model.IncomingWebhookFromJson(r.Body) hook := model.IncomingWebhookFromJson(r.Body)
if hook == nil { if hook == nil {
c.SetInvalidParam("webhook") c.SetInvalidParam("incoming_webhook")
return return
} }
@@ -53,6 +55,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} else { } else {
c.LogAudit("success") c.LogAudit("success")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(incomingHook.ToJson())) w.Write([]byte(incomingHook.ToJson()))
} }
} }
@@ -158,3 +161,68 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
} }
} }
} }
func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
hook := model.OutgoingWebhookFromJson(r.Body)
if hook == nil {
c.SetInvalidParam("outgoing_webhook")
return
}
c.LogAudit("attempt")
hook.CreatorId = c.Session.UserId
if !app.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
if rhook, err := app.CreateOutgoingWebhook(hook); err != nil {
c.LogAudit("fail")
c.Err = err
return
} else {
c.LogAudit("success")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(rhook.ToJson()))
}
}
func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
channelId := r.URL.Query().Get("channel_id")
teamId := r.URL.Query().Get("team_id")
var hooks []*model.OutgoingWebhook
var err *model.AppError
if len(channelId) > 0 {
if !app.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
hooks, err = app.GetOutgoingWebhooksForChannelPage(channelId, c.Params.Page, c.Params.PerPage)
} else if len(teamId) > 0 {
if !app.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_WEBHOOKS) {
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
}
hooks, err = app.GetOutgoingWebhooksForTeamPage(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.GetOutgoingWebhooksPage(c.Params.Page, c.Params.PerPage)
}
if err != nil {
c.Err = err
return
}
w.Write([]byte(model.OutgoingWebhookListToJson(hooks)))
}

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

@@ -256,3 +256,165 @@ func TestDeleteIncomingWebhook(t *testing.T) {
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
}) })
} }
func TestCreateOutgoingWebhook(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
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()
hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
CheckNoError(t, resp)
if rhook.ChannelId != hook.ChannelId {
t.Fatal("channel ids didn't match")
} else if rhook.CreatorId != th.SystemAdminUser.Id {
t.Fatal("user ids didn't match")
} else if rhook.TeamId != th.BasicChannel.TeamId {
t.Fatal("team ids didn't match")
}
hook.ChannelId = "junk"
_, resp = th.SystemAdminClient.CreateOutgoingWebhook(hook)
CheckNotFoundStatus(t, resp)
hook.ChannelId = th.BasicChannel.Id
th.LoginTeamAdmin()
_, resp = Client.CreateOutgoingWebhook(hook)
CheckNoError(t, resp)
th.LoginBasic()
_, resp = Client.CreateOutgoingWebhook(hook)
CheckForbiddenStatus(t, resp)
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
_, resp = Client.CreateOutgoingWebhook(hook)
CheckNoError(t, resp)
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = false
_, resp = Client.CreateOutgoingWebhook(hook)
CheckNotImplementedStatus(t, resp)
}
func TestGetOutgoingWebhooks(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
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()
hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
CheckNoError(t, resp)
hooks, resp := th.SystemAdminClient.GetOutgoingWebhooks(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.GetOutgoingWebhooks(0, 1, "")
CheckNoError(t, resp)
if len(hooks) != 1 {
t.Fatal("should only be 1")
}
hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForTeam(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.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
CheckNoError(t, resp)
if len(hooks) != 0 {
t.Fatal("no hooks should be returned")
}
hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForChannel(th.BasicChannel.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.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
CheckNoError(t, resp)
if len(hooks) != 0 {
t.Fatal("no hooks should be returned")
}
_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
CheckForbiddenStatus(t, resp)
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
_, resp = Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
CheckNoError(t, resp)
_, resp = Client.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
CheckForbiddenStatus(t, resp)
_, resp = Client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
CheckNoError(t, resp)
_, resp = Client.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
CheckForbiddenStatus(t, resp)
_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
CheckForbiddenStatus(t, resp)
Client.Logout()
_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
CheckUnauthorizedStatus(t, resp)
}

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

@@ -313,7 +313,7 @@ func UpdateChannelMemberNotifyProps(data map[string]string, channelId string, us
func DeleteChannel(channel *model.Channel, userId string) *model.AppError { func DeleteChannel(channel *model.Channel, userId string) *model.AppError {
uc := Srv.Store.User().Get(userId) uc := Srv.Store.User().Get(userId)
ihc := Srv.Store.Webhook().GetIncomingByChannel(channel.Id) ihc := Srv.Store.Webhook().GetIncomingByChannel(channel.Id)
ohc := Srv.Store.Webhook().GetOutgoingByChannel(channel.Id) ohc := Srv.Store.Webhook().GetOutgoingByChannel(channel.Id, -1, -1)
if uresult := <-uc; uresult.Err != nil { if uresult := <-uc; uresult.Err != nil {
return uresult.Err return uresult.Err

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

@@ -33,7 +33,7 @@ func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Chan
return nil return nil
} }
hchan := Srv.Store.Webhook().GetOutgoingByTeam(team.Id) hchan := Srv.Store.Webhook().GetOutgoingByTeam(team.Id, -1, -1)
result := <-hchan result := <-hchan
if result.Err != nil { if result.Err != nil {
return result.Err return result.Err
@@ -304,7 +304,7 @@ func CreateOutgoingWebhook(hook *model.OutgoingWebhook) (*model.OutgoingWebhook,
return nil, model.NewAppError("CreateOutgoingWebhook", "api.webhook.create_outgoing.triggers.app_error", nil, "", http.StatusBadRequest) return nil, model.NewAppError("CreateOutgoingWebhook", "api.webhook.create_outgoing.triggers.app_error", nil, "", http.StatusBadRequest)
} }
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(hook.TeamId); result.Err != nil { if result := <-Srv.Store.Webhook().GetOutgoingByTeam(hook.TeamId, -1, -1); result.Err != nil {
return nil, result.Err return nil, result.Err
} else { } else {
allHooks := result.Data.([]*model.OutgoingWebhook) allHooks := result.Data.([]*model.OutgoingWebhook)
@@ -349,7 +349,7 @@ func UpdateOutgoingWebhook(oldHook, updatedHook *model.OutgoingWebhook) (*model.
} }
var result store.StoreResult var result store.StoreResult
if result = <-Srv.Store.Webhook().GetOutgoingByTeam(oldHook.TeamId); result.Err != nil { if result = <-Srv.Store.Webhook().GetOutgoingByTeam(oldHook.TeamId, -1, -1); result.Err != nil {
return nil, result.Err return nil, result.Err
} }
@@ -389,12 +389,36 @@ func GetOutgoingWebhook(hookId string) (*model.OutgoingWebhook, *model.AppError)
} }
} }
func GetOutgoingWebhooksPage(page, perPage int) ([]*model.OutgoingWebhook, *model.AppError) {
if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
return nil, model.NewAppError("GetOutgoingWebhooksPage", "api.outgoing_webhook.disabled.app_error", nil, "", http.StatusNotImplemented)
}
if result := <-Srv.Store.Webhook().GetOutgoingList(page*perPage, perPage); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.OutgoingWebhook), nil
}
}
func GetOutgoingWebhooksForChannelPage(channelId string, page, perPage int) ([]*model.OutgoingWebhook, *model.AppError) {
if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
return nil, model.NewAppError("GetOutgoingWebhooksForChannelPage", "api.outgoing_webhook.disabled.app_error", nil, "", http.StatusNotImplemented)
}
if result := <-Srv.Store.Webhook().GetOutgoingByChannel(channelId, page*perPage, perPage); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.OutgoingWebhook), nil
}
}
func GetOutgoingWebhooksForTeamPage(teamId string, page, perPage int) ([]*model.OutgoingWebhook, *model.AppError) { func GetOutgoingWebhooksForTeamPage(teamId string, page, perPage int) ([]*model.OutgoingWebhook, *model.AppError) {
if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks { if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
return nil, model.NewAppError("GetOutgoingWebhooksForTeamPage", "api.outgoing_webhook.disabled.app_error", nil, "", http.StatusNotImplemented) return nil, model.NewAppError("GetOutgoingWebhooksForTeamPage", "api.outgoing_webhook.disabled.app_error", nil, "", http.StatusNotImplemented)
} }
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(teamId); result.Err != nil { if result := <-Srv.Store.Webhook().GetOutgoingByTeam(teamId, page*perPage, perPage); result.Err != nil {
return nil, result.Err return nil, result.Err
} else { } else {
return result.Data.([]*model.OutgoingWebhook), nil return result.Data.([]*model.OutgoingWebhook), nil

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

@@ -162,6 +162,10 @@ func (c *Client4) GetComplianceReportRoute(reportId string) string {
return fmt.Sprintf("/compliance/reports/%v", reportId) return fmt.Sprintf("/compliance/reports/%v", reportId)
} }
func (c *Client4) GetOutgoingWebhooksRoute() string {
return fmt.Sprintf("/hooks/outgoing")
}
func (c *Client4) GetPreferencesRoute(userId string) string { func (c *Client4) GetPreferencesRoute(userId string) string {
return fmt.Sprintf(c.GetUserRoute(userId) + "/preferences") return fmt.Sprintf(c.GetUserRoute(userId) + "/preferences")
} }
@@ -1125,6 +1129,49 @@ func (c *Client4) DeleteIncomingWebhook(hookID string) (bool, *Response) {
} }
} }
// CreateOutgoingWebhook creates an outgoing webhook for a team or channel.
func (c *Client4) CreateOutgoingWebhook(hook *OutgoingWebhook) (*OutgoingWebhook, *Response) {
if r, err := c.DoApiPost(c.GetOutgoingWebhooksRoute(), hook.ToJson()); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return OutgoingWebhookFromJson(r.Body), BuildResponse(r)
}
}
// GetOutgoingWebhooks returns a page of outgoing webhooks on the system. Page counting starts at 0.
func (c *Client4) GetOutgoingWebhooks(page int, perPage int, etag string) ([]*OutgoingWebhook, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
if r, err := c.DoApiGet(c.GetOutgoingWebhooksRoute()+query, etag); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return OutgoingWebhookListFromJson(r.Body), BuildResponse(r)
}
}
// GetOutgoingWebhooksForChannel returns a page of outgoing webhooks for a channel. Page counting starts at 0.
func (c *Client4) GetOutgoingWebhooksForChannel(channelId string, page int, perPage int, etag string) ([]*OutgoingWebhook, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v&channel_id=%v", page, perPage, channelId)
if r, err := c.DoApiGet(c.GetOutgoingWebhooksRoute()+query, etag); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return OutgoingWebhookListFromJson(r.Body), BuildResponse(r)
}
}
// GetOutgoingWebhooksForTeam returns a page of outgoing webhooks for a team. Page counting starts at 0.
func (c *Client4) GetOutgoingWebhooksForTeam(teamId string, page int, perPage int, etag string) ([]*OutgoingWebhook, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v&team_id=%v", page, perPage, teamId)
if r, err := c.DoApiGet(c.GetOutgoingWebhooksRoute()+query, etag); err != nil {
return nil, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return OutgoingWebhookListFromJson(r.Body), BuildResponse(r)
}
}
// Preferences Section // Preferences Section
// GetPreferences returns the user's preferences. // GetPreferences returns the user's preferences.

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

@@ -386,9 +386,9 @@ 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.NewAppError("SqlChannelStore.Get", "store.sql_channel.get.find.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError)
} else if obj == nil { } else if obj == nil {
result.Err = model.NewAppError("SqlChannelStore.Get", "store.sql_channel.get.existing.app_error", nil, "id="+id, http.StatusBadRequest) result.Err = model.NewAppError("SqlChannelStore.Get", "store.sql_channel.get.existing.app_error", nil, "id="+id, http.StatusNotFound)
} 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)

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

@@ -329,7 +329,7 @@ func (s SqlWebhookStore) GetOutgoing(id string) StoreChannel {
return storeChannel return storeChannel
} }
func (s SqlWebhookStore) GetOutgoingByChannel(channelId string) StoreChannel { func (s SqlWebhookStore) GetOutgoingList(offset, limit int) StoreChannel {
storeChannel := make(StoreChannel, 1) storeChannel := make(StoreChannel, 1)
go func() { go func() {
@@ -337,7 +337,35 @@ func (s SqlWebhookStore) GetOutgoingByChannel(channelId string) StoreChannel {
var webhooks []*model.OutgoingWebhook var webhooks []*model.OutgoingWebhook
if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM OutgoingWebhooks WHERE ChannelId = :ChannelId AND DeleteAt = 0", map[string]interface{}{"ChannelId": channelId}); err != nil { if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM OutgoingWebhooks WHERE DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewLocAppError("SqlWebhookStore.GetOutgoingList", "store.sql_webhooks.get_outgoing_by_channel.app_error", nil, "err="+err.Error())
}
result.Data = webhooks
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlWebhookStore) GetOutgoingByChannel(channelId string, offset, limit int) StoreChannel {
storeChannel := make(StoreChannel, 1)
go func() {
result := StoreResult{}
var webhooks []*model.OutgoingWebhook
query := ""
if limit < 0 || offset < 0 {
query = "SELECT * FROM OutgoingWebhooks WHERE ChannelId = :ChannelId AND DeleteAt = 0"
} else {
query = "SELECT * FROM OutgoingWebhooks WHERE ChannelId = :ChannelId AND DeleteAt = 0 LIMIT :Limit OFFSET :Offset"
}
if _, err := s.GetReplica().Select(&webhooks, query, map[string]interface{}{"ChannelId": channelId, "Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewLocAppError("SqlWebhookStore.GetOutgoingByChannel", "store.sql_webhooks.get_outgoing_by_channel.app_error", nil, "channelId="+channelId+", err="+err.Error()) result.Err = model.NewLocAppError("SqlWebhookStore.GetOutgoingByChannel", "store.sql_webhooks.get_outgoing_by_channel.app_error", nil, "channelId="+channelId+", err="+err.Error())
} }
@@ -350,7 +378,7 @@ func (s SqlWebhookStore) GetOutgoingByChannel(channelId string) StoreChannel {
return storeChannel return storeChannel
} }
func (s SqlWebhookStore) GetOutgoingByTeam(teamId string) StoreChannel { func (s SqlWebhookStore) GetOutgoingByTeam(teamId string, offset, limit int) StoreChannel {
storeChannel := make(StoreChannel, 1) storeChannel := make(StoreChannel, 1)
go func() { go func() {
@@ -358,7 +386,14 @@ func (s SqlWebhookStore) GetOutgoingByTeam(teamId string) StoreChannel {
var webhooks []*model.OutgoingWebhook var webhooks []*model.OutgoingWebhook
if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM OutgoingWebhooks WHERE TeamId = :TeamId AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId}); err != nil { query := ""
if limit < 0 || offset < 0 {
query = "SELECT * FROM OutgoingWebhooks WHERE TeamId = :TeamId AND DeleteAt = 0"
} else {
query = "SELECT * FROM OutgoingWebhooks WHERE TeamId = :TeamId AND DeleteAt = 0 LIMIT :Limit OFFSET :Offset"
}
if _, err := s.GetReplica().Select(&webhooks, query, map[string]interface{}{"TeamId": teamId, "Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewLocAppError("SqlWebhookStore.GetOutgoingByTeam", "store.sql_webhooks.get_outgoing_by_team.app_error", nil, "teamId="+teamId+", err="+err.Error()) result.Err = model.NewLocAppError("SqlWebhookStore.GetOutgoingByTeam", "store.sql_webhooks.get_outgoing_by_team.app_error", nil, "teamId="+teamId+", err="+err.Error())
} }

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

@@ -240,6 +240,59 @@ func TestWebhookStoreGetOutgoing(t *testing.T) {
} }
} }
func TestWebhookStoreGetOutgoingList(t *testing.T) {
Setup()
o1 := &model.OutgoingWebhook{}
o1.ChannelId = model.NewId()
o1.CreatorId = model.NewId()
o1.TeamId = model.NewId()
o1.CallbackURLs = []string{"http://nowhere.com/"}
o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook)
o2 := &model.OutgoingWebhook{}
o2.ChannelId = model.NewId()
o2.CreatorId = model.NewId()
o2.TeamId = model.NewId()
o2.CallbackURLs = []string{"http://nowhere.com/"}
o2 = (<-store.Webhook().SaveOutgoing(o2)).Data.(*model.OutgoingWebhook)
if r1 := <-store.Webhook().GetOutgoingList(0, 1000); r1.Err != nil {
t.Fatal(r1.Err)
} else {
hooks := r1.Data.([]*model.OutgoingWebhook)
found1 := false
found2 := false
for _, hook := range hooks {
if hook.CreateAt != o1.CreateAt {
found1 = true
}
if hook.CreateAt != o2.CreateAt {
found2 = true
}
}
if !found1 {
t.Fatal("missing hook1")
}
if !found2 {
t.Fatal("missing hook2")
}
}
if result := <-store.Webhook().GetOutgoingList(0, 2); result.Err != nil {
t.Fatal(result.Err)
} else {
if len(result.Data.([]*model.OutgoingWebhook)) != 2 {
t.Fatal("wrong number of hooks returned")
}
}
}
func TestWebhookStoreGetOutgoingByChannel(t *testing.T) { func TestWebhookStoreGetOutgoingByChannel(t *testing.T) {
Setup() Setup()
@@ -251,7 +304,7 @@ func TestWebhookStoreGetOutgoingByChannel(t *testing.T) {
o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook) o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook)
if r1 := <-store.Webhook().GetOutgoingByChannel(o1.ChannelId); r1.Err != nil { if r1 := <-store.Webhook().GetOutgoingByChannel(o1.ChannelId, 0, 100); r1.Err != nil {
t.Fatal(r1.Err) t.Fatal(r1.Err)
} else { } else {
if r1.Data.([]*model.OutgoingWebhook)[0].CreateAt != o1.CreateAt { if r1.Data.([]*model.OutgoingWebhook)[0].CreateAt != o1.CreateAt {
@@ -259,7 +312,7 @@ func TestWebhookStoreGetOutgoingByChannel(t *testing.T) {
} }
} }
if result := <-store.Webhook().GetOutgoingByChannel("123"); result.Err != nil { if result := <-store.Webhook().GetOutgoingByChannel("123", -1, -1); result.Err != nil {
t.Fatal(result.Err) t.Fatal(result.Err)
} else { } else {
if len(result.Data.([]*model.OutgoingWebhook)) != 0 { if len(result.Data.([]*model.OutgoingWebhook)) != 0 {
@@ -279,7 +332,7 @@ func TestWebhookStoreGetOutgoingByTeam(t *testing.T) {
o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook) o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook)
if r1 := <-store.Webhook().GetOutgoingByTeam(o1.TeamId); r1.Err != nil { if r1 := <-store.Webhook().GetOutgoingByTeam(o1.TeamId, 0, 100); r1.Err != nil {
t.Fatal(r1.Err) t.Fatal(r1.Err)
} else { } else {
if r1.Data.([]*model.OutgoingWebhook)[0].CreateAt != o1.CreateAt { if r1.Data.([]*model.OutgoingWebhook)[0].CreateAt != o1.CreateAt {
@@ -287,7 +340,7 @@ func TestWebhookStoreGetOutgoingByTeam(t *testing.T) {
} }
} }
if result := <-store.Webhook().GetOutgoingByTeam("123"); result.Err != nil { if result := <-store.Webhook().GetOutgoingByTeam("123", -1, -1); result.Err != nil {
t.Fatal(result.Err) t.Fatal(result.Err)
} else { } else {
if len(result.Data.([]*model.OutgoingWebhook)) != 0 { if len(result.Data.([]*model.OutgoingWebhook)) != 0 {

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

@@ -273,8 +273,9 @@ type WebhookStore interface {
SaveOutgoing(webhook *model.OutgoingWebhook) StoreChannel SaveOutgoing(webhook *model.OutgoingWebhook) StoreChannel
GetOutgoing(id string) StoreChannel GetOutgoing(id string) StoreChannel
GetOutgoingByChannel(channelId string) StoreChannel GetOutgoingList(offset, limit int) StoreChannel
GetOutgoingByTeam(teamId string) StoreChannel GetOutgoingByChannel(channelId string, offset, limit int) StoreChannel
GetOutgoingByTeam(teamId string, offset, limit int) StoreChannel
DeleteOutgoing(webhookId string, time int64) StoreChannel DeleteOutgoing(webhookId string, time int64) StoreChannel
PermanentDeleteOutgoingByUser(userId string) StoreChannel PermanentDeleteOutgoingByUser(userId string) StoreChannel
UpdateOutgoing(hook *model.OutgoingWebhook) StoreChannel UpdateOutgoing(hook *model.OutgoingWebhook) StoreChannel