MM-3543/MM-35436: fix thread being marked unread when updating reply post (#17645)
Summary Threads should not be returned as unread if a reply post has been edited or reacted to since the time the thread was last viewed Ticket Link https://mattermost.atlassian.net/browse/MM-35436 https://mattermost.atlassian.net/browse/MM-35437
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0aad9f7412
Коммит
6f5e14dd5e
@@ -5515,6 +5515,51 @@ func TestGetThreadsForUser(t *testing.T) {
|
|||||||
require.NotNil(t, uss3.Threads)
|
require.NotNil(t, uss3.Threads)
|
||||||
require.Len(t, uss3.Threads, 0)
|
require.Len(t, uss3.Threads, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("editing or reacting to reply post does not make thread unread", func(t *testing.T) {
|
||||||
|
Client := th.Client
|
||||||
|
|
||||||
|
rootPost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "root post"})
|
||||||
|
replyPost, _ := postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "reply post", RootId: rootPost.Id})
|
||||||
|
uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{
|
||||||
|
Deleted: false,
|
||||||
|
})
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
require.Equal(t, uss.TotalUnreadThreads, int64(1))
|
||||||
|
require.Equal(t, uss.Threads[0].PostId, rootPost.Id)
|
||||||
|
|
||||||
|
_, resp = th.Client.UpdateThreadReadForUser(th.BasicUser.Id, th.BasicChannel.TeamId, rootPost.Id, model.GetMillis())
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{
|
||||||
|
Deleted: false,
|
||||||
|
})
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
require.Equal(t, uss.TotalUnreadThreads, int64(0))
|
||||||
|
|
||||||
|
// edit post
|
||||||
|
editedReplyPostMessage := "edited " + replyPost.Message
|
||||||
|
_, resp = th.SystemAdminClient.PatchPost(replyPost.Id, &model.PostPatch{Message: &editedReplyPostMessage})
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{
|
||||||
|
Deleted: false,
|
||||||
|
})
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
require.Equal(t, uss.TotalUnreadThreads, int64(0))
|
||||||
|
|
||||||
|
// react to post
|
||||||
|
reaction := &model.Reaction{
|
||||||
|
UserId: th.SystemAdminUser.Id,
|
||||||
|
PostId: replyPost.Id,
|
||||||
|
EmojiName: "smile",
|
||||||
|
}
|
||||||
|
_, resp = th.SystemAdminClient.SaveReaction(reaction)
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{
|
||||||
|
Deleted: false,
|
||||||
|
})
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
require.Equal(t, uss.TotalUnreadThreads, int64(0))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestThreadSocketEvents(t *testing.T) {
|
func TestThreadSocketEvents(t *testing.T) {
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.Get
|
|||||||
model.Post
|
model.Post
|
||||||
}
|
}
|
||||||
|
|
||||||
unreadRepliesQuery := "SELECT COUNT(Posts.Id) From Posts Where Posts.RootId=ThreadMemberships.PostId AND Posts.UpdateAt >= ThreadMemberships.LastViewed"
|
unreadRepliesQuery := "SELECT COUNT(Posts.Id) From Posts Where Posts.RootId=ThreadMemberships.PostId AND Posts.CreateAt >= ThreadMemberships.LastViewed"
|
||||||
fetchConditions := sq.And{
|
fetchConditions := sq.And{
|
||||||
sq.Or{sq.Eq{"Channels.TeamId": teamId}, sq.Eq{"Channels.TeamId": ""}},
|
sq.Or{sq.Eq{"Channels.TeamId": teamId}, sq.Eq{"Channels.TeamId": ""}},
|
||||||
sq.Eq{"ThreadMemberships.UserId": userId},
|
sq.Eq{"ThreadMemberships.UserId": userId},
|
||||||
@@ -147,7 +147,7 @@ func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.Get
|
|||||||
LeftJoin("ThreadMemberships ON Posts.RootId = ThreadMemberships.PostId").
|
LeftJoin("ThreadMemberships ON Posts.RootId = ThreadMemberships.PostId").
|
||||||
LeftJoin("Channels ON Posts.ChannelId = Channels.Id").
|
LeftJoin("Channels ON Posts.ChannelId = Channels.Id").
|
||||||
Where(fetchConditions).
|
Where(fetchConditions).
|
||||||
Where("Posts.UpdateAt >= ThreadMemberships.LastViewed").ToSql()
|
Where("Posts.CreateAt >= ThreadMemberships.LastViewed").ToSql()
|
||||||
|
|
||||||
totalUnreadThreads, err := s.GetMaster().SelectInt(repliesQuery, repliesQueryArgs...)
|
totalUnreadThreads, err := s.GetMaster().SelectInt(repliesQuery, repliesQueryArgs...)
|
||||||
totalUnreadThreadsChan <- store.StoreResult{Data: totalUnreadThreads, NErr: errors.Wrapf(err, "failed to get count unread on threads for user id=%s", userId)}
|
totalUnreadThreadsChan <- store.StoreResult{Data: totalUnreadThreads, NErr: errors.Wrapf(err, "failed to get count unread on threads for user id=%s", userId)}
|
||||||
@@ -334,7 +334,7 @@ func (s *SqlThreadStore) GetThreadForUser(userId, teamId, threadId string, exten
|
|||||||
model.Post
|
model.Post
|
||||||
}
|
}
|
||||||
|
|
||||||
unreadRepliesQuery := "SELECT COUNT(Posts.Id) From Posts Where Posts.RootId=ThreadMemberships.PostId AND Posts.UpdateAt >= ThreadMemberships.LastViewed AND Posts.DeleteAt=0"
|
unreadRepliesQuery := "SELECT COUNT(Posts.Id) From Posts Where Posts.RootId=ThreadMemberships.PostId AND Posts.CreateAt >= ThreadMemberships.LastViewed AND Posts.DeleteAt=0"
|
||||||
fetchConditions := sq.And{
|
fetchConditions := sq.And{
|
||||||
sq.Or{sq.Eq{"Channels.TeamId": teamId}, sq.Eq{"Channels.TeamId": ""}},
|
sq.Or{sq.Eq{"Channels.TeamId": teamId}, sq.Eq{"Channels.TeamId": ""}},
|
||||||
sq.Eq{"ThreadMemberships.UserId": userId},
|
sq.Eq{"ThreadMemberships.UserId": userId},
|
||||||
|
|||||||
@@ -329,4 +329,29 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
|||||||
return m2.LastUpdated < m.LastUpdated
|
return m2.LastUpdated < m.LastUpdated
|
||||||
}, time.Second, 10*time.Millisecond)
|
}, time.Second, 10*time.Millisecond)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Updating post does not make thread unread", func(t *testing.T) {
|
||||||
|
newPosts := makeSomePosts()
|
||||||
|
m, err := ss.Thread().MaintainMembership(newPosts[0].UserId, newPosts[0].Id, true, false, true, true, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
th, err := ss.Thread().GetThreadForUser(newPosts[0].UserId, "", newPosts[0].Id, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(2), th.UnreadReplies)
|
||||||
|
|
||||||
|
m.LastViewed = newPosts[2].UpdateAt + 1
|
||||||
|
_, err = ss.Thread().UpdateMembership(m)
|
||||||
|
require.NoError(t, err)
|
||||||
|
th, err = ss.Thread().GetThreadForUser(newPosts[0].UserId, "", newPosts[0].Id, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), th.UnreadReplies)
|
||||||
|
|
||||||
|
editedPost := newPosts[2].Clone()
|
||||||
|
editedPost.Message = "This is an edited post"
|
||||||
|
_, err = ss.Post().Update(editedPost, newPosts[2])
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
th, err = ss.Thread().GetThreadForUser(newPosts[0].UserId, "", newPosts[0].Id, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), th.UnreadReplies)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user