MM-29703 Mark threads as read when channels are marked (#15994)
Co-authored-by: Jesús Espino <jespinog@gmail.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1729239385
Коммит
fe352ab57f
@@ -4157,11 +4157,11 @@ func testChannelStoreUpdateLastViewedAt(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, err)
|
||||
|
||||
var times map[string]int64
|
||||
times, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, m1.UserId)
|
||||
times, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, m1.UserId, false)
|
||||
require.Nil(t, err, "failed to update ", err)
|
||||
require.Equal(t, o1.LastPostAt, times[o1.Id], "last viewed at time incorrect")
|
||||
|
||||
times, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId, m2.ChannelId}, m1.UserId)
|
||||
times, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId, m2.ChannelId}, m1.UserId, false)
|
||||
require.Nil(t, err, "failed to update ", err)
|
||||
require.Equal(t, o2.LastPostAt, times[o2.Id], "last viewed at time incorrect")
|
||||
|
||||
@@ -4177,7 +4177,7 @@ func testChannelStoreUpdateLastViewedAt(t *testing.T, ss store.Store) {
|
||||
assert.Equal(t, o2.LastPostAt, rm2.LastUpdateAt)
|
||||
assert.Equal(t, o2.TotalMsgCount, rm2.MsgCount)
|
||||
|
||||
_, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, "missing id")
|
||||
_, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, "missing id", false)
|
||||
require.Nil(t, err, "failed to update")
|
||||
}
|
||||
|
||||
@@ -4198,16 +4198,16 @@ func testChannelStoreIncrementMentionCount(t *testing.T, ss store.Store) {
|
||||
_, err := ss.Channel().SaveMember(&m1)
|
||||
require.Nil(t, err)
|
||||
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, m1.UserId)
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, m1.UserId, false)
|
||||
require.Nil(t, err, "failed to update")
|
||||
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, "missing id")
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, "missing id", false)
|
||||
require.Nil(t, err, "failed to update")
|
||||
|
||||
err = ss.Channel().IncrementMentionCount("missing id", m1.UserId)
|
||||
err = ss.Channel().IncrementMentionCount("missing id", m1.UserId, false)
|
||||
require.Nil(t, err, "failed to update")
|
||||
|
||||
err = ss.Channel().IncrementMentionCount("missing id", "missing id")
|
||||
err = ss.Channel().IncrementMentionCount("missing id", "missing id", false)
|
||||
require.Nil(t, err, "failed to update")
|
||||
}
|
||||
|
||||
|
||||
@@ -1252,13 +1252,13 @@ func (_m *ChannelStore) GroupSyncedChannelCount() (int64, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// IncrementMentionCount provides a mock function with given fields: channelId, userId
|
||||
func (_m *ChannelStore) IncrementMentionCount(channelId string, userId string) error {
|
||||
ret := _m.Called(channelId, userId)
|
||||
// IncrementMentionCount provides a mock function with given fields: channelId, userId, updateThreads
|
||||
func (_m *ChannelStore) IncrementMentionCount(channelId string, userId string, updateThreads bool) error {
|
||||
ret := _m.Called(channelId, userId, updateThreads)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(channelId, userId)
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool) error); ok {
|
||||
r0 = rf(channelId, userId, updateThreads)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
@@ -1752,13 +1752,13 @@ func (_m *ChannelStore) Update(channel *model.Channel) (*model.Channel, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateLastViewedAt provides a mock function with given fields: channelIds, userId
|
||||
func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string) (map[string]int64, error) {
|
||||
ret := _m.Called(channelIds, userId)
|
||||
// UpdateLastViewedAt provides a mock function with given fields: channelIds, userId, updateThreads
|
||||
func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string, updateThreads bool) (map[string]int64, error) {
|
||||
ret := _m.Called(channelIds, userId, updateThreads)
|
||||
|
||||
var r0 map[string]int64
|
||||
if rf, ok := ret.Get(0).(func([]string, string) map[string]int64); ok {
|
||||
r0 = rf(channelIds, userId)
|
||||
if rf, ok := ret.Get(0).(func([]string, string, bool) map[string]int64); ok {
|
||||
r0 = rf(channelIds, userId, updateThreads)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(map[string]int64)
|
||||
@@ -1766,8 +1766,8 @@ func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string) (
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func([]string, string) error); ok {
|
||||
r1 = rf(channelIds, userId)
|
||||
if rf, ok := ret.Get(1).(func([]string, string, bool) error); ok {
|
||||
r1 = rf(channelIds, userId, updateThreads)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -1775,13 +1775,13 @@ func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string) (
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateLastViewedAtPost provides a mock function with given fields: unreadPost, userID, mentionCount
|
||||
func (_m *ChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int) (*model.ChannelUnreadAt, error) {
|
||||
ret := _m.Called(unreadPost, userID, mentionCount)
|
||||
// UpdateLastViewedAtPost provides a mock function with given fields: unreadPost, userID, mentionCount, updateThreads
|
||||
func (_m *ChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
ret := _m.Called(unreadPost, userID, mentionCount, updateThreads)
|
||||
|
||||
var r0 *model.ChannelUnreadAt
|
||||
if rf, ok := ret.Get(0).(func(*model.Post, string, int) *model.ChannelUnreadAt); ok {
|
||||
r0 = rf(unreadPost, userID, mentionCount)
|
||||
if rf, ok := ret.Get(0).(func(*model.Post, string, int, bool) *model.ChannelUnreadAt); ok {
|
||||
r0 = rf(unreadPost, userID, mentionCount, updateThreads)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.ChannelUnreadAt)
|
||||
@@ -1789,8 +1789,8 @@ func (_m *ChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID st
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.Post, string, int) error); ok {
|
||||
r1 = rf(unreadPost, userID, mentionCount)
|
||||
if rf, ok := ret.Get(1).(func(*model.Post, string, int, bool) error); ok {
|
||||
r1 = rf(unreadPost, userID, mentionCount, updateThreads)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,29 @@ type ThreadStore struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CollectThreadsWithNewerReplies provides a mock function with given fields: userId, channelIds, timestamp
|
||||
func (_m *ThreadStore) CollectThreadsWithNewerReplies(userId string, channelIds []string, timestamp int64) ([]string, error) {
|
||||
ret := _m.Called(userId, channelIds, timestamp)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(string, []string, int64) []string); ok {
|
||||
r0 = rf(userId, channelIds, timestamp)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, []string, int64) error); ok {
|
||||
r1 = rf(userId, channelIds, timestamp)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CreateMembershipIfNeeded provides a mock function with given fields: userId, postId
|
||||
func (_m *ThreadStore) CreateMembershipIfNeeded(userId string, postId string) error {
|
||||
ret := _m.Called(userId, postId)
|
||||
@@ -246,3 +269,17 @@ func (_m *ThreadStore) UpdateMembership(membership *model.ThreadMembership) (*mo
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateUnreadsByChannel provides a mock function with given fields: userId, changedThreads, timestamp
|
||||
func (_m *ThreadStore) UpdateUnreadsByChannel(userId string, changedThreads []string, timestamp int64) error {
|
||||
ret := _m.Called(userId, changedThreads, timestamp)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, []string, int64) error); ok {
|
||||
r0 = rf(userId, changedThreads, timestamp)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@ package storetest
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/store"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestThreadStore(t *testing.T, ss store.Store, s SqlSupplier) {
|
||||
@@ -16,42 +18,72 @@ func TestThreadStore(t *testing.T, ss store.Store, s SqlSupplier) {
|
||||
|
||||
func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
makeSomePosts := func() []*model.Post {
|
||||
o1 := model.Post{}
|
||||
o1.ChannelId = model.NewId()
|
||||
o1.UserId = model.NewId()
|
||||
o1.RootId = model.NewId()
|
||||
o1.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
u1 := model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewId(),
|
||||
}
|
||||
|
||||
u, err := ss.User().Save(&u1)
|
||||
require.Nil(t, err)
|
||||
|
||||
c, err2 := ss.Channel().Save(&model.Channel{
|
||||
DisplayName: model.NewId(),
|
||||
Type: model.CHANNEL_OPEN,
|
||||
Name: model.NewId(),
|
||||
}, 999)
|
||||
require.NoError(t, err2)
|
||||
|
||||
_, err44 := ss.Channel().SaveMember(&model.ChannelMember{
|
||||
ChannelId: c.Id,
|
||||
UserId: u1.Id,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
MsgCount: 90,
|
||||
})
|
||||
require.NoError(t, err44)
|
||||
o := model.Post{}
|
||||
o.ChannelId = c.Id
|
||||
o.UserId = u.Id
|
||||
o.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
otmp, err3 := ss.Post().Save(&o)
|
||||
require.NoError(t, err3)
|
||||
o2 := model.Post{}
|
||||
o2.ChannelId = model.NewId()
|
||||
o2.ChannelId = c.Id
|
||||
o2.UserId = model.NewId()
|
||||
o2.RootId = o1.RootId
|
||||
o2.RootId = otmp.Id
|
||||
o2.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
o3 := model.Post{}
|
||||
o3.ChannelId = model.NewId()
|
||||
o3.UserId = model.NewId()
|
||||
o3.RootId = model.NewId()
|
||||
o3.ChannelId = c.Id
|
||||
o3.UserId = u.Id
|
||||
o3.RootId = otmp.Id
|
||||
o3.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
o4 := model.Post{}
|
||||
o4.ChannelId = model.NewId()
|
||||
o4.ChannelId = c.Id
|
||||
o4.UserId = model.NewId()
|
||||
o4.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
newPosts, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&o1, &o2, &o3, &o4})
|
||||
require.Nil(t, err, "couldn't save item")
|
||||
newPosts, errIdx, err3 := ss.Post().SaveMultiple([]*model.Post{&o2, &o3, &o4})
|
||||
|
||||
olist, _ := ss.Post().Get(otmp.Id, true)
|
||||
o1 := olist.Posts[olist.Order[0]]
|
||||
|
||||
newPosts = append([]*model.Post{o1}, newPosts...)
|
||||
require.Nil(t, err3, "couldn't save item")
|
||||
require.Equal(t, -1, errIdx)
|
||||
require.Len(t, newPosts, 4)
|
||||
require.Equal(t, int64(2), newPosts[0].ReplyCount)
|
||||
require.Equal(t, int64(2), newPosts[1].ReplyCount)
|
||||
require.Equal(t, int64(1), newPosts[2].ReplyCount)
|
||||
require.Equal(t, int64(2), newPosts[2].ReplyCount)
|
||||
require.Equal(t, int64(0), newPosts[3].ReplyCount)
|
||||
|
||||
return newPosts
|
||||
}
|
||||
t.Run("Save replies creates a thread", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
thread, err := ss.Thread().Get(newPosts[0].RootId)
|
||||
thread, err := ss.Thread().Get(newPosts[0].Id)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(2), thread.ReplyCount)
|
||||
@@ -60,13 +92,13 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
o5 := model.Post{}
|
||||
o5.ChannelId = model.NewId()
|
||||
o5.UserId = model.NewId()
|
||||
o5.RootId = newPosts[0].RootId
|
||||
o5.RootId = newPosts[0].Id
|
||||
o5.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
_, _, err = ss.Post().SaveMultiple([]*model.Post{&o5})
|
||||
require.Nil(t, err, "couldn't save item")
|
||||
|
||||
thread, err = ss.Thread().Get(newPosts[0].RootId)
|
||||
thread, err = ss.Thread().Get(newPosts[0].Id)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(3), thread.ReplyCount)
|
||||
@@ -75,7 +107,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
|
||||
t.Run("Delete a reply updates count on a thread", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
thread, err := ss.Thread().Get(newPosts[0].RootId)
|
||||
thread, err := ss.Thread().Get(newPosts[0].Id)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(2), thread.ReplyCount)
|
||||
@@ -84,7 +116,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
err = ss.Post().Delete(newPosts[1].Id, 1234, model.NewId())
|
||||
require.Nil(t, err, "couldn't delete post")
|
||||
|
||||
thread, err = ss.Thread().Get(newPosts[0].RootId)
|
||||
thread, err = ss.Thread().Get(newPosts[0].Id)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(1), thread.ReplyCount)
|
||||
@@ -197,4 +229,84 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
thread2, _ := ss.Thread().Get(rootPost.Id)
|
||||
require.Nil(t, thread2)
|
||||
})
|
||||
|
||||
t.Run("Thread last updated is changed when channel is updated after UpdateLastViewedAtPost", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
|
||||
require.Nil(t, ss.Thread().CreateMembershipIfNeeded(newPosts[0].UserId, newPosts[0].Id))
|
||||
m, err1 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err1)
|
||||
m.LastUpdated -= 1000
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ss.Channel().UpdateLastViewedAtPost(newPosts[0], newPosts[0].UserId, 0, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
m2, err2 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err2)
|
||||
return m2.LastUpdated > m.LastUpdated
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
})
|
||||
|
||||
t.Run("Thread last updated is changed when channel is updated after IncrementMentionCount", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
|
||||
require.Nil(t, ss.Thread().CreateMembershipIfNeeded(newPosts[0].UserId, newPosts[0].Id))
|
||||
m, err1 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err1)
|
||||
m.LastUpdated -= 1000
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.Nil(t, err)
|
||||
|
||||
err = ss.Channel().IncrementMentionCount(newPosts[0].ChannelId, newPosts[0].UserId, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
m2, err2 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err2)
|
||||
return m2.LastUpdated > m.LastUpdated
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
})
|
||||
|
||||
t.Run("Thread last updated is changed when channel is updated after UpdateLastViewedAt", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
|
||||
require.Nil(t, ss.Thread().CreateMembershipIfNeeded(newPosts[0].UserId, newPosts[0].Id))
|
||||
m, err1 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err1)
|
||||
m.LastUpdated -= 1000
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ss.Channel().UpdateLastViewedAt([]string{newPosts[0].ChannelId}, newPosts[0].UserId, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
m2, err2 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err2)
|
||||
return m2.LastUpdated > m.LastUpdated
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
})
|
||||
|
||||
t.Run("Thread last updated is changed when channel is updated after UpdateLastViewedAtPost for mark unread", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
|
||||
require.Nil(t, ss.Thread().CreateMembershipIfNeeded(newPosts[0].UserId, newPosts[0].Id))
|
||||
m, err1 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err1)
|
||||
m.LastUpdated += 1000
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ss.Channel().UpdateLastViewedAtPost(newPosts[0], newPosts[0].UserId, 0, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
m2, err2 := ss.Thread().GetMembershipForUser(newPosts[0].UserId, newPosts[0].Id)
|
||||
require.Nil(t, err2)
|
||||
return m2.LastUpdated < m.LastUpdated
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2172,7 +2172,7 @@ func testUserUnreadCount(t *testing.T, ss store.Store) {
|
||||
// Post one message with mention to open channel
|
||||
_, nErr = ss.Post().Save(&p1)
|
||||
require.Nil(t, nErr)
|
||||
nErr = ss.Channel().IncrementMentionCount(c1.Id, u2.Id)
|
||||
nErr = ss.Channel().IncrementMentionCount(c1.Id, u2.Id, false)
|
||||
require.Nil(t, nErr)
|
||||
|
||||
// Post 2 messages without mention to direct channel
|
||||
@@ -2183,7 +2183,7 @@ func testUserUnreadCount(t *testing.T, ss store.Store) {
|
||||
|
||||
_, nErr = ss.Post().Save(&p2)
|
||||
require.Nil(t, nErr)
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id)
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id, false)
|
||||
require.Nil(t, nErr)
|
||||
|
||||
p3 := model.Post{}
|
||||
@@ -2193,7 +2193,7 @@ func testUserUnreadCount(t *testing.T, ss store.Store) {
|
||||
_, nErr = ss.Post().Save(&p3)
|
||||
require.Nil(t, nErr)
|
||||
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id)
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id, false)
|
||||
require.Nil(t, nErr)
|
||||
|
||||
badge, unreadCountErr := ss.User().GetUnreadCount(u2.Id)
|
||||
|
||||
Ссылка в новой задаче
Block a user