Only consider flagged posts that are on channels you are member of (#18380)

* Only consider flagged posts that are on channels you are member of

* Fix and add tests
Этот коммит содержится в:
Daniel Espino García
2021-09-29 23:16:25 +02:00
коммит произвёл GitHub
родитель a519b86e8f
Коммит 305e4793c3
2 изменённых файлов: 186 добавлений и 51 удалений

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

@@ -410,26 +410,21 @@ func (s *SqlPostStore) Overwrite(post *model.Post) (*model.Post, error) {
}
func (s *SqlPostStore) GetFlaggedPosts(userId string, offset int, limit int) (*model.PostList, error) {
pl := model.NewPostList()
var posts []*model.Post
if _, err := s.GetReplica().Select(&posts, "SELECT *, (SELECT count(Posts.Id) FROM Posts WHERE Posts.RootId = (CASE WHEN p.RootId = '' THEN p.Id ELSE p.RootId END) AND Posts.DeleteAt = 0) as ReplyCount FROM Posts p WHERE Id IN (SELECT Name FROM Preferences WHERE UserId = :UserId AND Category = :Category) AND DeleteAt = 0 ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset", map[string]interface{}{"UserId": userId, "Category": model.PreferenceCategoryFlaggedPost, "Offset": offset, "Limit": limit}); err != nil {
return nil, errors.Wrap(err, "failed to find Posts")
}
for _, post := range posts {
pl.AddPost(post)
pl.AddOrder(post.Id)
}
return pl, nil
return s.getFlaggedPosts(userId, "", "", offset, limit)
}
func (s *SqlPostStore) GetFlaggedPostsForTeam(userId, teamId string, offset int, limit int) (*model.PostList, error) {
return s.getFlaggedPosts(userId, "", teamId, offset, limit)
}
func (s *SqlPostStore) GetFlaggedPostsForChannel(userId, channelId string, offset int, limit int) (*model.PostList, error) {
return s.getFlaggedPosts(userId, channelId, "", offset, limit)
}
func (s *SqlPostStore) getFlaggedPosts(userId, channelId, teamId string, offset int, limit int) (*model.PostList, error) {
pl := model.NewPostList()
var posts []*model.Post
query := `
SELECT
A.*, (SELECT count(Posts.Id) FROM Posts WHERE Posts.RootId = (CASE WHEN A.RootId = '' THEN A.Id ELSE A.RootId END) AND Posts.DeleteAt = 0) as ReplyCount
@@ -441,22 +436,49 @@ func (s *SqlPostStore) GetFlaggedPostsForTeam(userId, teamId string, offset int,
WHERE
Id
IN
(SELECT
Name
FROM
Preferences
WHERE
UserId = :UserId
AND Category = :Category)
AND DeleteAt = 0
(
SELECT
Name
FROM
Preferences
WHERE
UserId = :UserId
AND Category = :Category
)
CHANNEL_FILTER
AND DeleteAt = 0
) as A
INNER JOIN Channels as B
ON B.Id = A.ChannelId
WHERE B.TeamId = :TeamId OR B.TeamId = ''
WHERE
ChannelId IN (
SELECT
Id
FROM
Channels,
ChannelMembers
WHERE
Id = ChannelId
AND UserId = :UserId
)
TEAM_FILTER
ORDER BY CreateAt DESC
LIMIT :Limit OFFSET :Offset`
if _, err := s.GetReplica().Select(&posts, query, map[string]interface{}{"UserId": userId, "Category": model.PreferenceCategoryFlaggedPost, "Offset": offset, "Limit": limit, "TeamId": teamId}); err != nil {
queryParams := map[string]interface{}{
"UserId": userId,
"Category": model.PreferenceCategoryFlaggedPost,
"Offset": offset,
"Limit": limit,
}
teamClause, queryParams := s.buildFlaggedPostTeamFilterClause(teamId, queryParams)
query = strings.Replace(query, "TEAM_FILTER", teamClause, 1)
channelClause, queryParams := s.buildFlaggedPostChannelFilterClause(channelId, queryParams)
query = strings.Replace(query, "CHANNEL_FILTER", channelClause, 1)
if _, err := s.GetReplica().Select(&posts, query, queryParams); err != nil {
return nil, errors.Wrap(err, "failed to find Posts")
}
@@ -468,31 +490,26 @@ func (s *SqlPostStore) GetFlaggedPostsForTeam(userId, teamId string, offset int,
return pl, nil
}
func (s *SqlPostStore) GetFlaggedPostsForChannel(userId, channelId string, offset int, limit int) (*model.PostList, error) {
pl := model.NewPostList()
var posts []*model.Post
query := `
SELECT
*, (SELECT count(Posts.Id) FROM Posts WHERE Posts.RootId = (CASE WHEN p.RootId = '' THEN p.Id ELSE p.RootId END) AND Posts.DeleteAt = 0) as ReplyCount
FROM Posts p
WHERE
Id IN (SELECT Name FROM Preferences WHERE UserId = :UserId AND Category = :Category)
AND ChannelId = :ChannelId
AND DeleteAt = 0
ORDER BY CreateAt DESC
LIMIT :Limit OFFSET :Offset`
if _, err := s.GetReplica().Select(&posts, query, map[string]interface{}{"UserId": userId, "Category": model.PreferenceCategoryFlaggedPost, "ChannelId": channelId, "Offset": offset, "Limit": limit}); err != nil {
return nil, errors.Wrap(err, "failed to find Posts")
}
for _, post := range posts {
pl.AddPost(post)
pl.AddOrder(post.Id)
func (s *SqlPostStore) buildFlaggedPostTeamFilterClause(teamId string, queryParams map[string]interface{}) (string, map[string]interface{}) {
if teamId == "" {
return "", queryParams
}
return pl, nil
queryParams["TeamId"] = teamId
return "AND B.TeamId = :TeamId OR B.TeamId = ''", queryParams
}
func (s *SqlPostStore) buildFlaggedPostChannelFilterClause(channelId string, queryParams map[string]interface{}) (string, map[string]interface{}) {
if channelId == "" {
return "", queryParams
}
queryParams["ChannelId"] = channelId
return "AND ChannelId = :ChannelId", queryParams
}
func (s *SqlPostStore) getPostWithCollapsedThreads(id, userID string, extended bool) (*model.PostList, error) {
if id == "" {
return nil, store.NewErrInvalidInput("Post", "id", id)

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

@@ -1961,6 +1961,13 @@ func testPostStoreGetFlaggedPostsForTeam(t *testing.T, ss store.Store, s SqlStor
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
m0 := &model.ChannelMember{}
m0.ChannelId = c1.Id
m0.UserId = o1.UserId
m0.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err = ss.Channel().SaveMember(m0)
require.NoError(t, err)
o4 := &model.Post{}
o4.ChannelId = model.NewId()
o4.UserId = model.NewId()
@@ -1995,6 +2002,15 @@ func testPostStoreGetFlaggedPostsForTeam(t *testing.T, ss store.Store, s SqlStor
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
// Post on channel where user is not a member
o6 := &model.Post{}
o6.ChannelId = model.NewId()
o6.UserId = m2.UserId
o6.Message = NewTestId()
o6, err = ss.Post().Save(o6)
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
r1, err := ss.Post().GetFlaggedPosts(o1.ChannelId, 0, 2)
require.NoError(t, err)
@@ -2094,16 +2110,39 @@ func testPostStoreGetFlaggedPostsForTeam(t *testing.T, ss store.Store, s SqlStor
require.NoError(t, err)
require.Len(t, r4.Order, 3, "should have 3 posts")
preferences = model.Preferences{
{
UserId: o1.UserId,
Category: model.PreferenceCategoryFlaggedPost,
Name: o6.Id,
Value: "true",
},
}
err = ss.Preference().Save(preferences)
require.NoError(t, err)
r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 10)
require.NoError(t, err)
require.Len(t, r4.Order, 3, "should have 3 posts")
// Manually truncate Channels table until testlib can handle cleanups
s.GetMaster().Exec("TRUNCATE Channels")
}
func testPostStoreGetFlaggedPosts(t *testing.T, ss store.Store) {
c1 := &model.Channel{}
c1.TeamId = model.NewId()
c1.DisplayName = "Channel1"
c1.Name = NewTestId()
c1.Type = model.ChannelTypeOpen
c1, err := ss.Channel().Save(c1, -1)
require.NoError(t, err)
o1 := &model.Post{}
o1.ChannelId = model.NewId()
o1.ChannelId = c1.Id
o1.UserId = model.NewId()
o1.Message = NewTestId()
o1, err := ss.Post().Save(o1)
o1, err = ss.Post().Save(o1)
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
@@ -2124,6 +2163,22 @@ func testPostStoreGetFlaggedPosts(t *testing.T, ss store.Store) {
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
// Post on channel where user is not a member
o4 := &model.Post{}
o4.ChannelId = model.NewId()
o4.UserId = model.NewId()
o4.Message = NewTestId()
o4, err = ss.Post().Save(o4)
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
m0 := &model.ChannelMember{}
m0.ChannelId = o1.ChannelId
m0.UserId = o1.UserId
m0.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err = ss.Channel().SaveMember(m0)
require.NoError(t, err)
r1, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
require.NoError(t, err)
require.Empty(t, r1.Order, "should be empty")
@@ -2187,14 +2242,46 @@ func testPostStoreGetFlaggedPosts(t *testing.T, ss store.Store) {
r4, err = ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
require.NoError(t, err)
require.Len(t, r4.Order, 2, "should have 2 posts")
preferences = model.Preferences{
{
UserId: o1.UserId,
Category: model.PreferenceCategoryFlaggedPost,
Name: o4.Id,
Value: "true",
},
}
nErr = ss.Preference().Save(preferences)
require.NoError(t, nErr)
r4, err = ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
require.NoError(t, err)
require.Len(t, r4.Order, 2, "should have 2 posts")
}
func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
c1 := &model.Channel{}
c1.TeamId = model.NewId()
c1.DisplayName = "Channel1"
c1.Name = NewTestId()
c1.Type = model.ChannelTypeOpen
c1, err := ss.Channel().Save(c1, -1)
require.NoError(t, err)
c2 := &model.Channel{}
c2.TeamId = model.NewId()
c2.DisplayName = "Channel2"
c2.Name = NewTestId()
c2.Type = model.ChannelTypeOpen
c2, err = ss.Channel().Save(c2, -1)
require.NoError(t, err)
o1 := &model.Post{}
o1.ChannelId = model.NewId()
o1.ChannelId = c1.Id
o1.UserId = model.NewId()
o1.Message = NewTestId()
o1, err := ss.Post().Save(o1)
o1, err = ss.Post().Save(o1)
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
@@ -2217,13 +2304,36 @@ func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
time.Sleep(2 * time.Millisecond)
o4 := &model.Post{}
o4.ChannelId = model.NewId()
o4.ChannelId = c2.Id
o4.UserId = model.NewId()
o4.Message = NewTestId()
o4, err = ss.Post().Save(o4)
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
// Post on channel where user is not a member
o5 := &model.Post{}
o5.ChannelId = model.NewId()
o5.UserId = model.NewId()
o5.Message = NewTestId()
o5, err = ss.Post().Save(o5)
require.NoError(t, err)
time.Sleep(2 * time.Millisecond)
m1 := &model.ChannelMember{}
m1.ChannelId = o1.ChannelId
m1.UserId = o1.UserId
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err = ss.Channel().SaveMember(m1)
require.NoError(t, err)
m2 := &model.ChannelMember{}
m2.ChannelId = o4.ChannelId
m2.UserId = o1.UserId
m2.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err = ss.Channel().SaveMember(m2)
require.NoError(t, err)
r, err := ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
require.NoError(t, err)
require.Empty(t, r.Order, "should be empty")
@@ -2273,6 +2383,14 @@ func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o4.ChannelId, 0, 10)
require.NoError(t, err)
require.Len(t, r.Order, 1, "should have 1 posts")
preference.Name = o5.Id
nErr = ss.Preference().Save(model.Preferences{preference})
require.NoError(t, nErr)
r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o5.ChannelId, 0, 10)
require.NoError(t, err)
require.Len(t, r.Order, 0, "should have 0 posts")
}
func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) {