From 0cc72342de7cd2c305d46f8635755d46a108242f Mon Sep 17 00:00:00 2001 From: Eli Yukelzon Date: Tue, 23 Mar 2021 13:31:54 +0200 Subject: [PATCH] MM-33544 is_following prop in getPosts API methods (#17093) Co-authored-by: Mattermod --- api4/post.go | 12 +- app/app_iface.go | 2 +- app/file.go | 2 +- app/opentracing/opentracing_layer.go | 4 +- app/plugin_api.go | 2 +- app/post.go | 18 +-- app/post_test.go | 1 + model/post.go | 3 + store/opentracinglayer/opentracinglayer.go | 4 +- store/retrylayer/retrylayer.go | 4 +- store/searchlayer/post_layer.go | 2 +- store/sqlstore/post_store.go | 41 +++++-- store/store.go | 2 +- store/storetest/mocks/PostStore.go | 14 +-- store/storetest/post_store.go | 129 ++++++++++++--------- store/storetest/reaction_store.go | 24 ++-- store/storetest/thread_store.go | 2 +- store/timerlayer/timerlayer.go | 4 +- 18 files changed, 162 insertions(+), 108 deletions(-) diff --git a/api4/post.go b/api4/post.go index 6291f9cf8e..cc3c95bf1e 100644 --- a/api4/post.go +++ b/api4/post.go @@ -174,7 +174,7 @@ func getPostsForChannel(c *Context, w http.ResponseWriter, r *http.Request) { etag := "" if since > 0 { - list, err = c.App.GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: since, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended}) + list, err = c.App.GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: since, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended, UserId: c.App.Session().UserId}) } else if afterPost != "" { etag = c.App.GetPostsEtag(channelId, collapsedThreads) @@ -182,7 +182,7 @@ func getPostsForChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } - list, err = c.App.GetPostsAfterPost(model.GetPostsOptions{ChannelId: channelId, PostId: afterPost, Page: page, PerPage: perPage, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads}) + list, err = c.App.GetPostsAfterPost(model.GetPostsOptions{ChannelId: channelId, PostId: afterPost, Page: page, PerPage: perPage, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, UserId: c.App.Session().UserId}) } else if beforePost != "" { etag = c.App.GetPostsEtag(channelId, collapsedThreads) @@ -190,7 +190,7 @@ func getPostsForChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } - list, err = c.App.GetPostsBeforePost(model.GetPostsOptions{ChannelId: channelId, PostId: beforePost, Page: page, PerPage: perPage, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended}) + list, err = c.App.GetPostsBeforePost(model.GetPostsOptions{ChannelId: channelId, PostId: beforePost, Page: page, PerPage: perPage, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended, UserId: c.App.Session().UserId}) } else { etag = c.App.GetPostsEtag(channelId, collapsedThreads) @@ -198,7 +198,7 @@ func getPostsForChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } - list, err = c.App.GetPostsPage(model.GetPostsOptions{ChannelId: channelId, Page: page, PerPage: perPage, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended}) + list, err = c.App.GetPostsPage(model.GetPostsOptions{ChannelId: channelId, Page: page, PerPage: perPage, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended, UserId: c.App.Session().UserId}) } if err != nil { @@ -257,7 +257,7 @@ func getPostsForChannelAroundLastUnread(c *Context, w http.ResponseWriter, r *ht return } - postList, err = c.App.GetPostsPage(model.GetPostsOptions{ChannelId: channelId, Page: app.PageDefault, PerPage: c.Params.LimitBefore, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended}) + postList, err = c.App.GetPostsPage(model.GetPostsOptions{ChannelId: channelId, Page: app.PageDefault, PerPage: c.Params.LimitBefore, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended, UserId: c.App.Session().UserId}) if err != nil { c.Err = err return @@ -418,7 +418,7 @@ func getPostThread(c *Context, w http.ResponseWriter, r *http.Request) { skipFetchThreads := r.URL.Query().Get("skipFetchThreads") == "true" collapsedThreads := r.URL.Query().Get("collapsedThreads") == "true" collapsedThreadsExtended := r.URL.Query().Get("collapsedThreadsExtended") == "true" - list, err := c.App.GetPostThread(c.Params.PostId, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + list, err := c.App.GetPostThread(c.Params.PostId, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, c.App.Session().UserId) if err != nil { c.Err = err return diff --git a/app/app_iface.go b/app/app_iface.go index 2f96f32b87..fc04b7e30f 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -643,7 +643,7 @@ type AppIface interface { GetPostAfterTime(channelID string, time int64, collapsedThreads bool) (*model.Post, *model.AppError) GetPostIdAfterTime(channelID string, time int64, collapsedThreads bool) (string, *model.AppError) GetPostIdBeforeTime(channelID string, time int64, collapsedThreads bool) (string, *model.AppError) - GetPostThread(postID string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool) (*model.PostList, *model.AppError) + GetPostThread(postID string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool, userID string) (*model.PostList, *model.AppError) GetPosts(channelID string, offset int, limit int) (*model.PostList, *model.AppError) GetPostsAfterPost(options model.GetPostsOptions) (*model.PostList, *model.AppError) GetPostsAroundPost(before bool, options model.GetPostsOptions) (*model.PostList, *model.AppError) diff --git a/app/file.go b/app/file.go index bf983c1d02..237f108696 100644 --- a/app/file.go +++ b/app/file.go @@ -407,7 +407,7 @@ func (a *App) MigrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo { fileMigrationLock.Lock() defer fileMigrationLock.Unlock() - result, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, false, false, false) + result, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, false, false, false, "") if nErr != nil { mlog.Error("Unable to get post when migrating post to use FileInfos", mlog.Err(nErr), mlog.String("post_id", post.Id)) return []*model.FileInfo{} diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index fe4d9558ef..5bd21d32e2 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -7155,7 +7155,7 @@ func (a *OpenTracingAppLayer) GetPostIdBeforeTime(channelID string, time int64, return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) GetPostThread(postID string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool) (*model.PostList, *model.AppError) { +func (a *OpenTracingAppLayer) GetPostThread(postID string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool, userID string) (*model.PostList, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetPostThread") @@ -7167,7 +7167,7 @@ func (a *OpenTracingAppLayer) GetPostThread(postID string, skipFetchThreads bool }() defer span.Finish() - resultVar0, resultVar1 := a.app.GetPostThread(postID, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + resultVar0, resultVar1 := a.app.GetPostThread(postID, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) diff --git a/app/plugin_api.go b/app/plugin_api.go index d71f1c6d19..2e25de6980 100644 --- a/app/plugin_api.go +++ b/app/plugin_api.go @@ -574,7 +574,7 @@ func (api *PluginAPI) DeletePost(postID string) *model.AppError { } func (api *PluginAPI) GetPostThread(postID string) (*model.PostList, *model.AppError) { - return api.app.GetPostThread(postID, false, false, false) + return api.app.GetPostThread(postID, false, false, false, "") } func (api *PluginAPI) GetPost(postID string) (*model.Post, *model.AppError) { diff --git a/app/post.go b/app/post.go index d9c256146c..c5a6e8aac5 100644 --- a/app/post.go +++ b/app/post.go @@ -187,7 +187,7 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo if post.RootId != "" { pchan = make(chan store.StoreResult, 1) go func() { - r, pErr := a.Srv().Store.Post().Get(sqlstore.WithMaster(context.Background()), post.RootId, false, false, false) + r, pErr := a.Srv().Store.Post().Get(sqlstore.WithMaster(context.Background()), post.RootId, false, false, false, "") pchan <- store.StoreResult{Data: r, NErr: pErr} close(pchan) }() @@ -538,7 +538,7 @@ func (a *App) DeleteEphemeralPost(userID, postID string) { func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError) { post.SanitizeProps() - postLists, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, false, false, false) + postLists, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, false, false, false, "") if nErr != nil { var nfErr *store.ErrNotFound var invErr *store.ErrInvalidInput @@ -742,8 +742,8 @@ func (a *App) GetSinglePost(postID string) (*model.Post, *model.AppError) { return post, nil } -func (a *App) GetPostThread(postID string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool) (*model.PostList, *model.AppError) { - posts, err := a.Srv().Store.Post().Get(context.Background(), postID, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) +func (a *App) GetPostThread(postID string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool, userID string) (*model.PostList, *model.AppError) { + posts, err := a.Srv().Store.Post().Get(context.Background(), postID, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) if err != nil { var nfErr *store.ErrNotFound var invErr *store.ErrInvalidInput @@ -788,7 +788,7 @@ func (a *App) GetFlaggedPostsForChannel(userID, channelID string, offset int, li } func (a *App) GetPermalinkPost(postID string, userID string) (*model.PostList, *model.AppError) { - list, nErr := a.Srv().Store.Post().Get(context.Background(), postID, false, false, false) + list, nErr := a.Srv().Store.Post().Get(context.Background(), postID, false, false, false, userID) if nErr != nil { var nfErr *store.ErrNotFound var invErr *store.ErrInvalidInput @@ -987,7 +987,7 @@ func (a *App) GetPostsForChannelAroundLastUnread(channelID, userID string, limit return model.NewPostList(), nil } - postList, err := a.GetPostThread(lastUnreadPostId, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + postList, err := a.GetPostThread(lastUnreadPostId, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) if err != nil { return nil, err } @@ -995,13 +995,13 @@ func (a *App) GetPostsForChannelAroundLastUnread(channelID, userID string, limit // channel organically, those replies will be added below. postList.Order = []string{lastUnreadPostId} - if postListBefore, err := a.GetPostsBeforePost(model.GetPostsOptions{ChannelId: channelID, PostId: lastUnreadPostId, Page: PageDefault, PerPage: limitBefore, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended}); err != nil { + if postListBefore, err := a.GetPostsBeforePost(model.GetPostsOptions{ChannelId: channelID, PostId: lastUnreadPostId, Page: PageDefault, PerPage: limitBefore, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended, UserId: userID}); err != nil { return nil, err } else if postListBefore != nil { postList.Extend(postListBefore) } - if postListAfter, err := a.GetPostsAfterPost(model.GetPostsOptions{ChannelId: channelID, PostId: lastUnreadPostId, Page: PageDefault, PerPage: limitAfter - 1, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended}); err != nil { + if postListAfter, err := a.GetPostsAfterPost(model.GetPostsOptions{ChannelId: channelID, PostId: lastUnreadPostId, Page: PageDefault, PerPage: limitAfter - 1, SkipFetchThreads: skipFetchThreads, CollapsedThreads: collapsedThreads, CollapsedThreadsExtended: collapsedThreadsExtended, UserId: userID}); err != nil { return nil, err } else if postListAfter != nil { postList.Extend(postListAfter) @@ -1437,7 +1437,7 @@ func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, *m // A mapping of thread root IDs to whether or not a post in that thread mentions the user mentionedByThread := make(map[string]bool) - thread, err := a.GetPostThread(post.Id, false, false, false) + thread, err := a.GetPostThread(post.Id, false, false, false, user.Id) if err != nil { return 0, err } diff --git a/app/post_test.go b/app/post_test.go index faee08d8cc..eac35d6ad7 100644 --- a/app/post_test.go +++ b/app/post_test.go @@ -1964,6 +1964,7 @@ func TestCollapsedThreadFetch(t *testing.T) { require.EqualValues(t, []string{user1.Id, user2.Id}, []string{l.Posts[postRoot.Id].Participants[0].Id, l.Posts[postRoot.Id].Participants[1].Id}) require.Empty(t, l.Posts[postRoot.Id].Participants[0].Email) require.NotZero(t, l.Posts[postRoot.Id].LastReplyAt) + require.True(t, l.Posts[postRoot.Id].IsFollowing) // try extended fetch l, err = th.App.GetPostsForChannelAroundLastUnread(channel.Id, user1.Id, 10, 10, true, true, true) diff --git a/model/post.go b/model/post.go index c29f4db505..ebb69767e2 100644 --- a/model/post.go +++ b/model/post.go @@ -101,6 +101,7 @@ type Post struct { ReplyCount int64 `json:"reply_count" db:"-"` LastReplyAt int64 `json:"last_reply_at" db:"-"` Participants []*User `json:"participants" db:"-"` + IsFollowing bool `json:"is_following" db:"-"` // for root posts in collapsed thread mode indicates if the current user is following this thread Metadata *PostMetadata `json:"metadata,omitempty" db:"-"` } @@ -228,6 +229,7 @@ func (o *Post) ToUnsanitizedJson() string { } type GetPostsSinceOptions struct { + UserId string ChannelId string Time int64 SkipFetchThreads bool @@ -236,6 +238,7 @@ type GetPostsSinceOptions struct { } type GetPostsOptions struct { + UserId string ChannelId string PostId string Page int diff --git a/store/opentracinglayer/opentracinglayer.go b/store/opentracinglayer/opentracinglayer.go index c74df984e6..fc19473021 100644 --- a/store/opentracinglayer/opentracinglayer.go +++ b/store/opentracinglayer/opentracinglayer.go @@ -4934,7 +4934,7 @@ func (s *OpenTracingLayerPostStore) Delete(postID string, time int64, deleteByID return err } -func (s *OpenTracingLayerPostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool) (*model.PostList, error) { +func (s *OpenTracingLayerPostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool, userID string) (*model.PostList, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.Get") s.Root.Store.SetContext(newCtx) @@ -4943,7 +4943,7 @@ func (s *OpenTracingLayerPostStore) Get(ctx context.Context, id string, skipFetc }() defer span.Finish() - result, err := s.PostStore.Get(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + result, err := s.PostStore.Get(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) if err != nil { span.LogFields(spanlog.Error(err)) ext.Error.Set(span, true) diff --git a/store/retrylayer/retrylayer.go b/store/retrylayer/retrylayer.go index b4d9ab95c0..6592b84224 100644 --- a/store/retrylayer/retrylayer.go +++ b/store/retrylayer/retrylayer.go @@ -5342,11 +5342,11 @@ func (s *RetryLayerPostStore) Delete(postID string, time int64, deleteByID strin } -func (s *RetryLayerPostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool) (*model.PostList, error) { +func (s *RetryLayerPostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool, userID string) (*model.PostList, error) { tries := 0 for { - result, err := s.PostStore.Get(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + result, err := s.PostStore.Get(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) if err == nil { return result, nil } diff --git a/store/searchlayer/post_layer.go b/store/searchlayer/post_layer.go index bd3ed366bf..efeb39ae74 100644 --- a/store/searchlayer/post_layer.go +++ b/store/searchlayer/post_layer.go @@ -110,7 +110,7 @@ func (s SearchPostStore) Delete(postId string, date int64, deletedByID string) e err := s.PostStore.Delete(postId, date, deletedByID) if err == nil { - postList, err2 := s.PostStore.Get(context.Background(), postId, true, false, false) + postList, err2 := s.PostStore.Get(context.Background(), postId, true, false, false, "") if postList != nil && len(postList.Order) > 0 { if err2 != nil { s.deletePostIndex(postList.Posts[postList.Order[0]]) diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go index f769f1ac11..cfd013262f 100644 --- a/store/sqlstore/post_store.go +++ b/store/sqlstore/post_store.go @@ -33,6 +33,7 @@ type SqlPostStore struct { type postWithExtra struct { ThreadReplyCount int64 + IsFollowing bool ThreadParticipants model.StringArray model.Post } @@ -425,7 +426,7 @@ func (s *SqlPostStore) GetFlaggedPostsForChannel(userId, channelId string, offse return pl, nil } -func (s *SqlPostStore) getPostWithCollapsedThreads(id string, extended bool) (*model.PostList, error) { +func (s *SqlPostStore) getPostWithCollapsedThreads(id, userID string, extended bool) (*model.PostList, error) { if id == "" { return nil, store.NewErrInvalidInput("Post", "id", id) } @@ -434,13 +435,19 @@ func (s *SqlPostStore) getPostWithCollapsedThreads(id string, extended bool) (*m for _, c := range postSliceColumns() { columns = append(columns, "Posts."+c) } - columns = append(columns, "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", "COALESCE(Threads.Participants, '[]') as ThreadParticipants") + columns = append(columns, + "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", + "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", + "COALESCE(Threads.Participants, '[]') as ThreadParticipants", + "COALESCE(ThreadMemberships.Following, false) as IsFollowing", + ) var post postWithExtra postFetchQuery, args, _ := s.getQueryBuilder(). Select(columns...). From("Posts"). LeftJoin("Threads ON Threads.PostId = Id"). + LeftJoin("ThreadMemberships ON ThreadMemberships.PostId = Id AND ThreadMemberships.UserId = ?", userID). Where(sq.Eq{"DeleteAt": 0}). Where(sq.Eq{"Id": id}).ToSql() @@ -455,9 +462,9 @@ func (s *SqlPostStore) getPostWithCollapsedThreads(id string, extended bool) (*m return s.prepareThreadedResponse([]*postWithExtra{&post}, extended, false) } -func (s *SqlPostStore) Get(ctx context.Context, id string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool) (*model.PostList, error) { +func (s *SqlPostStore) Get(ctx context.Context, id string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool, userID string) (*model.PostList, error) { if collapsedThreads { - return s.getPostWithCollapsedThreads(id, collapsedThreadsExtended) + return s.getPostWithCollapsedThreads(id, userID, collapsedThreadsExtended) } pl := model.NewPostList() @@ -689,6 +696,7 @@ func (s *SqlPostStore) prepareThreadedResponse(posts []*postWithExtra, extended, } processPost := func(p *postWithExtra) error { p.Post.ReplyCount = p.ThreadReplyCount + p.Post.IsFollowing = p.IsFollowing for _, th := range p.ThreadParticipants { var participant *model.User for _, u := range users { @@ -728,7 +736,12 @@ func (s *SqlPostStore) getPostsCollapsedThreads(options model.GetPostsOptions) ( for _, c := range postSliceColumns() { columns = append(columns, "Posts."+c) } - columns = append(columns, "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", "COALESCE(Threads.Participants, '[]') as ThreadParticipants") + columns = append(columns, + "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", + "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", + "COALESCE(Threads.Participants, '[]') as ThreadParticipants", + "COALESCE(ThreadMemberships.Following, false) as IsFollowing", + ) var posts []*postWithExtra offset := options.PerPage * options.Page @@ -736,6 +749,7 @@ func (s *SqlPostStore) getPostsCollapsedThreads(options model.GetPostsOptions) ( Select(columns...). From("Posts"). LeftJoin("Threads ON Threads.PostId = Id"). + LeftJoin("ThreadMemberships ON ThreadMemberships.PostId = Id AND ThreadMemberships.UserId = ?", options.UserId). Where(sq.Eq{"DeleteAt": 0}). Where(sq.Eq{"Posts.ChannelId": options.ChannelId}). Where(sq.Eq{"RootId": ""}). @@ -808,13 +822,19 @@ func (s *SqlPostStore) getPostsSinceCollapsedThreads(options model.GetPostsSince for _, c := range postSliceColumns() { columns = append(columns, "Posts."+c) } - columns = append(columns, "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", "COALESCE(Threads.Participants, '[]') as ThreadParticipants") + columns = append(columns, + "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", + "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", + "COALESCE(Threads.Participants, '[]') as ThreadParticipants", + "COALESCE(ThreadMemberships.Following, false) as IsFollowing", + ) var posts []*postWithExtra postFetchQuery, args, _ := s.getQueryBuilder(). Select(columns...). From("Posts"). LeftJoin("Threads ON Threads.PostId = Id"). + LeftJoin("ThreadMemberships ON ThreadMemberships.PostId = Id AND ThreadMemberships.UserId = ?", options.UserId). Where(sq.Eq{"DeleteAt": 0}). Where(sq.Eq{"Posts.ChannelId": options.ChannelId}). Where(sq.Gt{"UpdateAt": options.Time}). @@ -944,7 +964,12 @@ func (s *SqlPostStore) getPostsAround(before bool, options model.GetPostsOptions } columns := []string{"p.*"} if options.CollapsedThreads { - columns = append(columns, "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", "COALESCE(Threads.Participants, '[]') as ThreadParticipants") + columns = append(columns, + "COALESCE(Threads.ReplyCount, 0) as ThreadReplyCount", + "COALESCE(Threads.LastReplyAt, 0) as LastReplyAt", + "COALESCE(Threads.Participants, '[]') as ThreadParticipants", + "COALESCE(ThreadMemberships.Following, false) as IsFollowing", + ) } query := s.getQueryBuilder().Select(columns...) replyCountSubQuery := s.getQueryBuilder().Select("COUNT(Posts.Id)").From("Posts").Where(sq.Expr("Posts.RootId = (CASE WHEN p.RootId = '' THEN p.Id ELSE p.RootId END) AND Posts.DeleteAt = 0")) @@ -956,7 +981,7 @@ func (s *SqlPostStore) getPostsAround(before bool, options model.GetPostsOptions } if options.CollapsedThreads { conditions = append(conditions, sq.Eq{"RootId": ""}) - query = query.LeftJoin("Threads ON Threads.PostId = p.Id") + query = query.LeftJoin("Threads ON Threads.PostId = p.Id").LeftJoin("ThreadMemberships ON ThreadMemberships.PostId = p.Id AND ThreadMemberships.UserId=?", options.UserId) } else { query = query.Column(sq.Alias(replyCountSubQuery, "ReplyCount")) } diff --git a/store/store.go b/store/store.go index c25d4c120f..2c61b2aae6 100644 --- a/store/store.go +++ b/store/store.go @@ -274,7 +274,7 @@ type PostStore interface { SaveMultiple(posts []*model.Post) ([]*model.Post, int, error) Save(post *model.Post) (*model.Post, error) Update(newPost *model.Post, oldPost *model.Post) (*model.Post, error) - Get(ctx context.Context, id string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool) (*model.PostList, error) + Get(ctx context.Context, id string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool, userID string) (*model.PostList, error) GetSingle(id string) (*model.Post, error) Delete(postID string, time int64, deleteByID string) error PermanentDeleteByUser(userId string) error diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go index d4e22a9b6f..7e168be423 100644 --- a/store/storetest/mocks/PostStore.go +++ b/store/storetest/mocks/PostStore.go @@ -102,13 +102,13 @@ func (_m *PostStore) Delete(postID string, time int64, deleteByID string) error return r0 } -// Get provides a mock function with given fields: ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended -func (_m *PostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool) (*model.PostList, error) { - ret := _m.Called(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) +// Get provides a mock function with given fields: ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID +func (_m *PostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool, userID string) (*model.PostList, error) { + ret := _m.Called(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) var r0 *model.PostList - if rf, ok := ret.Get(0).(func(context.Context, string, bool, bool, bool) *model.PostList); ok { - r0 = rf(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + if rf, ok := ret.Get(0).(func(context.Context, string, bool, bool, bool, string) *model.PostList); ok { + r0 = rf(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*model.PostList) @@ -116,8 +116,8 @@ func (_m *PostStore) Get(ctx context.Context, id string, skipFetchThreads bool, } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, bool, bool, bool) error); ok { - r1 = rf(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + if rf, ok := ret.Get(1).(func(context.Context, string, bool, bool, bool, string) error); ok { + r1 = rf(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) } else { r1 = ret.Error(1) } diff --git a/store/storetest/post_store.go b/store/storetest/post_store.go index 992a46d4b4..cbf428aeca 100644 --- a/store/storetest/post_store.go +++ b/store/storetest/post_store.go @@ -55,6 +55,8 @@ func TestPostStore(t *testing.T, ss store.Store, s SqlStore) { t.Run("GetDirectPostParentsForExportAfter", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfter(t, ss, s) }) t.Run("GetDirectPostParentsForExportAfterDeleted", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterDeleted(t, ss, s) }) t.Run("GetDirectPostParentsForExportAfterBatched", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterBatched(t, ss, s) }) + t.Run("GetForThread", func(t *testing.T) { testPostStoreGetForThread(t, ss) }) + } func testPostStoreSave(t *testing.T, ss store.Store) { @@ -417,17 +419,40 @@ func testPostStoreGet(t *testing.T, ss store.Store) { etag2 := ss.Post().GetEtag(o1.ChannelId, false, false) require.Equal(t, 0, strings.Index(etag2, fmt.Sprintf("%v.%v", model.CurrentVersion, o1.UpdateAt)), "Invalid Etag") - r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) require.Equal(t, r1.Posts[o1.Id].CreateAt, o1.CreateAt, "invalid returned post") - _, err = ss.Post().Get(context.Background(), "123", false, false, false) + _, err = ss.Post().Get(context.Background(), "123", false, false, false, "") require.Error(t, err, "Missing id should have failed") - _, err = ss.Post().Get(context.Background(), "", false, false, false) + _, err = ss.Post().Get(context.Background(), "", false, false, false, "") require.Error(t, err, "should fail for blank post ids") } +func testPostStoreGetForThread(t *testing.T, ss store.Store) { + o1 := &model.Post{ChannelId: model.NewId(), UserId: model.NewId(), Message: "zz" + model.NewId() + "b"} + o1, err := ss.Post().Save(o1) + require.NoError(t, err) + _, err = ss.Post().Save(&model.Post{ChannelId: o1.ChannelId, UserId: model.NewId(), Message: "zz" + model.NewId() + "b", RootId: o1.Id}) + require.NoError(t, err) + + threadMembership := &model.ThreadMembership{ + PostId: o1.Id, + UserId: o1.UserId, + Following: true, + LastViewed: 0, + LastUpdated: 0, + UnreadMentions: 0, + } + _, err = ss.Thread().SaveMembership(threadMembership) + require.NoError(t, err) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, true, false, o1.UserId) + require.NoError(t, err) + require.Equal(t, r1.Posts[o1.Id].CreateAt, o1.CreateAt, "invalid returned post") + require.True(t, r1.Posts[o1.Id].IsFollowing) +} + func testPostStoreGetSingle(t *testing.T, ss store.Store) { o1 := &model.Post{} o1.ChannelId = model.NewId() @@ -469,15 +494,15 @@ func testPostStoreUpdate(t *testing.T, ss store.Store) { o3, err = ss.Post().Save(o3) require.NoError(t, err) - r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro1 := r1.Posts[o1.Id] - r2, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r2, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro2 := r2.Posts[o2.Id] - r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err) ro3 := r3.Posts[o3.Id] @@ -488,7 +513,7 @@ func testPostStoreUpdate(t *testing.T, ss store.Store) { _, err = ss.Post().Update(o1a, ro1) require.NoError(t, err) - r1, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro1a := r1.Posts[o1.Id] @@ -499,7 +524,7 @@ func testPostStoreUpdate(t *testing.T, ss store.Store) { _, err = ss.Post().Update(o2a, ro2) require.NoError(t, err) - r2, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + r2, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro2a := r2.Posts[o2.Id] @@ -510,7 +535,7 @@ func testPostStoreUpdate(t *testing.T, ss store.Store) { _, err = ss.Post().Update(o3a, ro3) require.NoError(t, err) - r3, err = ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, err = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err) ro3a := r3.Posts[o3.Id] @@ -526,7 +551,7 @@ func testPostStoreUpdate(t *testing.T, ss store.Store) { }) require.NoError(t, err) - r4, err := ss.Post().Get(context.Background(), o4.Id, false, false, false) + r4, err := ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, err) ro4 := r4.Posts[o4.Id] @@ -536,7 +561,7 @@ func testPostStoreUpdate(t *testing.T, ss store.Store) { _, err = ss.Post().Update(o4a, ro4) require.NoError(t, err) - r4, err = ss.Post().Get(context.Background(), o4.Id, false, false, false) + r4, err = ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, err) ro4a := r4.Posts[o4.Id] @@ -557,7 +582,7 @@ func testPostStoreDelete(t *testing.T, ss store.Store) { o1, err := ss.Post().Save(o1) require.NoError(t, err) - r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) require.Equal(t, r1.Posts[o1.Id].CreateAt, o1.CreateAt, "invalid returned post") @@ -570,7 +595,7 @@ func testPostStoreDelete(t *testing.T, ss store.Store) { assert.Equal(t, deleteByID, actual, "Expected (*Post).Props[model.POST_PROPS_DELETE_BY] to be %v but got %v.", deleteByID, actual) - r3, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r3, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.Error(t, err, "Missing id should have failed - PostList %v", r3) etag2 := ss.Post().GetEtag(o1.ChannelId, false, false) @@ -597,10 +622,10 @@ func testPostStoreDelete1Level(t *testing.T, ss store.Store) { err = ss.Post().Delete(o1.Id, model.GetMillis(), "") require.NoError(t, err) - _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") - _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") } @@ -640,16 +665,16 @@ func testPostStoreDelete2Level(t *testing.T, ss store.Store) { err = ss.Post().Delete(o1.Id, model.GetMillis(), "") require.NoError(t, err) - _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") - _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") - _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") - _, err = ss.Post().Get(context.Background(), o4.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, err) } @@ -680,16 +705,16 @@ func testPostStorePermDelete1Level(t *testing.T, ss store.Store) { err2 := ss.Post().PermanentDeleteByUser(o2.UserId) require.NoError(t, err2) - _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err, "Deleted id shouldn't have failed") - _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") err = ss.Post().PermanentDeleteByChannel(o3.ChannelId) require.NoError(t, err) - _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") } @@ -720,13 +745,13 @@ func testPostStorePermDelete1Level2(t *testing.T, ss store.Store) { err2 := ss.Post().PermanentDeleteByUser(o1.UserId) require.NoError(t, err2) - _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") - _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.Error(t, err, "Deleted id should have failed") - _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err, "Deleted id should have failed") } @@ -756,7 +781,7 @@ func testPostStoreGetWithChildren(t *testing.T, ss store.Store) { o3, err = ss.Post().Save(o3) require.NoError(t, err) - pl, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + pl, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) require.Len(t, pl.Posts, 3, "invalid returned post") @@ -764,7 +789,7 @@ func testPostStoreGetWithChildren(t *testing.T, ss store.Store) { dErr := ss.Post().Delete(o3.Id, model.GetMillis(), "") require.NoError(t, dErr) - pl, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + pl, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) require.Len(t, pl.Posts, 2, "invalid returned post") @@ -772,7 +797,7 @@ func testPostStoreGetWithChildren(t *testing.T, ss store.Store) { dErr = ss.Post().Delete(o2.Id, model.GetMillis(), "") require.NoError(t, dErr) - pl, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + pl, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) require.Len(t, pl.Posts, 1, "invalid returned post") @@ -2242,23 +2267,23 @@ func testPostStoreOverwriteMultiple(t *testing.T, ss store.Store) { }) require.NoError(t, err) - r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro1 := r1.Posts[o1.Id] - r2, err := ss.Post().Get(context.Background(), o2.Id, false, false, false) + r2, err := ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.NoError(t, err) ro2 := r2.Posts[o2.Id] - r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err) ro3 := r3.Posts[o3.Id] - r4, err := ss.Post().Get(context.Background(), o4.Id, false, false, false) + r4, err := ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, err) ro4 := r4.Posts[o4.Id] - r5, err := ss.Post().Get(context.Background(), o5.Id, false, false, false) + r5, err := ss.Post().Get(context.Background(), o5.Id, false, false, false, "") require.NoError(t, err) ro5 := r5.Posts[o5.Id] @@ -2284,15 +2309,15 @@ func testPostStoreOverwriteMultiple(t *testing.T, ss store.Store) { require.NoError(t, err) require.Equal(t, -1, errIdx) - r1, nErr := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, nErr := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, nErr) ro1a := r1.Posts[o1.Id] - r2, nErr = ss.Post().Get(context.Background(), o1.Id, false, false, false) + r2, nErr = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, nErr) ro2a := r2.Posts[o2.Id] - r3, nErr = ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, nErr = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, nErr) ro3a := r3.Posts[o3.Id] @@ -2314,11 +2339,11 @@ func testPostStoreOverwriteMultiple(t *testing.T, ss store.Store) { require.NoError(t, err) require.Equal(t, -1, errIdx) - r4, nErr := ss.Post().Get(context.Background(), o4.Id, false, false, false) + r4, nErr := ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, nErr) ro4a := r4.Posts[o4.Id] - r5, nErr = ss.Post().Get(context.Background(), o5.Id, false, false, false) + r5, nErr = ss.Post().Get(context.Background(), o5.Id, false, false, false, "") require.NoError(t, nErr) ro5a := r5.Posts[o5.Id] @@ -2361,19 +2386,19 @@ func testPostStoreOverwrite(t *testing.T, ss store.Store) { }) require.NoError(t, err) - r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro1 := r1.Posts[o1.Id] - r2, err := ss.Post().Get(context.Background(), o2.Id, false, false, false) + r2, err := ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.NoError(t, err) ro2 := r2.Posts[o2.Id] - r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err) ro3 := r3.Posts[o3.Id] - r4, err := ss.Post().Get(context.Background(), o4.Id, false, false, false) + r4, err := ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, err) ro4 := r4.Posts[o4.Id] @@ -2398,15 +2423,15 @@ func testPostStoreOverwrite(t *testing.T, ss store.Store) { _, err = ss.Post().Overwrite(o3a) require.NoError(t, err) - r1, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro1a := r1.Posts[o1.Id] - r2, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + r2, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro2a := r2.Posts[o2.Id] - r3, err = ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, err = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err) ro3a := r3.Posts[o3.Id] @@ -2422,7 +2447,7 @@ func testPostStoreOverwrite(t *testing.T, ss store.Store) { _, err = ss.Post().Overwrite(o4a) require.NoError(t, err) - r4, err = ss.Post().Get(context.Background(), o4.Id, false, false, false) + r4, err = ss.Post().Get(context.Background(), o4.Id, false, false, false, "") require.NoError(t, err) ro4a := r4.Posts[o4.Id] @@ -2453,15 +2478,15 @@ func testPostStoreGetPostsByIds(t *testing.T, ss store.Store) { o3, err = ss.Post().Save(o3) require.NoError(t, err) - r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false) + r1, err := ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.NoError(t, err) ro1 := r1.Posts[o1.Id] - r2, err := ss.Post().Get(context.Background(), o2.Id, false, false, false) + r2, err := ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.NoError(t, err) ro2 := r2.Posts[o2.Id] - r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false) + r3, err := ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err) ro3 := r3.Posts[o3.Id] @@ -2568,13 +2593,13 @@ func testPostStorePermanentDeleteBatch(t *testing.T, ss store.Store) { _, err = ss.Post().PermanentDeleteBatch(2000, 1000) require.NoError(t, err) - _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o1.Id, false, false, false, "") require.Error(t, err, "Should have not found post 1 after purge") - _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o2.Id, false, false, false, "") require.Error(t, err, "Should have not found post 2 after purge") - _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false) + _, err = ss.Post().Get(context.Background(), o3.Id, false, false, false, "") require.NoError(t, err, "Should have not found post 3 after purge") } diff --git a/store/storetest/reaction_store.go b/store/storetest/reaction_store.go index 9c12ea9d3b..1d1d46f9cf 100644 --- a/store/storetest/reaction_store.go +++ b/store/storetest/reaction_store.go @@ -53,7 +53,7 @@ func testReactionSave(t *testing.T, ss store.Store) { assert.Zero(t, saved.DeleteAt, "should've saved reaction delete_at with zero value and returned it") var secondUpdateAt int64 - postList, err := ss.Post().Get(context.Background(), reaction1.PostId, false, false, false) + postList, err := ss.Post().Get(context.Background(), reaction1.PostId, false, false, false, "") require.NoError(t, err) assert.True(t, postList.Posts[post.Id].HasReactions, "should've set HasReactions = true on post") @@ -77,7 +77,7 @@ func testReactionSave(t *testing.T, ss store.Store) { _, nErr = ss.Reaction().Save(reaction2) require.NoError(t, nErr) - postList, err = ss.Post().Get(context.Background(), reaction2.PostId, false, false, false) + postList, err = ss.Post().Get(context.Background(), reaction2.PostId, false, false, false, "") require.NoError(t, err) assert.NotEqual(t, postList.Posts[post.Id].UpdateAt, secondUpdateAt, "should've marked post as updated even if HasReactions doesn't change") @@ -127,7 +127,7 @@ func testReactionDelete(t *testing.T, ss store.Store) { _, nErr := ss.Reaction().Save(reaction) require.NoError(t, nErr) - result, err := ss.Post().Get(context.Background(), reaction.PostId, false, false, false) + result, err := ss.Post().Get(context.Background(), reaction.PostId, false, false, false, "") require.NoError(t, err) firstUpdateAt := result.Posts[post.Id].UpdateAt @@ -140,7 +140,7 @@ func testReactionDelete(t *testing.T, ss store.Store) { assert.Empty(t, reactions, "should've deleted reaction") - postList, err := ss.Post().Get(context.Background(), post.Id, false, false, false) + postList, err := ss.Post().Get(context.Background(), post.Id, false, false, false, "") require.NoError(t, err) assert.False(t, postList.Posts[post.Id].HasReactions, "should've set HasReactions = false on post") @@ -326,11 +326,11 @@ func testReactionDeleteAllWithEmojiName(t *testing.T, ss store.Store, s SqlStore // make at least one Reaction record contain NULL for Update and DeleteAt to simulate post schema upgrade case. sqlResult, err := s.GetMaster().Exec(` - UPDATE - Reactions - SET - UpdateAt=NULL, DeleteAt=NULL - WHERE + UPDATE + Reactions + SET + UpdateAt=NULL, DeleteAt=NULL + WHERE UserId = :UserId AND PostId = :PostId AND EmojiName = :EmojiName`, map[string]interface{}{ "UserId": userId, @@ -363,15 +363,15 @@ func testReactionDeleteAllWithEmojiName(t *testing.T, ss store.Store, s SqlStore assert.Empty(t, returned, "should've only removed reactions with emoji name") // check that the posts are updated - postList, err := ss.Post().Get(context.Background(), post.Id, false, false, false) + postList, err := ss.Post().Get(context.Background(), post.Id, false, false, false, "") require.NoError(t, err) assert.True(t, postList.Posts[post.Id].HasReactions, "post should still have reactions") - postList, err = ss.Post().Get(context.Background(), post2.Id, false, false, false) + postList, err = ss.Post().Get(context.Background(), post2.Id, false, false, false, "") require.NoError(t, err) assert.True(t, postList.Posts[post2.Id].HasReactions, "post should still have reactions") - postList, err = ss.Post().Get(context.Background(), post3.Id, false, false, false) + postList, err = ss.Post().Get(context.Background(), post3.Id, false, false, false, "") require.NoError(t, err) assert.False(t, postList.Posts[post3.Id].HasReactions, "post shouldn't have reactions any more") diff --git a/store/storetest/thread_store.go b/store/storetest/thread_store.go index 91ec4154de..a0317bcc4c 100644 --- a/store/storetest/thread_store.go +++ b/store/storetest/thread_store.go @@ -70,7 +70,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) { newPosts, errIdx, err3 := ss.Post().SaveMultiple([]*model.Post{&o2, &o3, &o4}) - olist, _ := ss.Post().Get(context.Background(), otmp.Id, true, false, false) + olist, _ := ss.Post().Get(context.Background(), otmp.Id, true, false, false, "") o1 := olist.Posts[olist.Order[0]] newPosts = append([]*model.Post{o1}, newPosts...) diff --git a/store/timerlayer/timerlayer.go b/store/timerlayer/timerlayer.go index aecfc7d80f..091848348e 100644 --- a/store/timerlayer/timerlayer.go +++ b/store/timerlayer/timerlayer.go @@ -4476,10 +4476,10 @@ func (s *TimerLayerPostStore) Delete(postID string, time int64, deleteByID strin return err } -func (s *TimerLayerPostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool) (*model.PostList, error) { +func (s *TimerLayerPostStore) Get(ctx context.Context, id string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool, userID string) (*model.PostList, error) { start := timemodule.Now() - result, err := s.PostStore.Get(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended) + result, err := s.PostStore.Get(ctx, id, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID) elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) if s.Root.Metrics != nil {