mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-8404] Channel notification setting for disabling channel mentions (#9777)
* Channel notification setting for disabling channel mentions * Updates unit tests (#MM-8404) * Adds constants (#MM-8404) * Refactors if statement and adds unit test (#MM-8404) * Moves ignore_channel_mentions_notify_prop constant to channel model (#MM8484)
This commit is contained in:
committed by
Harrison Healey
parent
fa0aecce1e
commit
4aca95fff9
@@ -663,6 +663,10 @@ func (a *App) UpdateChannelMemberNotifyProps(data map[string]string, channelId s
|
||||
member.NotifyProps[model.PUSH_NOTIFY_PROP] = push
|
||||
}
|
||||
|
||||
if ignoreChannelMentions, exists := data[model.IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP]; exists {
|
||||
member.NotifyProps[model.IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP] = ignoreChannelMentions
|
||||
}
|
||||
|
||||
result := <-a.Srv.Store.Channel().UpdateMember(member)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
|
||||
@@ -84,7 +84,7 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
}
|
||||
|
||||
} else {
|
||||
keywords := a.GetMentionKeywordsInChannel(profileMap, post.Type != model.POST_HEADER_CHANGE && post.Type != model.POST_PURPOSE_CHANGE)
|
||||
keywords := a.GetMentionKeywordsInChannel(profileMap, post.Type != model.POST_HEADER_CHANGE && post.Type != model.POST_PURPOSE_CHANGE, channelMemberNotifyPropsMap)
|
||||
|
||||
m := GetExplicitMentions(post, keywords)
|
||||
|
||||
@@ -555,7 +555,7 @@ func GetMentionsEnabledFields(post *model.Post) model.StringArray {
|
||||
|
||||
// Given a map of user IDs to profiles, returns a list of mention
|
||||
// keywords for all users in the channel.
|
||||
func (a *App) GetMentionKeywordsInChannel(profiles map[string]*model.User, lookForSpecialMentions bool) map[string][]string {
|
||||
func (a *App) GetMentionKeywordsInChannel(profiles map[string]*model.User, lookForSpecialMentions bool, channelMemberNotifyPropsMap map[string]model.StringMap) map[string][]string {
|
||||
keywords := make(map[string][]string)
|
||||
|
||||
for id, profile := range profiles {
|
||||
@@ -577,9 +577,16 @@ func (a *App) GetMentionKeywordsInChannel(profiles map[string]*model.User, lookF
|
||||
keywords[profile.FirstName] = append(keywords[profile.FirstName], profile.Id)
|
||||
}
|
||||
|
||||
ignoreChannelMentions := false
|
||||
if ignoreChannelMentionsNotifyProp, ok := channelMemberNotifyPropsMap[profile.Id][model.IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP]; ok {
|
||||
if ignoreChannelMentionsNotifyProp == model.IGNORE_CHANNEL_MENTIONS_ON {
|
||||
ignoreChannelMentions = true
|
||||
}
|
||||
}
|
||||
|
||||
// Add @channel and @all to keywords if user has them turned on
|
||||
if lookForSpecialMentions {
|
||||
if int64(len(profiles)) <= *a.Config().TeamSettings.MaxNotificationsPerChannel && profile.NotifyProps["channel"] == "true" {
|
||||
if int64(len(profiles)) <= *a.Config().TeamSettings.MaxNotificationsPerChannel && profile.NotifyProps["channel"] == "true" && !ignoreChannelMentions {
|
||||
keywords["@channel"] = append(keywords["@channel"], profile.Id)
|
||||
keywords["@all"] = append(keywords["@all"], profile.Id)
|
||||
|
||||
|
||||
@@ -625,8 +625,14 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
channelMemberNotifyPropsMap1Off := map[string]model.StringMap{
|
||||
user1.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
}
|
||||
|
||||
profiles := map[string]*model.User{user1.Id: user1}
|
||||
mentions := th.App.GetMentionKeywordsInChannel(profiles, true)
|
||||
mentions := th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap1Off)
|
||||
if len(mentions) != 3 {
|
||||
t.Fatal("should've returned three mention keywords")
|
||||
} else if ids, ok := mentions["user"]; !ok || ids[0] != user1.Id {
|
||||
@@ -647,8 +653,14 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
channelMemberNotifyPropsMap2Off := map[string]model.StringMap{
|
||||
user2.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
}
|
||||
|
||||
profiles = map[string]*model.User{user2.Id: user2}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap2Off)
|
||||
if len(mentions) != 2 {
|
||||
t.Fatal("should've returned two mention keyword")
|
||||
} else if ids, ok := mentions["First"]; !ok || ids[0] != user2.Id {
|
||||
@@ -665,8 +677,14 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
// Channel-wide mentions are not ignored on channel level
|
||||
channelMemberNotifyPropsMap3Off := map[string]model.StringMap{
|
||||
user3.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
}
|
||||
profiles = map[string]*model.User{user3.Id: user3}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap3Off)
|
||||
if len(mentions) != 3 {
|
||||
t.Fatal("should've returned three mention keywords")
|
||||
} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user3.Id {
|
||||
@@ -675,6 +693,45 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
t.Fatal("should've returned mention key of @all")
|
||||
}
|
||||
|
||||
// Channel member notify props is set to default
|
||||
channelMemberNotifyPropsMapDefault := map[string]model.StringMap{
|
||||
user3.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_DEFAULT,
|
||||
},
|
||||
}
|
||||
profiles = map[string]*model.User{user3.Id: user3}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMapDefault)
|
||||
if len(mentions) != 3 {
|
||||
t.Fatal("should've returned three mention keywords")
|
||||
} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user3.Id {
|
||||
t.Fatal("should've returned mention key of @channel")
|
||||
} else if ids, ok := mentions["@all"]; !ok || ids[0] != user3.Id {
|
||||
t.Fatal("should've returned mention key of @all")
|
||||
}
|
||||
|
||||
// Channel member notify props is empty
|
||||
channelMemberNotifyPropsMapEmpty := map[string]model.StringMap{}
|
||||
profiles = map[string]*model.User{user3.Id: user3}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMapEmpty)
|
||||
if len(mentions) != 3 {
|
||||
t.Fatal("should've returned three mention keywords")
|
||||
} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user3.Id {
|
||||
t.Fatal("should've returned mention key of @channel")
|
||||
} else if ids, ok := mentions["@all"]; !ok || ids[0] != user3.Id {
|
||||
t.Fatal("should've returned mention key of @all")
|
||||
}
|
||||
|
||||
// Channel-wide mentions are ignored channel level
|
||||
channelMemberNotifyPropsMap3On := map[string]model.StringMap{
|
||||
user3.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_ON,
|
||||
},
|
||||
}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap3On)
|
||||
if len(mentions) == 0 {
|
||||
t.Fatal("should've not returned any keywords")
|
||||
}
|
||||
|
||||
// user with all types of mentions enabled
|
||||
user4 := &model.User{
|
||||
Id: model.NewId(),
|
||||
@@ -687,8 +744,15 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
// Channel-wide mentions are not ignored on channel level
|
||||
channelMemberNotifyPropsMap4Off := map[string]model.StringMap{
|
||||
user4.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
}
|
||||
|
||||
profiles = map[string]*model.User{user4.Id: user4}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap4Off)
|
||||
if len(mentions) != 6 {
|
||||
t.Fatal("should've returned six mention keywords")
|
||||
} else if ids, ok := mentions["user"]; !ok || ids[0] != user4.Id {
|
||||
@@ -705,6 +769,25 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
t.Fatal("should've returned mention key of @all")
|
||||
}
|
||||
|
||||
// Channel-wide mentions are ignored on channel level
|
||||
channelMemberNotifyPropsMap4On := map[string]model.StringMap{
|
||||
user4.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_ON,
|
||||
},
|
||||
}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap4On)
|
||||
if len(mentions) != 4 {
|
||||
t.Fatal("should've returned four mention keywords")
|
||||
} else if ids, ok := mentions["user"]; !ok || ids[0] != user4.Id {
|
||||
t.Fatal("should've returned mention key of user")
|
||||
} else if ids, ok := mentions["@user"]; !ok || ids[0] != user4.Id {
|
||||
t.Fatal("should've returned mention key of @user")
|
||||
} else if ids, ok := mentions["mention"]; !ok || ids[0] != user4.Id {
|
||||
t.Fatal("should've returned mention key of mention")
|
||||
} else if ids, ok := mentions["First"]; !ok || ids[0] != user4.Id {
|
||||
t.Fatal("should've returned mention key of First")
|
||||
}
|
||||
|
||||
dup_count := func(list []string) map[string]int {
|
||||
|
||||
duplicate_frequency := make(map[string]int)
|
||||
@@ -731,7 +814,22 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
user3.Id: user3,
|
||||
user4.Id: user4,
|
||||
}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
|
||||
// Channel-wide mentions are not ignored on channel level for all users
|
||||
channelMemberNotifyPropsMap5Off := map[string]model.StringMap{
|
||||
user1.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
user2.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
user3.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
user4.Id: {
|
||||
"ignore_channel_mentions": model.IGNORE_CHANNEL_MENTIONS_OFF,
|
||||
},
|
||||
}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap5Off)
|
||||
if len(mentions) != 6 {
|
||||
t.Fatal("should've returned six mention keywords")
|
||||
} else if ids, ok := mentions["user"]; !ok || len(ids) != 2 || (ids[0] != user1.Id && ids[1] != user1.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
|
||||
@@ -750,7 +848,7 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
|
||||
// multiple users and more than MaxNotificationsPerChannel
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxNotificationsPerChannel = 3 })
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, true, channelMemberNotifyPropsMap4Off)
|
||||
if len(mentions) != 4 {
|
||||
t.Fatal("should've returned four mention keywords")
|
||||
} else if _, ok := mentions["@channel"]; ok {
|
||||
@@ -765,7 +863,7 @@ func TestGetMentionKeywords(t *testing.T) {
|
||||
profiles = map[string]*model.User{
|
||||
user1.Id: user1,
|
||||
}
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, false)
|
||||
mentions = th.App.GetMentionKeywordsInChannel(profiles, false, channelMemberNotifyPropsMap4Off)
|
||||
if len(mentions) != 3 {
|
||||
t.Fatal("should've returned three mention keywords")
|
||||
} else if ids, ok := mentions["user"]; !ok || len(ids) != 1 || ids[0] != user1.Id {
|
||||
|
||||
@@ -3750,6 +3750,10 @@
|
||||
"id": "model.channel_member.is_valid.email_value.app_error",
|
||||
"translation": "Invalid email notification value"
|
||||
},
|
||||
{
|
||||
"id": "model.channel_member.is_valid.ignore_channel_mentions_value.app_error",
|
||||
"translation": "Invalid ignore channel mentions status"
|
||||
},
|
||||
{
|
||||
"id": "model.channel_member.is_valid.notify_level.app_error",
|
||||
"translation": "Invalid notify level"
|
||||
|
||||
@@ -11,12 +11,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
CHANNEL_NOTIFY_DEFAULT = "default"
|
||||
CHANNEL_NOTIFY_ALL = "all"
|
||||
CHANNEL_NOTIFY_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_NONE = "none"
|
||||
CHANNEL_MARK_UNREAD_ALL = "all"
|
||||
CHANNEL_MARK_UNREAD_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_DEFAULT = "default"
|
||||
CHANNEL_NOTIFY_ALL = "all"
|
||||
CHANNEL_NOTIFY_MENTION = "mention"
|
||||
CHANNEL_NOTIFY_NONE = "none"
|
||||
CHANNEL_MARK_UNREAD_ALL = "all"
|
||||
CHANNEL_MARK_UNREAD_MENTION = "mention"
|
||||
IGNORE_CHANNEL_MENTIONS_DEFAULT = "default"
|
||||
IGNORE_CHANNEL_MENTIONS_OFF = "off"
|
||||
IGNORE_CHANNEL_MENTIONS_ON = "on"
|
||||
IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP = "ignore_channel_mentions"
|
||||
)
|
||||
|
||||
type ChannelUnread struct {
|
||||
@@ -116,6 +120,12 @@ func (o *ChannelMember) IsValid() *AppError {
|
||||
}
|
||||
}
|
||||
|
||||
if ignoreChannelMentions, ok := o.NotifyProps[IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP]; ok {
|
||||
if len(ignoreChannelMentions) > 40 || !IsIgnoreChannelMentionsValid(ignoreChannelMentions) {
|
||||
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.ignore_channel_mentions_value.app_error", nil, "ignore_channel_mentions="+ignoreChannelMentions, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -146,11 +156,16 @@ func IsSendEmailValid(sendEmail string) bool {
|
||||
return sendEmail == CHANNEL_NOTIFY_DEFAULT || sendEmail == "true" || sendEmail == "false"
|
||||
}
|
||||
|
||||
func IsIgnoreChannelMentionsValid(ignoreChannelMentions string) bool {
|
||||
return ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_ON || ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_OFF || ignoreChannelMentions == IGNORE_CHANNEL_MENTIONS_DEFAULT
|
||||
}
|
||||
|
||||
func GetDefaultChannelNotifyProps() StringMap {
|
||||
return StringMap{
|
||||
DESKTOP_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
MARK_UNREAD_NOTIFY_PROP: CHANNEL_MARK_UNREAD_ALL,
|
||||
PUSH_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
EMAIL_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
DESKTOP_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
MARK_UNREAD_NOTIFY_PROP: CHANNEL_MARK_UNREAD_ALL,
|
||||
PUSH_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
EMAIL_NOTIFY_PROP: CHANNEL_NOTIFY_DEFAULT,
|
||||
IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP: IGNORE_CHANNEL_MENTIONS_DEFAULT,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user