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