diff --git a/app/notification.go b/app/notification.go index 29f10fa1c0..5dcdbe0c78 100644 --- a/app/notification.go +++ b/app/notification.go @@ -191,7 +191,7 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod mac := make(chan *model.AppError, 1) go func(userID string) { defer close(mac) - _, incrementMentions := mentions.Mentions[userID] + mentionType, incrementMentions := mentions.Mentions[userID] // if the user was not explicitly mentioned, check if they explicitly unfollowed the thread if !incrementMentions { membership, err := a.Srv().Store.Thread().GetMembershipForUser(userID, post.RootId) @@ -206,6 +206,9 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod return } } + if mentionType == ThreadMention || mentionType == CommentMention { + incrementMentions = false + } opts := store.ThreadMembershipOpts{ Following: true, diff --git a/app/notification_test.go b/app/notification_test.go index 981f3bca2b..2262eab4ed 100644 --- a/app/notification_test.go +++ b/app/notification_test.go @@ -5,6 +5,7 @@ package app import ( "fmt" + "os" "testing" "github.com/stretchr/testify/assert" @@ -2609,3 +2610,75 @@ func TestGetGroupsAllowedForReferenceInChannel(t *testing.T) { require.Equal(t, groupsMap[*group3.Name], group3) }) } + +func TestReplyPostNotificationsWithCRT(t *testing.T) { + t.Run("Reply posts only shows badges for explicit mentions in collapsed threads", func(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + u1 := th.BasicUser + u2 := th.BasicUser2 + c1 := th.BasicChannel + th.AddUserToChannel(u2, c1) + + // Enable "Trigger notifications on messages in + // reply threads that I start or participate in" + // for the second user + oldValue := th.BasicUser2.NotifyProps[model.COMMENTS_NOTIFY_PROP] + newNotifyProps := th.BasicUser2.NotifyProps + newNotifyProps[model.COMMENTS_NOTIFY_PROP] = model.COMMENTS_NOTIFY_ANY + u2, appErr := th.App.PatchUser(th.BasicUser2.Id, &model.UserPatch{NotifyProps: newNotifyProps}, false) + require.Nil(t, appErr) + require.Equal(t, model.COMMENTS_NOTIFY_ANY, u2.NotifyProps[model.COMMENTS_NOTIFY_PROP]) + defer func() { + newNotifyProps := th.BasicUser2.NotifyProps + newNotifyProps[model.COMMENTS_NOTIFY_PROP] = oldValue + _, nAppErr := th.App.PatchUser(th.BasicUser2.Id, &model.UserPatch{NotifyProps: newNotifyProps}, false) + require.Nil(t, nAppErr) + }() + + // Enable CRT + os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") + defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.ThreadAutoFollow = true + *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON + }) + + rootPost := &model.Post{ + ChannelId: c1.Id, + Message: "root post by user1", + UserId: u1.Id, + } + rpost, appErr := th.App.CreatePost(th.Context, rootPost, c1, false, true) + require.Nil(t, appErr) + + replyPost1 := &model.Post{ + ChannelId: c1.Id, + Message: "reply post by user2", + UserId: u2.Id, + RootId: rpost.Id, + } + _, appErr = th.App.CreatePost(th.Context, replyPost1, c1, false, true) + require.Nil(t, appErr) + + replyPost2 := &model.Post{ + ChannelId: c1.Id, + Message: "reply post by user1", + UserId: u1.Id, + RootId: rpost.Id, + } + _, appErr = th.App.CreatePost(th.Context, replyPost2, c1, false, true) + require.Nil(t, appErr) + + threadMembership, appErr := th.App.GetThreadMembershipForUser(u2.Id, rpost.Id) + require.Nil(t, appErr) + thread, appErr := th.App.GetThreadForUser(c1.TeamId, threadMembership, false) + require.Nil(t, appErr) + // Then: with notifications set to "all" we should + // not see a mention badge + require.Equal(t, int64(0), thread.UnreadMentions) + // Then: last post is still marked as unread + require.Equal(t, int64(1), thread.UnreadReplies) + }) +}