Expand Plugin and REST APIs to trigger user typing event (#14331)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8c1164d86b
Коммит
66597d0fcb
32
api4/user.go
32
api4/user.go
@@ -80,6 +80,8 @@ func (api *API) InitUser() {
|
||||
api.BaseRoutes.Users.Handle("/tokens/revoke", api.ApiSessionRequired(revokeUserAccessToken)).Methods("POST")
|
||||
api.BaseRoutes.Users.Handle("/tokens/disable", api.ApiSessionRequired(disableUserAccessToken)).Methods("POST")
|
||||
api.BaseRoutes.Users.Handle("/tokens/enable", api.ApiSessionRequired(enableUserAccessToken)).Methods("POST")
|
||||
|
||||
api.BaseRoutes.User.Handle("/typing", api.ApiSessionRequiredDisableWhenBusy(publishUserTyping)).Methods("POST")
|
||||
}
|
||||
|
||||
func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -2270,3 +2272,33 @@ func demoteUserToGuest(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
func publishUserTyping(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireUserId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
typingRequest := model.TypingRequestFromJson(r.Body)
|
||||
if typingRequest == nil {
|
||||
c.SetInvalidParam("typing_request")
|
||||
return
|
||||
}
|
||||
|
||||
if c.Params.UserId != c.App.Session().UserId && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.HasPermissionToChannel(c.Params.UserId, typingRequest.ChannelId, model.PERMISSION_CREATE_POST) {
|
||||
c.SetPermissionError(model.PERMISSION_CREATE_POST)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.App.PublishUserTyping(c.Params.UserId, typingRequest.ChannelId, typingRequest.ParentId); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -4781,3 +4781,78 @@ func TestGetKnownUsers(t *testing.T) {
|
||||
assert.ElementsMatch(t, userIds, []string{u2.Id, u3.Id})
|
||||
})
|
||||
}
|
||||
|
||||
func TestPublishUserTyping(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
tr := model.TypingRequest{
|
||||
ChannelId: th.BasicChannel.Id,
|
||||
ParentId: "randomparentid",
|
||||
}
|
||||
|
||||
t.Run("should return ok for non-system admin when triggering typing event for own user", func(t *testing.T) {
|
||||
_, resp := th.Client.PublishUserTyping(th.BasicUser.Id, tr)
|
||||
CheckNoError(t, resp)
|
||||
})
|
||||
|
||||
t.Run("should return ok for system admin when triggering typing event for own user", func(t *testing.T) {
|
||||
th.LinkUserToTeam(th.SystemAdminUser, th.BasicTeam)
|
||||
th.AddUserToChannel(th.SystemAdminUser, th.BasicChannel)
|
||||
|
||||
_, resp := th.SystemAdminClient.PublishUserTyping(th.SystemAdminUser.Id, tr)
|
||||
CheckNoError(t, resp)
|
||||
})
|
||||
|
||||
t.Run("should return forbidden for non-system admin when triggering a typing event for a different user", func(t *testing.T) {
|
||||
_, resp := th.Client.PublishUserTyping(th.BasicUser2.Id, tr)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("should return bad request when triggering a typing event for an invalid user id", func(t *testing.T) {
|
||||
_, resp := th.Client.PublishUserTyping("invalid", tr)
|
||||
CheckErrorMessage(t, resp, "api.context.invalid_url_param.app_error")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("should send typing event via websocket when triggering a typing event for a user with a common channel", func(t *testing.T) {
|
||||
webSocketClient, err := th.CreateWebSocketClient()
|
||||
assert.Nil(t, err)
|
||||
defer webSocketClient.Close()
|
||||
|
||||
webSocketClient.Listen()
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
wsResp := <-webSocketClient.ResponseChannel
|
||||
require.Equal(t, model.STATUS_OK, wsResp.Status)
|
||||
|
||||
_, resp := th.SystemAdminClient.PublishUserTyping(th.BasicUser2.Id, tr)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
assertExpectedWebsocketEvent(t, webSocketClient, model.WEBSOCKET_EVENT_TYPING, func(resp *model.WebSocketEvent) {
|
||||
assert.Equal(t, th.BasicChannel.Id, resp.GetBroadcast().ChannelId)
|
||||
|
||||
eventUserId, ok := resp.GetData()["user_id"].(string)
|
||||
require.True(t, ok, "expected user_id")
|
||||
assert.Equal(t, th.BasicUser2.Id, eventUserId)
|
||||
|
||||
eventParentId, ok := resp.GetData()["parent_id"].(string)
|
||||
require.True(t, ok, "expected parent_id")
|
||||
assert.Equal(t, "randomparentid", eventParentId)
|
||||
})
|
||||
})
|
||||
|
||||
th.Server.Busy.Set(time.Second * 10)
|
||||
|
||||
t.Run("should return service unavailable for non-system admin user when triggering a typing event and server busy", func(t *testing.T) {
|
||||
_, resp := th.Client.PublishUserTyping("invalid", tr)
|
||||
CheckErrorMessage(t, resp, "api.context.server_busy.app_error")
|
||||
CheckServiceUnavailableStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("should return service unavailable for system admin user when triggering a typing event and server busy", func(t *testing.T) {
|
||||
_, resp := th.SystemAdminClient.PublishUserTyping(th.SystemAdminUser.Id, tr)
|
||||
CheckErrorMessage(t, resp, "api.context.server_busy.app_error")
|
||||
CheckServiceUnavailableStatus(t, resp)
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user