github.com/dschalla/mattermost-server@v4.8.1-rc1+incompatible/app/notification_test.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/mattermost/mattermost-server/model"
    13  	"github.com/mattermost/mattermost-server/utils"
    14  )
    15  
    16  func TestSendNotifications(t *testing.T) {
    17  	th := Setup().InitBasic()
    18  	defer th.TearDown()
    19  
    20  	th.App.AddUserToChannel(th.BasicUser2, th.BasicChannel)
    21  
    22  	post1, err := th.App.CreatePostMissingChannel(&model.Post{
    23  		UserId:    th.BasicUser.Id,
    24  		ChannelId: th.BasicChannel.Id,
    25  		Message:   "@" + th.BasicUser2.Username,
    26  	}, true)
    27  
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  
    32  	mentions, err := th.App.SendNotifications(post1, th.BasicTeam, th.BasicChannel, th.BasicUser, nil)
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	} else if mentions == nil {
    36  		t.Log(mentions)
    37  		t.Fatal("user should have been mentioned")
    38  	} else if mentions[0] != th.BasicUser2.Id {
    39  		t.Log(mentions)
    40  		t.Fatal("user should have been mentioned")
    41  	}
    42  
    43  	dm, err := th.App.CreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id)
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  
    48  	post2, err := th.App.CreatePostMissingChannel(&model.Post{
    49  		UserId:    th.BasicUser.Id,
    50  		ChannelId: dm.Id,
    51  		Message:   "dm message",
    52  	}, true)
    53  
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  
    58  	_, err = th.App.SendNotifications(post2, th.BasicTeam, dm, th.BasicUser, nil)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	th.App.UpdateActive(th.BasicUser2, false)
    64  	th.App.InvalidateAllCaches()
    65  
    66  	post3, err := th.App.CreatePostMissingChannel(&model.Post{
    67  		UserId:    th.BasicUser.Id,
    68  		ChannelId: dm.Id,
    69  		Message:   "dm message",
    70  	}, true)
    71  
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  
    76  	_, err = th.App.SendNotifications(post3, th.BasicTeam, dm, th.BasicUser, nil)
    77  	if err != nil {
    78  		t.Fatal(err)
    79  	}
    80  }
    81  
    82  func TestGetExplicitMentions(t *testing.T) {
    83  	id1 := model.NewId()
    84  	id2 := model.NewId()
    85  	id3 := model.NewId()
    86  
    87  	for name, tc := range map[string]struct {
    88  		Message  string
    89  		Keywords map[string][]string
    90  		Expected *ExplicitMentions
    91  	}{
    92  		"Nobody": {
    93  			Message:  "this is a message",
    94  			Keywords: map[string][]string{},
    95  			Expected: &ExplicitMentions{},
    96  		},
    97  		"NonexistentUser": {
    98  			Message: "this is a message for @user",
    99  			Expected: &ExplicitMentions{
   100  				OtherPotentialMentions: []string{"user"},
   101  			},
   102  		},
   103  		"OnePerson": {
   104  			Message:  "this is a message for @user",
   105  			Keywords: map[string][]string{"@user": {id1}},
   106  			Expected: &ExplicitMentions{
   107  				MentionedUserIds: map[string]bool{
   108  					id1: true,
   109  				},
   110  			},
   111  		},
   112  		"OnePersonWithPeriodAtEndOfUsername": {
   113  			Message:  "this is a message for @user.name.",
   114  			Keywords: map[string][]string{"@user.name.": {id1}},
   115  			Expected: &ExplicitMentions{
   116  				MentionedUserIds: map[string]bool{
   117  					id1: true,
   118  				},
   119  			},
   120  		},
   121  		"OnePersonWithPeriodAtEndOfUsernameButNotSimilarName": {
   122  			Message:  "this is a message for @user.name.",
   123  			Keywords: map[string][]string{"@user.name.": {id1}, "@user.name": {id2}},
   124  			Expected: &ExplicitMentions{
   125  				MentionedUserIds: map[string]bool{
   126  					id1: true,
   127  				},
   128  			},
   129  		},
   130  		"OnePersonAtEndOfSentence": {
   131  			Message:  "this is a message for @user.",
   132  			Keywords: map[string][]string{"@user": {id1}},
   133  			Expected: &ExplicitMentions{
   134  				MentionedUserIds: map[string]bool{
   135  					id1: true,
   136  				},
   137  			},
   138  		},
   139  		"OnePersonWithoutAtMention": {
   140  			Message:  "this is a message for @user",
   141  			Keywords: map[string][]string{"this": {id1}},
   142  			Expected: &ExplicitMentions{
   143  				MentionedUserIds: map[string]bool{
   144  					id1: true,
   145  				},
   146  				OtherPotentialMentions: []string{"user"},
   147  			},
   148  		},
   149  		"MultiplePeopleWithOneWord": {
   150  			Message:  "this is a message for @user",
   151  			Keywords: map[string][]string{"@user": {id1, id2}},
   152  			Expected: &ExplicitMentions{
   153  				MentionedUserIds: map[string]bool{
   154  					id1: true,
   155  					id2: true,
   156  				},
   157  			},
   158  		},
   159  		"OneOfMultiplePeople": {
   160  			Message:  "this is a message for @user",
   161  			Keywords: map[string][]string{"@user": {id1}, "@mention": {id2}},
   162  			Expected: &ExplicitMentions{
   163  				MentionedUserIds: map[string]bool{
   164  					id1: true,
   165  				},
   166  			},
   167  		},
   168  		"MultiplePeopleWithMultipleWords": {
   169  			Message:  "this is an @mention for @user",
   170  			Keywords: map[string][]string{"@user": {id1}, "@mention": {id2}},
   171  			Expected: &ExplicitMentions{
   172  				MentionedUserIds: map[string]bool{
   173  					id1: true,
   174  					id2: true,
   175  				},
   176  			},
   177  		},
   178  		"Channel": {
   179  			Message:  "this is an message for @channel",
   180  			Keywords: map[string][]string{"@channel": {id1, id2}},
   181  			Expected: &ExplicitMentions{
   182  				MentionedUserIds: map[string]bool{
   183  					id1: true,
   184  					id2: true,
   185  				},
   186  				ChannelMentioned: true,
   187  			},
   188  		},
   189  		"All": {
   190  			Message:  "this is an message for @all",
   191  			Keywords: map[string][]string{"@all": {id1, id2}},
   192  			Expected: &ExplicitMentions{
   193  				MentionedUserIds: map[string]bool{
   194  					id1: true,
   195  					id2: true,
   196  				},
   197  				AllMentioned: true,
   198  			},
   199  		},
   200  		"UserWithPeriod": {
   201  			Message:  "user.period doesn't complicate things at all by including periods in their username",
   202  			Keywords: map[string][]string{"user.period": {id1}, "user": {id2}},
   203  			Expected: &ExplicitMentions{
   204  				MentionedUserIds: map[string]bool{
   205  					id1: true,
   206  				},
   207  			},
   208  		},
   209  		"AtUserWithPeriodAtEndOfSentence": {
   210  			Message:  "this is a message for @user.period.",
   211  			Keywords: map[string][]string{"@user.period": {id1}},
   212  			Expected: &ExplicitMentions{
   213  				MentionedUserIds: map[string]bool{
   214  					id1: true,
   215  				},
   216  			},
   217  		},
   218  		"UserWithPeriodAtEndOfSentence": {
   219  			Message:  "this is a message for user.period.",
   220  			Keywords: map[string][]string{"user.period": {id1}},
   221  			Expected: &ExplicitMentions{
   222  				MentionedUserIds: map[string]bool{
   223  					id1: true,
   224  				},
   225  			},
   226  		},
   227  		"PotentialOutOfChannelUser": {
   228  			Message:  "this is an message for @potential and @user",
   229  			Keywords: map[string][]string{"@user": {id1}},
   230  			Expected: &ExplicitMentions{
   231  				MentionedUserIds: map[string]bool{
   232  					id1: true,
   233  				},
   234  				OtherPotentialMentions: []string{"potential"},
   235  			},
   236  		},
   237  		"InlineCode": {
   238  			Message:  "`this shouldn't mention @channel at all`",
   239  			Keywords: map[string][]string{},
   240  			Expected: &ExplicitMentions{},
   241  		},
   242  		"FencedCodeBlock": {
   243  			Message:  "```\nthis shouldn't mention @channel at all\n```",
   244  			Keywords: map[string][]string{},
   245  			Expected: &ExplicitMentions{},
   246  		},
   247  		"Emphasis": {
   248  			Message:  "*@aaa @bbb @ccc*",
   249  			Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}},
   250  			Expected: &ExplicitMentions{
   251  				MentionedUserIds: map[string]bool{
   252  					id1: true,
   253  					id2: true,
   254  					id3: true,
   255  				},
   256  			},
   257  		},
   258  		"StrongEmphasis": {
   259  			Message:  "**@aaa @bbb @ccc**",
   260  			Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}},
   261  			Expected: &ExplicitMentions{
   262  				MentionedUserIds: map[string]bool{
   263  					id1: true,
   264  					id2: true,
   265  					id3: true,
   266  				},
   267  			},
   268  		},
   269  		"Strikethrough": {
   270  			Message:  "~~@aaa @bbb @ccc~~",
   271  			Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}},
   272  			Expected: &ExplicitMentions{
   273  				MentionedUserIds: map[string]bool{
   274  					id1: true,
   275  					id2: true,
   276  					id3: true,
   277  				},
   278  			},
   279  		},
   280  		"Heading": {
   281  			Message:  "### @aaa",
   282  			Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}},
   283  			Expected: &ExplicitMentions{
   284  				MentionedUserIds: map[string]bool{
   285  					id1: true,
   286  				},
   287  			},
   288  		},
   289  		"BlockQuote": {
   290  			Message:  "> @aaa",
   291  			Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}},
   292  			Expected: &ExplicitMentions{
   293  				MentionedUserIds: map[string]bool{
   294  					id1: true,
   295  				},
   296  			},
   297  		},
   298  		"Emoji": {
   299  			Message:  ":smile:",
   300  			Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}},
   301  			Expected: &ExplicitMentions{},
   302  		},
   303  		"NotEmoji": {
   304  			Message:  "smile",
   305  			Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}},
   306  			Expected: &ExplicitMentions{
   307  				MentionedUserIds: map[string]bool{
   308  					id1: true,
   309  				},
   310  			},
   311  		},
   312  		"UnclosedEmoji": {
   313  			Message:  ":smile",
   314  			Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}},
   315  			Expected: &ExplicitMentions{
   316  				MentionedUserIds: map[string]bool{
   317  					id1: true,
   318  				},
   319  			},
   320  		},
   321  		"UnopenedEmoji": {
   322  			Message:  "smile:",
   323  			Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}},
   324  			Expected: &ExplicitMentions{
   325  				MentionedUserIds: map[string]bool{
   326  					id1: true,
   327  				},
   328  			},
   329  		},
   330  		"IndentedCodeBlock": {
   331  			Message:  "    this shouldn't mention @channel at all",
   332  			Keywords: map[string][]string{},
   333  			Expected: &ExplicitMentions{},
   334  		},
   335  		"LinkTitle": {
   336  			Message:  `[foo](this "shouldn't mention @channel at all")`,
   337  			Keywords: map[string][]string{},
   338  			Expected: &ExplicitMentions{},
   339  		},
   340  		"MalformedInlineCode": {
   341  			Message:  "`this should mention @channel``",
   342  			Keywords: map[string][]string{},
   343  			Expected: &ExplicitMentions{
   344  				ChannelMentioned: true,
   345  			},
   346  		},
   347  	} {
   348  		t.Run(name, func(t *testing.T) {
   349  			m := GetExplicitMentions(tc.Message, tc.Keywords)
   350  			if tc.Expected.MentionedUserIds == nil {
   351  				tc.Expected.MentionedUserIds = make(map[string]bool)
   352  			}
   353  			assert.EqualValues(t, tc.Expected, m)
   354  		})
   355  	}
   356  }
   357  
   358  func TestGetExplicitMentionsAtHere(t *testing.T) {
   359  	// test all the boundary cases that we know can break up terms (and those that we know won't)
   360  	cases := map[string]bool{
   361  		"":          false,
   362  		"here":      false,
   363  		"@here":     true,
   364  		" @here ":   true,
   365  		"\n@here\n": true,
   366  		"!@here!":   true,
   367  		"#@here#":   true,
   368  		"$@here$":   true,
   369  		"%@here%":   true,
   370  		"^@here^":   true,
   371  		"&@here&":   true,
   372  		"*@here*":   true,
   373  		"(@here(":   true,
   374  		")@here)":   true,
   375  		"-@here-":   true,
   376  		"_@here_":   false, // This case shouldn't mention since it would be mentioning "@here_"
   377  		"=@here=":   true,
   378  		"+@here+":   true,
   379  		"[@here[":   true,
   380  		"{@here{":   true,
   381  		"]@here]":   true,
   382  		"}@here}":   true,
   383  		"\\@here\\": true,
   384  		"|@here|":   true,
   385  		";@here;":   true,
   386  		":@here:":   false, // This case shouldn't trigger a mention since it follows the format of reactions e.g. :word:
   387  		"'@here'":   true,
   388  		"\"@here\"": true,
   389  		",@here,":   true,
   390  		"<@here<":   true,
   391  		".@here.":   true,
   392  		">@here>":   true,
   393  		"/@here/":   true,
   394  		"?@here?":   true,
   395  		"`@here`":   false, // This case shouldn't mention since it's a code block
   396  		"~@here~":   true,
   397  	}
   398  
   399  	for message, shouldMention := range cases {
   400  		if m := GetExplicitMentions(message, nil); m.HereMentioned && !shouldMention {
   401  			t.Fatalf("shouldn't have mentioned @here with \"%v\"", message)
   402  		} else if !m.HereMentioned && shouldMention {
   403  			t.Fatalf("should've mentioned @here with \"%v\"", message)
   404  		}
   405  	}
   406  
   407  	// mentioning @here and someone
   408  	id := model.NewId()
   409  	if m := GetExplicitMentions("@here @user @potential", map[string][]string{"@user": {id}}); !m.HereMentioned {
   410  		t.Fatal("should've mentioned @here with \"@here @user\"")
   411  	} else if len(m.MentionedUserIds) != 1 || !m.MentionedUserIds[id] {
   412  		t.Fatal("should've mentioned @user with \"@here @user\"")
   413  	} else if len(m.OtherPotentialMentions) > 1 {
   414  		t.Fatal("should've potential mentions for @potential")
   415  	}
   416  }
   417  
   418  func TestGetMentionKeywords(t *testing.T) {
   419  	th := Setup()
   420  	defer th.TearDown()
   421  
   422  	// user with username or custom mentions enabled
   423  	user1 := &model.User{
   424  		Id:        model.NewId(),
   425  		FirstName: "First",
   426  		Username:  "User",
   427  		NotifyProps: map[string]string{
   428  			"mention_keys": "User,@User,MENTION",
   429  		},
   430  	}
   431  
   432  	profiles := map[string]*model.User{user1.Id: user1}
   433  	mentions := th.App.GetMentionKeywordsInChannel(profiles, true)
   434  	if len(mentions) != 3 {
   435  		t.Fatal("should've returned three mention keywords")
   436  	} else if ids, ok := mentions["user"]; !ok || ids[0] != user1.Id {
   437  		t.Fatal("should've returned mention key of user")
   438  	} else if ids, ok := mentions["@user"]; !ok || ids[0] != user1.Id {
   439  		t.Fatal("should've returned mention key of @user")
   440  	} else if ids, ok := mentions["mention"]; !ok || ids[0] != user1.Id {
   441  		t.Fatal("should've returned mention key of mention")
   442  	}
   443  
   444  	// user with first name mention enabled
   445  	user2 := &model.User{
   446  		Id:        model.NewId(),
   447  		FirstName: "First",
   448  		Username:  "User",
   449  		NotifyProps: map[string]string{
   450  			"first_name": "true",
   451  		},
   452  	}
   453  
   454  	profiles = map[string]*model.User{user2.Id: user2}
   455  	mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
   456  	if len(mentions) != 2 {
   457  		t.Fatal("should've returned two mention keyword")
   458  	} else if ids, ok := mentions["First"]; !ok || ids[0] != user2.Id {
   459  		t.Fatal("should've returned mention key of First")
   460  	}
   461  
   462  	// user with @channel/@all mentions enabled
   463  	user3 := &model.User{
   464  		Id:        model.NewId(),
   465  		FirstName: "First",
   466  		Username:  "User",
   467  		NotifyProps: map[string]string{
   468  			"channel": "true",
   469  		},
   470  	}
   471  
   472  	profiles = map[string]*model.User{user3.Id: user3}
   473  	mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
   474  	if len(mentions) != 3 {
   475  		t.Fatal("should've returned three mention keywords")
   476  	} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user3.Id {
   477  		t.Fatal("should've returned mention key of @channel")
   478  	} else if ids, ok := mentions["@all"]; !ok || ids[0] != user3.Id {
   479  		t.Fatal("should've returned mention key of @all")
   480  	}
   481  
   482  	// user with all types of mentions enabled
   483  	user4 := &model.User{
   484  		Id:        model.NewId(),
   485  		FirstName: "First",
   486  		Username:  "User",
   487  		NotifyProps: map[string]string{
   488  			"mention_keys": "User,@User,MENTION",
   489  			"first_name":   "true",
   490  			"channel":      "true",
   491  		},
   492  	}
   493  
   494  	profiles = map[string]*model.User{user4.Id: user4}
   495  	mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
   496  	if len(mentions) != 6 {
   497  		t.Fatal("should've returned six mention keywords")
   498  	} else if ids, ok := mentions["user"]; !ok || ids[0] != user4.Id {
   499  		t.Fatal("should've returned mention key of user")
   500  	} else if ids, ok := mentions["@user"]; !ok || ids[0] != user4.Id {
   501  		t.Fatal("should've returned mention key of @user")
   502  	} else if ids, ok := mentions["mention"]; !ok || ids[0] != user4.Id {
   503  		t.Fatal("should've returned mention key of mention")
   504  	} else if ids, ok := mentions["First"]; !ok || ids[0] != user4.Id {
   505  		t.Fatal("should've returned mention key of First")
   506  	} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user4.Id {
   507  		t.Fatal("should've returned mention key of @channel")
   508  	} else if ids, ok := mentions["@all"]; !ok || ids[0] != user4.Id {
   509  		t.Fatal("should've returned mention key of @all")
   510  	}
   511  
   512  	dup_count := func(list []string) map[string]int {
   513  
   514  		duplicate_frequency := make(map[string]int)
   515  
   516  		for _, item := range list {
   517  			// check if the item/element exist in the duplicate_frequency map
   518  
   519  			_, exist := duplicate_frequency[item]
   520  
   521  			if exist {
   522  				duplicate_frequency[item] += 1 // increase counter by 1 if already in the map
   523  			} else {
   524  				duplicate_frequency[item] = 1 // else start counting from 1
   525  			}
   526  		}
   527  		return duplicate_frequency
   528  	}
   529  
   530  	// multiple users but no more than MaxNotificationsPerChannel
   531  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxNotificationsPerChannel = 4 })
   532  	profiles = map[string]*model.User{
   533  		user1.Id: user1,
   534  		user2.Id: user2,
   535  		user3.Id: user3,
   536  		user4.Id: user4,
   537  	}
   538  	mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
   539  	if len(mentions) != 6 {
   540  		t.Fatal("should've returned six mention keywords")
   541  	} 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) {
   542  		t.Fatal("should've mentioned user1 and user4 with user")
   543  	} else if ids := dup_count(mentions["@user"]); len(ids) != 4 || (ids[user1.Id] != 2) || (ids[user4.Id] != 2) {
   544  		t.Fatal("should've mentioned user1 and user4 with @user")
   545  	} else if ids, ok := mentions["mention"]; !ok || len(ids) != 2 || (ids[0] != user1.Id && ids[1] != user1.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
   546  		t.Fatal("should've mentioned user1 and user4 with mention")
   547  	} else if ids, ok := mentions["First"]; !ok || len(ids) != 2 || (ids[0] != user2.Id && ids[1] != user2.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
   548  		t.Fatal("should've mentioned user2 and user4 with First")
   549  	} else if ids, ok := mentions["@channel"]; !ok || len(ids) != 2 || (ids[0] != user3.Id && ids[1] != user3.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
   550  		t.Fatal("should've mentioned user3 and user4 with @channel")
   551  	} else if ids, ok := mentions["@all"]; !ok || len(ids) != 2 || (ids[0] != user3.Id && ids[1] != user3.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
   552  		t.Fatal("should've mentioned user3 and user4 with @all")
   553  	}
   554  
   555  	// multiple users and more than MaxNotificationsPerChannel
   556  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxNotificationsPerChannel = 3 })
   557  	mentions = th.App.GetMentionKeywordsInChannel(profiles, true)
   558  	if len(mentions) != 4 {
   559  		t.Fatal("should've returned four mention keywords")
   560  	} else if _, ok := mentions["@channel"]; ok {
   561  		t.Fatal("should not have mentioned any user with @channel")
   562  	} else if _, ok := mentions["@all"]; ok {
   563  		t.Fatal("should not have mentioned any user with @all")
   564  	} else if _, ok := mentions["@here"]; ok {
   565  		t.Fatal("should not have mentioned any user with @here")
   566  	}
   567  
   568  	// no special mentions
   569  	profiles = map[string]*model.User{
   570  		user1.Id: user1,
   571  	}
   572  	mentions = th.App.GetMentionKeywordsInChannel(profiles, false)
   573  	if len(mentions) != 3 {
   574  		t.Fatal("should've returned three mention keywords")
   575  	} else if ids, ok := mentions["user"]; !ok || len(ids) != 1 || ids[0] != user1.Id {
   576  		t.Fatal("should've mentioned user1 with user")
   577  	} else if ids, ok := mentions["@user"]; !ok || len(ids) != 2 || ids[0] != user1.Id || ids[1] != user1.Id {
   578  		t.Fatal("should've mentioned user1 twice with @user")
   579  	} else if ids, ok := mentions["mention"]; !ok || len(ids) != 1 || ids[0] != user1.Id {
   580  		t.Fatal("should've mentioned user1 with mention")
   581  	} else if _, ok := mentions["First"]; ok {
   582  		t.Fatal("should not have mentioned user1 with First")
   583  	} else if _, ok := mentions["@channel"]; ok {
   584  		t.Fatal("should not have mentioned any user with @channel")
   585  	} else if _, ok := mentions["@all"]; ok {
   586  		t.Fatal("should not have mentioned any user with @all")
   587  	} else if _, ok := mentions["@here"]; ok {
   588  		t.Fatal("should not have mentioned any user with @here")
   589  	}
   590  }
   591  
   592  func TestDoesNotifyPropsAllowPushNotification(t *testing.T) {
   593  	userNotifyProps := make(map[string]string)
   594  	channelNotifyProps := make(map[string]string)
   595  
   596  	user := &model.User{Id: model.NewId(), Email: "unit@test.com"}
   597  
   598  	post := &model.Post{UserId: user.Id, ChannelId: model.NewId()}
   599  
   600  	// When the post is a System Message
   601  	systemPost := &model.Post{UserId: user.Id, Type: model.POST_JOIN_CHANNEL}
   602  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL
   603  	user.NotifyProps = userNotifyProps
   604  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, systemPost, false) {
   605  		t.Fatal("Should have returned false")
   606  	}
   607  
   608  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, systemPost, true) {
   609  		t.Fatal("Should have returned false")
   610  	}
   611  
   612  	// When default is ALL and no channel props is set
   613  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   614  		t.Fatal("Should have returned true")
   615  	}
   616  
   617  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   618  		t.Fatal("Should have returned true")
   619  	}
   620  
   621  	// When default is MENTION and no channel props is set
   622  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION
   623  	user.NotifyProps = userNotifyProps
   624  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   625  		t.Fatal("Should have returned false")
   626  	}
   627  
   628  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   629  		t.Fatal("Should have returned true")
   630  	}
   631  
   632  	// When default is NONE and no channel props is set
   633  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE
   634  	user.NotifyProps = userNotifyProps
   635  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   636  		t.Fatal("Should have returned false")
   637  	}
   638  
   639  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   640  		t.Fatal("Should have returned false")
   641  	}
   642  
   643  	// WHEN default is ALL and channel is DEFAULT
   644  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL
   645  	user.NotifyProps = userNotifyProps
   646  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_DEFAULT
   647  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   648  		t.Fatal("Should have returned true")
   649  	}
   650  
   651  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   652  		t.Fatal("Should have returned true")
   653  	}
   654  
   655  	// WHEN default is MENTION and channel is DEFAULT
   656  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION
   657  	user.NotifyProps = userNotifyProps
   658  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_DEFAULT
   659  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   660  		t.Fatal("Should have returned false")
   661  	}
   662  
   663  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   664  		t.Fatal("Should have returned true")
   665  	}
   666  
   667  	// WHEN default is NONE and channel is DEFAULT
   668  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE
   669  	user.NotifyProps = userNotifyProps
   670  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_DEFAULT
   671  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   672  		t.Fatal("Should have returned false")
   673  	}
   674  
   675  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   676  		t.Fatal("Should have returned false")
   677  	}
   678  
   679  	// WHEN default is ALL and channel is ALL
   680  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL
   681  	user.NotifyProps = userNotifyProps
   682  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL
   683  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   684  		t.Fatal("Should have returned true")
   685  	}
   686  
   687  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   688  		t.Fatal("Should have returned true")
   689  	}
   690  
   691  	// WHEN default is MENTION and channel is ALL
   692  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION
   693  	user.NotifyProps = userNotifyProps
   694  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL
   695  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   696  		t.Fatal("Should have returned true")
   697  	}
   698  
   699  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   700  		t.Fatal("Should have returned true")
   701  	}
   702  
   703  	// WHEN default is NONE and channel is ALL
   704  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE
   705  	user.NotifyProps = userNotifyProps
   706  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL
   707  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   708  		t.Fatal("Should have returned true")
   709  	}
   710  
   711  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   712  		t.Fatal("Should have returned true")
   713  	}
   714  
   715  	// WHEN default is ALL and channel is MENTION
   716  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL
   717  	user.NotifyProps = userNotifyProps
   718  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION
   719  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   720  		t.Fatal("Should have returned false")
   721  	}
   722  
   723  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   724  		t.Fatal("Should have returned true")
   725  	}
   726  
   727  	// WHEN default is MENTION and channel is MENTION
   728  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION
   729  	user.NotifyProps = userNotifyProps
   730  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION
   731  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   732  		t.Fatal("Should have returned false")
   733  	}
   734  
   735  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   736  		t.Fatal("Should have returned true")
   737  	}
   738  
   739  	// WHEN default is NONE and channel is MENTION
   740  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE
   741  	user.NotifyProps = userNotifyProps
   742  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION
   743  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   744  		t.Fatal("Should have returned false")
   745  	}
   746  
   747  	if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   748  		t.Fatal("Should have returned true")
   749  	}
   750  
   751  	// WHEN default is ALL and channel is NONE
   752  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL
   753  	user.NotifyProps = userNotifyProps
   754  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_NONE
   755  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   756  		t.Fatal("Should have returned false")
   757  	}
   758  
   759  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   760  		t.Fatal("Should have returned false")
   761  	}
   762  
   763  	// WHEN default is MENTION and channel is NONE
   764  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION
   765  	user.NotifyProps = userNotifyProps
   766  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_NONE
   767  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   768  		t.Fatal("Should have returned false")
   769  	}
   770  
   771  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   772  		t.Fatal("Should have returned false")
   773  	}
   774  
   775  	// WHEN default is NONE and channel is NONE
   776  	userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE
   777  	user.NotifyProps = userNotifyProps
   778  	channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_NONE
   779  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) {
   780  		t.Fatal("Should have returned false")
   781  	}
   782  
   783  	if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) {
   784  		t.Fatal("Should have returned false")
   785  	}
   786  }
   787  
   788  func TestDoesStatusAllowPushNotification(t *testing.T) {
   789  	userNotifyProps := make(map[string]string)
   790  	userId := model.NewId()
   791  	channelId := model.NewId()
   792  
   793  	offline := &model.Status{UserId: userId, Status: model.STATUS_OFFLINE, Manual: false, LastActivityAt: 0, ActiveChannel: ""}
   794  	away := &model.Status{UserId: userId, Status: model.STATUS_AWAY, Manual: false, LastActivityAt: 0, ActiveChannel: ""}
   795  	online := &model.Status{UserId: userId, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: ""}
   796  	dnd := &model.Status{UserId: userId, Status: model.STATUS_DND, Manual: true, LastActivityAt: model.GetMillis(), ActiveChannel: ""}
   797  
   798  	userNotifyProps["push_status"] = model.STATUS_ONLINE
   799  	// WHEN props is ONLINE and user is offline
   800  	if !DoesStatusAllowPushNotification(userNotifyProps, offline, channelId) {
   801  		t.Fatal("Should have been true")
   802  	}
   803  
   804  	if !DoesStatusAllowPushNotification(userNotifyProps, offline, "") {
   805  		t.Fatal("Should have been true")
   806  	}
   807  
   808  	// WHEN props is ONLINE and user is away
   809  	if !DoesStatusAllowPushNotification(userNotifyProps, away, channelId) {
   810  		t.Fatal("Should have been true")
   811  	}
   812  
   813  	if !DoesStatusAllowPushNotification(userNotifyProps, away, "") {
   814  		t.Fatal("Should have been true")
   815  	}
   816  
   817  	// WHEN props is ONLINE and user is online
   818  	if !DoesStatusAllowPushNotification(userNotifyProps, online, channelId) {
   819  		t.Fatal("Should have been true")
   820  	}
   821  
   822  	if DoesStatusAllowPushNotification(userNotifyProps, online, "") {
   823  		t.Fatal("Should have been false")
   824  	}
   825  
   826  	// WHEN props is ONLINE and user is dnd
   827  	if DoesStatusAllowPushNotification(userNotifyProps, dnd, channelId) {
   828  		t.Fatal("Should have been false")
   829  	}
   830  
   831  	if DoesStatusAllowPushNotification(userNotifyProps, dnd, "") {
   832  		t.Fatal("Should have been false")
   833  	}
   834  
   835  	userNotifyProps["push_status"] = model.STATUS_AWAY
   836  	// WHEN props is AWAY and user is offline
   837  	if !DoesStatusAllowPushNotification(userNotifyProps, offline, channelId) {
   838  		t.Fatal("Should have been true")
   839  	}
   840  
   841  	if !DoesStatusAllowPushNotification(userNotifyProps, offline, "") {
   842  		t.Fatal("Should have been true")
   843  	}
   844  
   845  	// WHEN props is AWAY and user is away
   846  	if !DoesStatusAllowPushNotification(userNotifyProps, away, channelId) {
   847  		t.Fatal("Should have been true")
   848  	}
   849  
   850  	if !DoesStatusAllowPushNotification(userNotifyProps, away, "") {
   851  		t.Fatal("Should have been true")
   852  	}
   853  
   854  	// WHEN props is AWAY and user is online
   855  	if DoesStatusAllowPushNotification(userNotifyProps, online, channelId) {
   856  		t.Fatal("Should have been false")
   857  	}
   858  
   859  	if DoesStatusAllowPushNotification(userNotifyProps, online, "") {
   860  		t.Fatal("Should have been false")
   861  	}
   862  
   863  	// WHEN props is AWAY and user is dnd
   864  	if DoesStatusAllowPushNotification(userNotifyProps, dnd, channelId) {
   865  		t.Fatal("Should have been false")
   866  	}
   867  
   868  	if DoesStatusAllowPushNotification(userNotifyProps, dnd, "") {
   869  		t.Fatal("Should have been false")
   870  	}
   871  
   872  	userNotifyProps["push_status"] = model.STATUS_OFFLINE
   873  	// WHEN props is OFFLINE and user is offline
   874  	if !DoesStatusAllowPushNotification(userNotifyProps, offline, channelId) {
   875  		t.Fatal("Should have been true")
   876  	}
   877  
   878  	if !DoesStatusAllowPushNotification(userNotifyProps, offline, "") {
   879  		t.Fatal("Should have been true")
   880  	}
   881  
   882  	// WHEN props is OFFLINE and user is away
   883  	if DoesStatusAllowPushNotification(userNotifyProps, away, channelId) {
   884  		t.Fatal("Should have been false")
   885  	}
   886  
   887  	if DoesStatusAllowPushNotification(userNotifyProps, away, "") {
   888  		t.Fatal("Should have been false")
   889  	}
   890  
   891  	// WHEN props is OFFLINE and user is online
   892  	if DoesStatusAllowPushNotification(userNotifyProps, online, channelId) {
   893  		t.Fatal("Should have been false")
   894  	}
   895  
   896  	if DoesStatusAllowPushNotification(userNotifyProps, online, "") {
   897  		t.Fatal("Should have been false")
   898  	}
   899  
   900  	// WHEN props is OFFLINE and user is dnd
   901  	if DoesStatusAllowPushNotification(userNotifyProps, dnd, channelId) {
   902  		t.Fatal("Should have been false")
   903  	}
   904  
   905  	if DoesStatusAllowPushNotification(userNotifyProps, dnd, "") {
   906  		t.Fatal("Should have been false")
   907  	}
   908  
   909  }
   910  
   911  func TestGetDirectMessageNotificationEmailSubject(t *testing.T) {
   912  	th := Setup()
   913  	defer th.TearDown()
   914  
   915  	expectedPrefix := "[http://localhost:8065] New Direct Message from sender on"
   916  	post := &model.Post{
   917  		CreateAt: 1501804801000,
   918  	}
   919  	translateFunc := utils.GetUserTranslations("en")
   920  	subject := getDirectMessageNotificationEmailSubject(post, translateFunc, "http://localhost:8065", "sender")
   921  	if !strings.HasPrefix(subject, expectedPrefix) {
   922  		t.Fatal("Expected subject line prefix '" + expectedPrefix + "', got " + subject)
   923  	}
   924  }
   925  
   926  func TestGetNotificationEmailSubject(t *testing.T) {
   927  	th := Setup()
   928  	defer th.TearDown()
   929  
   930  	expectedPrefix := "[http://localhost:8065] Notification in team on"
   931  	post := &model.Post{
   932  		CreateAt: 1501804801000,
   933  	}
   934  	translateFunc := utils.GetUserTranslations("en")
   935  	subject := getNotificationEmailSubject(post, translateFunc, "http://localhost:8065", "team")
   936  	if !strings.HasPrefix(subject, expectedPrefix) {
   937  		t.Fatal("Expected subject line prefix '" + expectedPrefix + "', got " + subject)
   938  	}
   939  }
   940  
   941  func TestGetNotificationEmailBodyFullNotificationPublicChannel(t *testing.T) {
   942  	th := Setup()
   943  	defer th.TearDown()
   944  
   945  	recipient := &model.User{}
   946  	post := &model.Post{
   947  		Message: "This is the message",
   948  	}
   949  	channel := &model.Channel{
   950  		DisplayName: "ChannelName",
   951  		Type:        model.CHANNEL_OPEN,
   952  	}
   953  	senderName := "sender"
   954  	teamName := "team"
   955  	teamURL := "http://localhost:8065/" + teamName
   956  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL
   957  	translateFunc := utils.GetUserTranslations("en")
   958  
   959  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
   960  	if !strings.Contains(body, "You have a new notification.") {
   961  		t.Fatal("Expected email text 'You have a new notification. Got " + body)
   962  	}
   963  	if !strings.Contains(body, "CHANNEL: "+channel.DisplayName) {
   964  		t.Fatal("Expected email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body)
   965  	}
   966  	if !strings.Contains(body, senderName+" - ") {
   967  		t.Fatal("Expected email text '" + senderName + " - '. Got " + body)
   968  	}
   969  	if !strings.Contains(body, post.Message) {
   970  		t.Fatal("Expected email text '" + post.Message + "'. Got " + body)
   971  	}
   972  	if !strings.Contains(body, teamURL) {
   973  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
   974  	}
   975  }
   976  
   977  func TestGetNotificationEmailBodyFullNotificationGroupChannel(t *testing.T) {
   978  	th := Setup()
   979  	defer th.TearDown()
   980  
   981  	recipient := &model.User{}
   982  	post := &model.Post{
   983  		Message: "This is the message",
   984  	}
   985  	channel := &model.Channel{
   986  		DisplayName: "ChannelName",
   987  		Type:        model.CHANNEL_GROUP,
   988  	}
   989  	senderName := "sender"
   990  	teamName := "team"
   991  	teamURL := "http://localhost:8065/" + teamName
   992  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL
   993  	translateFunc := utils.GetUserTranslations("en")
   994  
   995  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
   996  	if !strings.Contains(body, "You have a new notification.") {
   997  		t.Fatal("Expected email text 'You have a new notification. Got " + body)
   998  	}
   999  	if !strings.Contains(body, "CHANNEL: Group Message") {
  1000  		t.Fatal("Expected email text 'CHANNEL: Group Message'. Got " + body)
  1001  	}
  1002  	if !strings.Contains(body, senderName+" - ") {
  1003  		t.Fatal("Expected email text '" + senderName + " - '. Got " + body)
  1004  	}
  1005  	if !strings.Contains(body, post.Message) {
  1006  		t.Fatal("Expected email text '" + post.Message + "'. Got " + body)
  1007  	}
  1008  	if !strings.Contains(body, teamURL) {
  1009  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1010  	}
  1011  }
  1012  
  1013  func TestGetNotificationEmailBodyFullNotificationPrivateChannel(t *testing.T) {
  1014  	th := Setup()
  1015  	defer th.TearDown()
  1016  
  1017  	recipient := &model.User{}
  1018  	post := &model.Post{
  1019  		Message: "This is the message",
  1020  	}
  1021  	channel := &model.Channel{
  1022  		DisplayName: "ChannelName",
  1023  		Type:        model.CHANNEL_PRIVATE,
  1024  	}
  1025  	senderName := "sender"
  1026  	teamName := "team"
  1027  	teamURL := "http://localhost:8065/" + teamName
  1028  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL
  1029  	translateFunc := utils.GetUserTranslations("en")
  1030  
  1031  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
  1032  	if !strings.Contains(body, "You have a new notification.") {
  1033  		t.Fatal("Expected email text 'You have a new notification. Got " + body)
  1034  	}
  1035  	if !strings.Contains(body, "CHANNEL: "+channel.DisplayName) {
  1036  		t.Fatal("Expected email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body)
  1037  	}
  1038  	if !strings.Contains(body, senderName+" - ") {
  1039  		t.Fatal("Expected email text '" + senderName + " - '. Got " + body)
  1040  	}
  1041  	if !strings.Contains(body, post.Message) {
  1042  		t.Fatal("Expected email text '" + post.Message + "'. Got " + body)
  1043  	}
  1044  	if !strings.Contains(body, teamURL) {
  1045  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1046  	}
  1047  }
  1048  
  1049  func TestGetNotificationEmailBodyFullNotificationDirectChannel(t *testing.T) {
  1050  	th := Setup()
  1051  	defer th.TearDown()
  1052  
  1053  	recipient := &model.User{}
  1054  	post := &model.Post{
  1055  		Message: "This is the message",
  1056  	}
  1057  	channel := &model.Channel{
  1058  		DisplayName: "ChannelName",
  1059  		Type:        model.CHANNEL_DIRECT,
  1060  	}
  1061  	senderName := "sender"
  1062  	teamName := "team"
  1063  	teamURL := "http://localhost:8065/" + teamName
  1064  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL
  1065  	translateFunc := utils.GetUserTranslations("en")
  1066  
  1067  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
  1068  	if !strings.Contains(body, "You have a new direct message.") {
  1069  		t.Fatal("Expected email text 'You have a new direct message. Got " + body)
  1070  	}
  1071  	if !strings.Contains(body, senderName+" - ") {
  1072  		t.Fatal("Expected email text '" + senderName + " - '. Got " + body)
  1073  	}
  1074  	if !strings.Contains(body, post.Message) {
  1075  		t.Fatal("Expected email text '" + post.Message + "'. Got " + body)
  1076  	}
  1077  	if !strings.Contains(body, teamURL) {
  1078  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1079  	}
  1080  }
  1081  
  1082  // from here
  1083  func TestGetNotificationEmailBodyGenericNotificationPublicChannel(t *testing.T) {
  1084  	th := Setup()
  1085  	defer th.TearDown()
  1086  
  1087  	recipient := &model.User{}
  1088  	post := &model.Post{
  1089  		Message: "This is the message",
  1090  	}
  1091  	channel := &model.Channel{
  1092  		DisplayName: "ChannelName",
  1093  		Type:        model.CHANNEL_OPEN,
  1094  	}
  1095  	senderName := "sender"
  1096  	teamName := "team"
  1097  	teamURL := "http://localhost:8065/" + teamName
  1098  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC
  1099  	translateFunc := utils.GetUserTranslations("en")
  1100  
  1101  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
  1102  	if !strings.Contains(body, "You have a new notification from "+senderName) {
  1103  		t.Fatal("Expected email text 'You have a new notification from " + senderName + "'. Got " + body)
  1104  	}
  1105  	if strings.Contains(body, "CHANNEL: "+channel.DisplayName) {
  1106  		t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body)
  1107  	}
  1108  	if strings.Contains(body, post.Message) {
  1109  		t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body)
  1110  	}
  1111  	if !strings.Contains(body, teamURL) {
  1112  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1113  	}
  1114  }
  1115  
  1116  func TestGetNotificationEmailBodyGenericNotificationGroupChannel(t *testing.T) {
  1117  	th := Setup()
  1118  	defer th.TearDown()
  1119  
  1120  	recipient := &model.User{}
  1121  	post := &model.Post{
  1122  		Message: "This is the message",
  1123  	}
  1124  	channel := &model.Channel{
  1125  		DisplayName: "ChannelName",
  1126  		Type:        model.CHANNEL_GROUP,
  1127  	}
  1128  	senderName := "sender"
  1129  	teamName := "team"
  1130  	teamURL := "http://localhost:8065/" + teamName
  1131  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC
  1132  	translateFunc := utils.GetUserTranslations("en")
  1133  
  1134  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
  1135  	if !strings.Contains(body, "You have a new notification from "+senderName) {
  1136  		t.Fatal("Expected email text 'You have a new notification from " + senderName + "'. Got " + body)
  1137  	}
  1138  	if strings.Contains(body, "CHANNEL: "+channel.DisplayName) {
  1139  		t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body)
  1140  	}
  1141  	if strings.Contains(body, post.Message) {
  1142  		t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body)
  1143  	}
  1144  	if !strings.Contains(body, teamURL) {
  1145  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1146  	}
  1147  }
  1148  
  1149  func TestGetNotificationEmailBodyGenericNotificationPrivateChannel(t *testing.T) {
  1150  	th := Setup()
  1151  	defer th.TearDown()
  1152  
  1153  	recipient := &model.User{}
  1154  	post := &model.Post{
  1155  		Message: "This is the message",
  1156  	}
  1157  	channel := &model.Channel{
  1158  		DisplayName: "ChannelName",
  1159  		Type:        model.CHANNEL_PRIVATE,
  1160  	}
  1161  	senderName := "sender"
  1162  	teamName := "team"
  1163  	teamURL := "http://localhost:8065/" + teamName
  1164  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC
  1165  	translateFunc := utils.GetUserTranslations("en")
  1166  
  1167  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
  1168  	if !strings.Contains(body, "You have a new notification from "+senderName) {
  1169  		t.Fatal("Expected email text 'You have a new notification from " + senderName + "'. Got " + body)
  1170  	}
  1171  	if strings.Contains(body, "CHANNEL: "+channel.DisplayName) {
  1172  		t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body)
  1173  	}
  1174  	if strings.Contains(body, post.Message) {
  1175  		t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body)
  1176  	}
  1177  	if !strings.Contains(body, teamURL) {
  1178  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1179  	}
  1180  }
  1181  
  1182  func TestGetNotificationEmailBodyGenericNotificationDirectChannel(t *testing.T) {
  1183  	th := Setup()
  1184  	defer th.TearDown()
  1185  
  1186  	recipient := &model.User{}
  1187  	post := &model.Post{
  1188  		Message: "This is the message",
  1189  	}
  1190  	channel := &model.Channel{
  1191  		DisplayName: "ChannelName",
  1192  		Type:        model.CHANNEL_DIRECT,
  1193  	}
  1194  	senderName := "sender"
  1195  	teamName := "team"
  1196  	teamURL := "http://localhost:8065/" + teamName
  1197  	emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC
  1198  	translateFunc := utils.GetUserTranslations("en")
  1199  
  1200  	body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc)
  1201  	if !strings.Contains(body, "You have a new direct message from "+senderName) {
  1202  		t.Fatal("Expected email text 'You have a new direct message from " + senderName + "'. Got " + body)
  1203  	}
  1204  	if strings.Contains(body, "CHANNEL: "+channel.DisplayName) {
  1205  		t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body)
  1206  	}
  1207  	if strings.Contains(body, post.Message) {
  1208  		t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body)
  1209  	}
  1210  	if !strings.Contains(body, teamURL) {
  1211  		t.Fatal("Expected email text '" + teamURL + "'. Got " + body)
  1212  	}
  1213  }
  1214  
  1215  func TestGetPushNotificationMessage(t *testing.T) {
  1216  	th := Setup()
  1217  	defer th.TearDown()
  1218  
  1219  	for name, tc := range map[string]struct {
  1220  		Message                  string
  1221  		WasMentioned             bool
  1222  		HasFiles                 bool
  1223  		Locale                   string
  1224  		PushNotificationContents string
  1225  		ChannelType              string
  1226  
  1227  		ExpectedMessage  string
  1228  		ExpectedCategory string
  1229  	}{
  1230  		"full message, public channel, no mention": {
  1231  			Message:          "this is a message",
  1232  			ChannelType:      model.CHANNEL_OPEN,
  1233  			ExpectedMessage:  "user in channel: this is a message",
  1234  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1235  		},
  1236  		"full message, public channel, mention": {
  1237  			Message:          "this is a message",
  1238  			WasMentioned:     true,
  1239  			ChannelType:      model.CHANNEL_OPEN,
  1240  			ExpectedMessage:  "user in channel: this is a message",
  1241  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1242  		},
  1243  		"full message, private channel, no mention": {
  1244  			Message:          "this is a message",
  1245  			ChannelType:      model.CHANNEL_PRIVATE,
  1246  			ExpectedMessage:  "user in channel: this is a message",
  1247  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1248  		},
  1249  		"full message, private channel, mention": {
  1250  			Message:          "this is a message",
  1251  			WasMentioned:     true,
  1252  			ChannelType:      model.CHANNEL_PRIVATE,
  1253  			ExpectedMessage:  "user in channel: this is a message",
  1254  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1255  		},
  1256  		"full message, group message channel, no mention": {
  1257  			Message:          "this is a message",
  1258  			ChannelType:      model.CHANNEL_GROUP,
  1259  			ExpectedMessage:  "user in channel: this is a message",
  1260  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1261  		},
  1262  		"full message, group message channel, mention": {
  1263  			Message:          "this is a message",
  1264  			WasMentioned:     true,
  1265  			ChannelType:      model.CHANNEL_GROUP,
  1266  			ExpectedMessage:  "user in channel: this is a message",
  1267  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1268  		},
  1269  		"full message, direct message channel, no mention": {
  1270  			Message:          "this is a message",
  1271  			ChannelType:      model.CHANNEL_DIRECT,
  1272  			ExpectedMessage:  "user: this is a message",
  1273  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1274  		},
  1275  		"full message, direct message channel, mention": {
  1276  			Message:          "this is a message",
  1277  			WasMentioned:     true,
  1278  			ChannelType:      model.CHANNEL_DIRECT,
  1279  			ExpectedMessage:  "user: this is a message",
  1280  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1281  		},
  1282  		"generic message with channel, public channel, no mention": {
  1283  			Message:                  "this is a message",
  1284  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1285  			ChannelType:              model.CHANNEL_OPEN,
  1286  			ExpectedMessage:          "user posted in channel",
  1287  		},
  1288  		"generic message with channel, public channel, mention": {
  1289  			Message:                  "this is a message",
  1290  			WasMentioned:             true,
  1291  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1292  			ChannelType:              model.CHANNEL_OPEN,
  1293  			ExpectedMessage:          "user mentioned you in channel",
  1294  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1295  		},
  1296  		"generic message with channel, private channel, no mention": {
  1297  			Message:                  "this is a message",
  1298  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1299  			ChannelType:              model.CHANNEL_PRIVATE,
  1300  			ExpectedMessage:          "user posted in channel",
  1301  		},
  1302  		"generic message with channel, private channel, mention": {
  1303  			Message:                  "this is a message",
  1304  			WasMentioned:             true,
  1305  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1306  			ChannelType:              model.CHANNEL_PRIVATE,
  1307  			ExpectedMessage:          "user mentioned you in channel",
  1308  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1309  		},
  1310  		"generic message with channel, group message channel, no mention": {
  1311  			Message:                  "this is a message",
  1312  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1313  			ChannelType:              model.CHANNEL_GROUP,
  1314  			ExpectedMessage:          "user posted in channel",
  1315  		},
  1316  		"generic message with channel, group message channel, mention": {
  1317  			Message:                  "this is a message",
  1318  			WasMentioned:             true,
  1319  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1320  			ChannelType:              model.CHANNEL_GROUP,
  1321  			ExpectedMessage:          "user mentioned you in channel",
  1322  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1323  		},
  1324  		"generic message with channel, direct message channel, no mention": {
  1325  			Message:                  "this is a message",
  1326  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1327  			ChannelType:              model.CHANNEL_DIRECT,
  1328  			ExpectedMessage:          "user sent you a direct message",
  1329  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1330  		},
  1331  		"generic message with channel, direct message channel, mention": {
  1332  			Message:                  "this is a message",
  1333  			WasMentioned:             true,
  1334  			PushNotificationContents: model.GENERIC_NOTIFICATION,
  1335  			ChannelType:              model.CHANNEL_DIRECT,
  1336  			ExpectedMessage:          "user sent you a direct message",
  1337  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1338  		},
  1339  		"generic message without channel, public channel, no mention": {
  1340  			Message:                  "this is a message",
  1341  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1342  			ChannelType:              model.CHANNEL_OPEN,
  1343  			ExpectedMessage:          "user posted a message",
  1344  		},
  1345  		"generic message without channel, public channel, mention": {
  1346  			Message:                  "this is a message",
  1347  			WasMentioned:             true,
  1348  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1349  			ChannelType:              model.CHANNEL_OPEN,
  1350  			ExpectedMessage:          "user mentioned you",
  1351  		},
  1352  		"generic message without channel, private channel, no mention": {
  1353  			Message:                  "this is a message",
  1354  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1355  			ChannelType:              model.CHANNEL_PRIVATE,
  1356  			ExpectedMessage:          "user posted a message",
  1357  		},
  1358  		"generic message without channel, private channel, mention": {
  1359  			Message:                  "this is a message",
  1360  			WasMentioned:             true,
  1361  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1362  			ChannelType:              model.CHANNEL_PRIVATE,
  1363  			ExpectedMessage:          "user mentioned you",
  1364  		},
  1365  		"generic message without channel, group message channel, no mention": {
  1366  			Message:                  "this is a message",
  1367  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1368  			ChannelType:              model.CHANNEL_GROUP,
  1369  			ExpectedMessage:          "user posted a message",
  1370  		},
  1371  		"generic message without channel, group message channel, mention": {
  1372  			Message:                  "this is a message",
  1373  			WasMentioned:             true,
  1374  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1375  			ChannelType:              model.CHANNEL_GROUP,
  1376  			ExpectedMessage:          "user mentioned you",
  1377  		},
  1378  		"generic message without channel, direct message channel, no mention": {
  1379  			Message:                  "this is a message",
  1380  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1381  			ChannelType:              model.CHANNEL_DIRECT,
  1382  			ExpectedMessage:          "user sent you a direct message",
  1383  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1384  		},
  1385  		"generic message without channel, direct message channel, mention": {
  1386  			Message:                  "this is a message",
  1387  			WasMentioned:             true,
  1388  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1389  			ChannelType:              model.CHANNEL_DIRECT,
  1390  			ExpectedMessage:          "user sent you a direct message",
  1391  			ExpectedCategory:         model.CATEGORY_CAN_REPLY,
  1392  		},
  1393  		"only files, public channel": {
  1394  			HasFiles:         true,
  1395  			ChannelType:      model.CHANNEL_OPEN,
  1396  			ExpectedMessage:  "user uploaded one or more files in channel",
  1397  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1398  		},
  1399  		"only files, private channel": {
  1400  			HasFiles:         true,
  1401  			ChannelType:      model.CHANNEL_PRIVATE,
  1402  			ExpectedMessage:  "user uploaded one or more files in channel",
  1403  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1404  		},
  1405  		"only files, group message channel": {
  1406  			HasFiles:         true,
  1407  			ChannelType:      model.CHANNEL_GROUP,
  1408  			ExpectedMessage:  "user uploaded one or more files in channel",
  1409  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1410  		},
  1411  		"only files, direct message channel": {
  1412  			HasFiles:         true,
  1413  			ChannelType:      model.CHANNEL_DIRECT,
  1414  			ExpectedMessage:  "user uploaded one or more files in a direct message",
  1415  			ExpectedCategory: model.CATEGORY_CAN_REPLY,
  1416  		},
  1417  		"only files without channel, public channel": {
  1418  			HasFiles:                 true,
  1419  			PushNotificationContents: model.GENERIC_NO_CHANNEL_NOTIFICATION,
  1420  			ChannelType:              model.CHANNEL_OPEN,
  1421  			ExpectedMessage:          "user uploaded one or more files",
  1422  		},
  1423  	} {
  1424  		t.Run(name, func(t *testing.T) {
  1425  			locale := tc.Locale
  1426  			if locale == "" {
  1427  				locale = "en"
  1428  			}
  1429  
  1430  			pushNotificationContents := tc.PushNotificationContents
  1431  			if pushNotificationContents == "" {
  1432  				pushNotificationContents = model.FULL_NOTIFICATION
  1433  			}
  1434  
  1435  			th.App.UpdateConfig(func(cfg *model.Config) {
  1436  				*cfg.EmailSettings.PushNotificationContents = pushNotificationContents
  1437  			})
  1438  
  1439  			if actualMessage, actualCategory := th.App.getPushNotificationMessage(
  1440  				tc.Message,
  1441  				tc.WasMentioned,
  1442  				tc.HasFiles,
  1443  				"user",
  1444  				"channel",
  1445  				tc.ChannelType,
  1446  				utils.GetUserTranslations(locale),
  1447  			); actualMessage != tc.ExpectedMessage {
  1448  				t.Fatalf("Received incorrect push notification message `%v`, expected `%v`", actualMessage, tc.ExpectedMessage)
  1449  			} else if actualCategory != tc.ExpectedCategory {
  1450  				t.Fatalf("Received incorrect push notification category `%v`, expected `%v`", actualCategory, tc.ExpectedCategory)
  1451  			}
  1452  		})
  1453  	}
  1454  }