[MM-17069] Api endpoint to unread a channel (#11794)

* [MM-17069] endpoint to unread a channel from post

* [MM-17069] update mock

* [MM-17069] first passing test

* [MM-17069] fix SQL typo

* [MM-17069] fix msgCount

* add tests

* [MM-17069] Fix tests

* [MM-16069] Remove trash, add comments

* [MM-16069] Add message to errors

* [MM-17069] fix go fmt

* [MM-17069] return an UnreadChannel response

* [MM-17069] added unauthorized test

* [MM-17069] fix operator

* [MM-17069] refactor tests

* [MM-16069] back to green tests

* [MM-17069] change url to include user

* [MM-17069] Fixing code review comments

* [MM-17069] One shouldn't fix manually what a machine can fix better

* [MM-17069] change response type, update tests

* [MM-17069] fix permission error

* [MM-17069] Add tests for edit_other_users permission

* [MM-17069] no magic numbers
Этот коммит содержится в:
Guillermo Vayá
2019-08-21 14:48:25 +02:00
коммит произвёл Harrison Healey
родитель bd152c6534
Коммит 6b0f4f1aee
10 изменённых файлов: 365 добавлений и 0 удалений

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

@@ -28,6 +28,7 @@ func (api *API) InitPost() {
api.BaseRoutes.Team.Handle("/posts/search", api.ApiSessionRequired(searchPosts)).Methods("POST")
api.BaseRoutes.Post.Handle("", api.ApiSessionRequired(updatePost)).Methods("PUT")
api.BaseRoutes.Post.Handle("/patch", api.ApiSessionRequired(patchPost)).Methods("PUT")
api.BaseRoutes.PostForUser.Handle("/set_unread", api.ApiSessionRequired(setPostUnread)).Methods("POST")
api.BaseRoutes.Post.Handle("/pin", api.ApiSessionRequired(pinPost)).Methods("POST")
api.BaseRoutes.Post.Handle("/unpin", api.ApiSessionRequired(unpinPost)).Methods("POST")
}
@@ -576,6 +577,28 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(patchedPost.ToJson()))
}
func setPostUnread(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequirePostId().RequireUserId()
if c.Err != nil {
return
}
if c.App.Session.UserId != c.Params.UserId && !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
return
}
if !c.App.SessionHasPermissionToChannelByPost(c.App.Session, c.Params.PostId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
return
}
state, err := c.App.MarkChannelAsUnreadFromPost(c.Params.PostId, c.Params.UserId)
if err != nil {
c.Err = err
return
}
w.Write([]byte(state.ToJson()))
}
func saveIsPinnedPost(c *Context, w http.ResponseWriter, r *http.Request, isPinned bool) {
c.RequirePostId()
if c.Err != nil {

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

@@ -2647,3 +2647,84 @@ func TestGetFileInfosForPost(t *testing.T) {
_, resp = th.SystemAdminClient.GetFileInfosForPost(th.BasicPost.Id, "")
CheckNoError(t, resp)
}
func TestSetChannelUnread(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
u1 := th.BasicUser
u2 := th.BasicUser2
s2, _ := th.App.GetSession(th.Client.AuthToken)
th.Client.Login(u1.Email, u1.Password)
c1 := th.BasicChannel
c1toc2 := &model.ChannelView{ChannelId: th.BasicChannel2.Id, PrevChannelId: c1.Id}
now := utils.MillisFromTime(time.Now())
th.CreateMessagePostNoClient(c1, "AAA", now)
p2 := th.CreateMessagePostNoClient(c1, "BBB", now+10)
th.CreateMessagePostNoClient(c1, "CCC", now+20)
pp1 := th.CreateMessagePostNoClient(th.BasicPrivateChannel, "Sssh!", now)
pp2 := th.CreateMessagePostNoClient(th.BasicPrivateChannel, "You Sssh!", now+10)
require.NotNil(t, pp1)
require.NotNil(t, pp2)
// Ensure that post have been read
unread, err := th.App.GetChannelUnread(c1.Id, u1.Id)
require.Nil(t, err)
require.Equal(t, int64(4), unread.MsgCount)
unread, err = th.App.GetChannelUnread(c1.Id, u2.Id)
require.Nil(t, err)
require.Equal(t, int64(4), unread.MsgCount)
_, err = th.App.ViewChannel(c1toc2, u2.Id, s2.Id)
require.Nil(t, err)
unread, err = th.App.GetChannelUnread(c1.Id, u2.Id)
require.Nil(t, err)
require.Equal(t, int64(0), unread.MsgCount)
t.Run("Unread last one", func(t *testing.T) {
r := th.Client.SetPostUnread(u1.Id, p2.Id)
checkHTTPStatus(t, r, 200, false)
unread, err := th.App.GetChannelUnread(c1.Id, u1.Id)
require.Nil(t, err)
assert.Equal(t, int64(1), unread.MsgCount)
})
t.Run("Unread on a private channel", func(t *testing.T) {
r := th.Client.SetPostUnread(u1.Id, pp2.Id)
assert.Equal(t, 200, r.StatusCode)
unread, err := th.App.GetChannelUnread(th.BasicPrivateChannel.Id, u1.Id)
require.Nil(t, err)
assert.Equal(t, int64(0), unread.MsgCount)
r = th.Client.SetPostUnread(u1.Id, pp1.Id)
assert.Equal(t, 200, r.StatusCode)
unread, err = th.App.GetChannelUnread(th.BasicPrivateChannel.Id, u1.Id)
require.Nil(t, err)
assert.Equal(t, int64(1), unread.MsgCount)
})
t.Run("Can't unread an imaginary post", func(t *testing.T) {
r := th.Client.SetPostUnread(u1.Id, "invalid4ofngungryquinj976y")
assert.Equal(t, http.StatusForbidden, r.StatusCode)
})
// let's create another user to test permissions
u3 := th.CreateUser()
c3 := th.CreateClient()
c3.Login(u3.Email, u3.Password)
t.Run("Can't unread channels you don't belong to", func(t *testing.T) {
r := c3.SetPostUnread(u3.Id, pp1.Id)
assert.Equal(t, http.StatusForbidden, r.StatusCode)
})
t.Run("Can't unread users you don't have permission to edit", func(t *testing.T) {
r := c3.SetPostUnread(u1.Id, pp1.Id)
assert.Equal(t, http.StatusForbidden, r.StatusCode)
})
t.Run("Can't unread if user is not logged in", func(t *testing.T) {
th.Client.Logout()
response := th.Client.SetPostUnread(u1.Id, p2.Id)
checkHTTPStatus(t, response, http.StatusUnauthorized, true)
})
}