github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+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 "OnePersonWithoutAtMention": { 113 Message: "this is a message for @user", 114 Keywords: map[string][]string{"this": {id1}}, 115 Expected: &ExplicitMentions{ 116 MentionedUserIds: map[string]bool{ 117 id1: true, 118 }, 119 OtherPotentialMentions: []string{"user"}, 120 }, 121 }, 122 "MultiplePeopleWithOneWord": { 123 Message: "this is a message for @user", 124 Keywords: map[string][]string{"@user": {id1, id2}}, 125 Expected: &ExplicitMentions{ 126 MentionedUserIds: map[string]bool{ 127 id1: true, 128 id2: true, 129 }, 130 }, 131 }, 132 "OneOfMultiplePeople": { 133 Message: "this is a message for @user", 134 Keywords: map[string][]string{"@user": {id1}, "@mention": {id2}}, 135 Expected: &ExplicitMentions{ 136 MentionedUserIds: map[string]bool{ 137 id1: true, 138 }, 139 }, 140 }, 141 "MultiplePeopleWithMultipleWords": { 142 Message: "this is an @mention for @user", 143 Keywords: map[string][]string{"@user": {id1}, "@mention": {id2}}, 144 Expected: &ExplicitMentions{ 145 MentionedUserIds: map[string]bool{ 146 id1: true, 147 id2: true, 148 }, 149 }, 150 }, 151 "Channel": { 152 Message: "this is an message for @channel", 153 Keywords: map[string][]string{"@channel": {id1, id2}}, 154 Expected: &ExplicitMentions{ 155 MentionedUserIds: map[string]bool{ 156 id1: true, 157 id2: true, 158 }, 159 ChannelMentioned: true, 160 }, 161 }, 162 "All": { 163 Message: "this is an message for @all", 164 Keywords: map[string][]string{"@all": {id1, id2}}, 165 Expected: &ExplicitMentions{ 166 MentionedUserIds: map[string]bool{ 167 id1: true, 168 id2: true, 169 }, 170 AllMentioned: true, 171 }, 172 }, 173 "UserWithPeriod": { 174 Message: "user.period doesn't complicate things at all by including periods in their username", 175 Keywords: map[string][]string{"user.period": {id1}, "user": {id2}}, 176 Expected: &ExplicitMentions{ 177 MentionedUserIds: map[string]bool{ 178 id1: true, 179 }, 180 }, 181 }, 182 "PotentialOutOfChannelUser": { 183 Message: "this is an message for @potential and @user", 184 Keywords: map[string][]string{"@user": {id1}}, 185 Expected: &ExplicitMentions{ 186 MentionedUserIds: map[string]bool{ 187 id1: true, 188 }, 189 OtherPotentialMentions: []string{"potential"}, 190 }, 191 }, 192 "InlineCode": { 193 Message: "`this shouldn't mention @channel at all`", 194 Keywords: map[string][]string{}, 195 Expected: &ExplicitMentions{}, 196 }, 197 "FencedCodeBlock": { 198 Message: "```\nthis shouldn't mention @channel at all\n```", 199 Keywords: map[string][]string{}, 200 Expected: &ExplicitMentions{}, 201 }, 202 "Emphasis": { 203 Message: "*@aaa @bbb @ccc*", 204 Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}}, 205 Expected: &ExplicitMentions{ 206 MentionedUserIds: map[string]bool{ 207 id1: true, 208 id2: true, 209 id3: true, 210 }, 211 }, 212 }, 213 "StrongEmphasis": { 214 Message: "**@aaa @bbb @ccc**", 215 Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}}, 216 Expected: &ExplicitMentions{ 217 MentionedUserIds: map[string]bool{ 218 id1: true, 219 id2: true, 220 id3: true, 221 }, 222 }, 223 }, 224 "Strikethrough": { 225 Message: "~~@aaa @bbb @ccc~~", 226 Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}}, 227 Expected: &ExplicitMentions{ 228 MentionedUserIds: map[string]bool{ 229 id1: true, 230 id2: true, 231 id3: true, 232 }, 233 }, 234 }, 235 "Heading": { 236 Message: "### @aaa", 237 Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}}, 238 Expected: &ExplicitMentions{ 239 MentionedUserIds: map[string]bool{ 240 id1: true, 241 }, 242 }, 243 }, 244 "BlockQuote": { 245 Message: "> @aaa", 246 Keywords: map[string][]string{"@aaa": {id1}, "@bbb": {id2}, "@ccc": {id3}}, 247 Expected: &ExplicitMentions{ 248 MentionedUserIds: map[string]bool{ 249 id1: true, 250 }, 251 }, 252 }, 253 "Emoji": { 254 Message: ":smile:", 255 Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}}, 256 Expected: &ExplicitMentions{}, 257 }, 258 "NotEmoji": { 259 Message: "smile", 260 Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}}, 261 Expected: &ExplicitMentions{ 262 MentionedUserIds: map[string]bool{ 263 id1: true, 264 }, 265 }, 266 }, 267 "UnclosedEmoji": { 268 Message: ":smile", 269 Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}}, 270 Expected: &ExplicitMentions{ 271 MentionedUserIds: map[string]bool{ 272 id1: true, 273 }, 274 }, 275 }, 276 "UnopenedEmoji": { 277 Message: "smile:", 278 Keywords: map[string][]string{"smile": {id1}, "smiley": {id2}, "smiley_cat": {id3}}, 279 Expected: &ExplicitMentions{ 280 MentionedUserIds: map[string]bool{ 281 id1: true, 282 }, 283 }, 284 }, 285 "IndentedCodeBlock": { 286 Message: " this shouldn't mention @channel at all", 287 Keywords: map[string][]string{}, 288 Expected: &ExplicitMentions{}, 289 }, 290 "LinkTitle": { 291 Message: `[foo](this "shouldn't mention @channel at all")`, 292 Keywords: map[string][]string{}, 293 Expected: &ExplicitMentions{}, 294 }, 295 "MalformedInlineCode": { 296 Message: "`this should mention @channel``", 297 Keywords: map[string][]string{}, 298 Expected: &ExplicitMentions{ 299 ChannelMentioned: true, 300 }, 301 }, 302 } { 303 t.Run(name, func(t *testing.T) { 304 m := GetExplicitMentions(tc.Message, tc.Keywords) 305 if tc.Expected.MentionedUserIds == nil { 306 tc.Expected.MentionedUserIds = make(map[string]bool) 307 } 308 assert.EqualValues(t, tc.Expected, m) 309 }) 310 } 311 } 312 313 func TestGetExplicitMentionsAtHere(t *testing.T) { 314 // test all the boundary cases that we know can break up terms (and those that we know won't) 315 cases := map[string]bool{ 316 "": false, 317 "here": false, 318 "@here": true, 319 " @here ": true, 320 "\n@here\n": true, 321 "!@here!": true, 322 "#@here#": true, 323 "$@here$": true, 324 "%@here%": true, 325 "^@here^": true, 326 "&@here&": true, 327 "*@here*": true, 328 "(@here(": true, 329 ")@here)": true, 330 "-@here-": true, 331 "_@here_": false, // This case shouldn't mention since it would be mentioning "@here_" 332 "=@here=": true, 333 "+@here+": true, 334 "[@here[": true, 335 "{@here{": true, 336 "]@here]": true, 337 "}@here}": true, 338 "\\@here\\": true, 339 "|@here|": true, 340 ";@here;": true, 341 ":@here:": false, // This case shouldn't trigger a mention since it follows the format of reactions e.g. :word: 342 "'@here'": true, 343 "\"@here\"": true, 344 ",@here,": true, 345 "<@here<": true, 346 ".@here.": true, 347 ">@here>": true, 348 "/@here/": true, 349 "?@here?": true, 350 "`@here`": false, // This case shouldn't mention since it's a code block 351 "~@here~": true, 352 } 353 354 for message, shouldMention := range cases { 355 if m := GetExplicitMentions(message, nil); m.HereMentioned && !shouldMention { 356 t.Fatalf("shouldn't have mentioned @here with \"%v\"", message) 357 } else if !m.HereMentioned && shouldMention { 358 t.Fatalf("should've mentioned @here with \"%v\"", message) 359 } 360 } 361 362 // mentioning @here and someone 363 id := model.NewId() 364 if m := GetExplicitMentions("@here @user @potential", map[string][]string{"@user": {id}}); !m.HereMentioned { 365 t.Fatal("should've mentioned @here with \"@here @user\"") 366 } else if len(m.MentionedUserIds) != 1 || !m.MentionedUserIds[id] { 367 t.Fatal("should've mentioned @user with \"@here @user\"") 368 } else if len(m.OtherPotentialMentions) > 1 { 369 t.Fatal("should've potential mentions for @potential") 370 } 371 } 372 373 func TestGetMentionKeywords(t *testing.T) { 374 th := Setup() 375 defer th.TearDown() 376 377 // user with username or custom mentions enabled 378 user1 := &model.User{ 379 Id: model.NewId(), 380 FirstName: "First", 381 Username: "User", 382 NotifyProps: map[string]string{ 383 "mention_keys": "User,@User,MENTION", 384 }, 385 } 386 387 profiles := map[string]*model.User{user1.Id: user1} 388 mentions := th.App.GetMentionKeywordsInChannel(profiles, true) 389 if len(mentions) != 3 { 390 t.Fatal("should've returned three mention keywords") 391 } else if ids, ok := mentions["user"]; !ok || ids[0] != user1.Id { 392 t.Fatal("should've returned mention key of user") 393 } else if ids, ok := mentions["@user"]; !ok || ids[0] != user1.Id { 394 t.Fatal("should've returned mention key of @user") 395 } else if ids, ok := mentions["mention"]; !ok || ids[0] != user1.Id { 396 t.Fatal("should've returned mention key of mention") 397 } 398 399 // user with first name mention enabled 400 user2 := &model.User{ 401 Id: model.NewId(), 402 FirstName: "First", 403 Username: "User", 404 NotifyProps: map[string]string{ 405 "first_name": "true", 406 }, 407 } 408 409 profiles = map[string]*model.User{user2.Id: user2} 410 mentions = th.App.GetMentionKeywordsInChannel(profiles, true) 411 if len(mentions) != 2 { 412 t.Fatal("should've returned two mention keyword") 413 } else if ids, ok := mentions["First"]; !ok || ids[0] != user2.Id { 414 t.Fatal("should've returned mention key of First") 415 } 416 417 // user with @channel/@all mentions enabled 418 user3 := &model.User{ 419 Id: model.NewId(), 420 FirstName: "First", 421 Username: "User", 422 NotifyProps: map[string]string{ 423 "channel": "true", 424 }, 425 } 426 427 profiles = map[string]*model.User{user3.Id: user3} 428 mentions = th.App.GetMentionKeywordsInChannel(profiles, true) 429 if len(mentions) != 3 { 430 t.Fatal("should've returned three mention keywords") 431 } else if ids, ok := mentions["@channel"]; !ok || ids[0] != user3.Id { 432 t.Fatal("should've returned mention key of @channel") 433 } else if ids, ok := mentions["@all"]; !ok || ids[0] != user3.Id { 434 t.Fatal("should've returned mention key of @all") 435 } 436 437 // user with all types of mentions enabled 438 user4 := &model.User{ 439 Id: model.NewId(), 440 FirstName: "First", 441 Username: "User", 442 NotifyProps: map[string]string{ 443 "mention_keys": "User,@User,MENTION", 444 "first_name": "true", 445 "channel": "true", 446 }, 447 } 448 449 profiles = map[string]*model.User{user4.Id: user4} 450 mentions = th.App.GetMentionKeywordsInChannel(profiles, true) 451 if len(mentions) != 6 { 452 t.Fatal("should've returned six mention keywords") 453 } else if ids, ok := mentions["user"]; !ok || ids[0] != user4.Id { 454 t.Fatal("should've returned mention key of user") 455 } else if ids, ok := mentions["@user"]; !ok || ids[0] != user4.Id { 456 t.Fatal("should've returned mention key of @user") 457 } else if ids, ok := mentions["mention"]; !ok || ids[0] != user4.Id { 458 t.Fatal("should've returned mention key of mention") 459 } else if ids, ok := mentions["First"]; !ok || ids[0] != user4.Id { 460 t.Fatal("should've returned mention key of First") 461 } else if ids, ok := mentions["@channel"]; !ok || ids[0] != user4.Id { 462 t.Fatal("should've returned mention key of @channel") 463 } else if ids, ok := mentions["@all"]; !ok || ids[0] != user4.Id { 464 t.Fatal("should've returned mention key of @all") 465 } 466 467 dup_count := func(list []string) map[string]int { 468 469 duplicate_frequency := make(map[string]int) 470 471 for _, item := range list { 472 // check if the item/element exist in the duplicate_frequency map 473 474 _, exist := duplicate_frequency[item] 475 476 if exist { 477 duplicate_frequency[item] += 1 // increase counter by 1 if already in the map 478 } else { 479 duplicate_frequency[item] = 1 // else start counting from 1 480 } 481 } 482 return duplicate_frequency 483 } 484 485 // multiple users but no more than MaxNotificationsPerChannel 486 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxNotificationsPerChannel = 4 }) 487 profiles = map[string]*model.User{ 488 user1.Id: user1, 489 user2.Id: user2, 490 user3.Id: user3, 491 user4.Id: user4, 492 } 493 mentions = th.App.GetMentionKeywordsInChannel(profiles, true) 494 if len(mentions) != 6 { 495 t.Fatal("should've returned six mention keywords") 496 } 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) { 497 t.Fatal("should've mentioned user1 and user4 with user") 498 } else if ids := dup_count(mentions["@user"]); len(ids) != 4 || (ids[user1.Id] != 2) || (ids[user4.Id] != 2) { 499 t.Fatal("should've mentioned user1 and user4 with @user") 500 } 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) { 501 t.Fatal("should've mentioned user1 and user4 with mention") 502 } 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) { 503 t.Fatal("should've mentioned user2 and user4 with First") 504 } 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) { 505 t.Fatal("should've mentioned user3 and user4 with @channel") 506 } 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) { 507 t.Fatal("should've mentioned user3 and user4 with @all") 508 } 509 510 // multiple users and more than MaxNotificationsPerChannel 511 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxNotificationsPerChannel = 3 }) 512 mentions = th.App.GetMentionKeywordsInChannel(profiles, true) 513 if len(mentions) != 4 { 514 t.Fatal("should've returned four mention keywords") 515 } else if _, ok := mentions["@channel"]; ok { 516 t.Fatal("should not have mentioned any user with @channel") 517 } else if _, ok := mentions["@all"]; ok { 518 t.Fatal("should not have mentioned any user with @all") 519 } else if _, ok := mentions["@here"]; ok { 520 t.Fatal("should not have mentioned any user with @here") 521 } 522 523 // no special mentions 524 profiles = map[string]*model.User{ 525 user1.Id: user1, 526 } 527 mentions = th.App.GetMentionKeywordsInChannel(profiles, false) 528 if len(mentions) != 3 { 529 t.Fatal("should've returned three mention keywords") 530 } else if ids, ok := mentions["user"]; !ok || len(ids) != 1 || ids[0] != user1.Id { 531 t.Fatal("should've mentioned user1 with user") 532 } else if ids, ok := mentions["@user"]; !ok || len(ids) != 2 || ids[0] != user1.Id || ids[1] != user1.Id { 533 t.Fatal("should've mentioned user1 twice with @user") 534 } else if ids, ok := mentions["mention"]; !ok || len(ids) != 1 || ids[0] != user1.Id { 535 t.Fatal("should've mentioned user1 with mention") 536 } else if _, ok := mentions["First"]; ok { 537 t.Fatal("should not have mentioned user1 with First") 538 } else if _, ok := mentions["@channel"]; ok { 539 t.Fatal("should not have mentioned any user with @channel") 540 } else if _, ok := mentions["@all"]; ok { 541 t.Fatal("should not have mentioned any user with @all") 542 } else if _, ok := mentions["@here"]; ok { 543 t.Fatal("should not have mentioned any user with @here") 544 } 545 } 546 547 func TestDoesNotifyPropsAllowPushNotification(t *testing.T) { 548 userNotifyProps := make(map[string]string) 549 channelNotifyProps := make(map[string]string) 550 551 user := &model.User{Id: model.NewId(), Email: "unit@test.com"} 552 553 post := &model.Post{UserId: user.Id, ChannelId: model.NewId()} 554 555 // When the post is a System Message 556 systemPost := &model.Post{UserId: user.Id, Type: model.POST_JOIN_CHANNEL} 557 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL 558 user.NotifyProps = userNotifyProps 559 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, systemPost, false) { 560 t.Fatal("Should have returned false") 561 } 562 563 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, systemPost, true) { 564 t.Fatal("Should have returned false") 565 } 566 567 // When default is ALL and no channel props is set 568 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 569 t.Fatal("Should have returned true") 570 } 571 572 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 573 t.Fatal("Should have returned true") 574 } 575 576 // When default is MENTION and no channel props is set 577 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION 578 user.NotifyProps = userNotifyProps 579 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 580 t.Fatal("Should have returned false") 581 } 582 583 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 584 t.Fatal("Should have returned true") 585 } 586 587 // When default is NONE and no channel props is set 588 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE 589 user.NotifyProps = userNotifyProps 590 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 591 t.Fatal("Should have returned false") 592 } 593 594 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 595 t.Fatal("Should have returned false") 596 } 597 598 // WHEN default is ALL and channel is DEFAULT 599 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL 600 user.NotifyProps = userNotifyProps 601 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_DEFAULT 602 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 603 t.Fatal("Should have returned true") 604 } 605 606 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 607 t.Fatal("Should have returned true") 608 } 609 610 // WHEN default is MENTION and channel is DEFAULT 611 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION 612 user.NotifyProps = userNotifyProps 613 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_DEFAULT 614 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 615 t.Fatal("Should have returned false") 616 } 617 618 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 619 t.Fatal("Should have returned true") 620 } 621 622 // WHEN default is NONE and channel is DEFAULT 623 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE 624 user.NotifyProps = userNotifyProps 625 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_DEFAULT 626 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 627 t.Fatal("Should have returned false") 628 } 629 630 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 631 t.Fatal("Should have returned false") 632 } 633 634 // WHEN default is ALL and channel is ALL 635 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL 636 user.NotifyProps = userNotifyProps 637 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL 638 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 639 t.Fatal("Should have returned true") 640 } 641 642 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 643 t.Fatal("Should have returned true") 644 } 645 646 // WHEN default is MENTION and channel is ALL 647 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION 648 user.NotifyProps = userNotifyProps 649 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL 650 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 651 t.Fatal("Should have returned true") 652 } 653 654 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 655 t.Fatal("Should have returned true") 656 } 657 658 // WHEN default is NONE and channel is ALL 659 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE 660 user.NotifyProps = userNotifyProps 661 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL 662 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 663 t.Fatal("Should have returned true") 664 } 665 666 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 667 t.Fatal("Should have returned true") 668 } 669 670 // WHEN default is ALL and channel is MENTION 671 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL 672 user.NotifyProps = userNotifyProps 673 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION 674 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 675 t.Fatal("Should have returned false") 676 } 677 678 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 679 t.Fatal("Should have returned true") 680 } 681 682 // WHEN default is MENTION and channel is MENTION 683 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION 684 user.NotifyProps = userNotifyProps 685 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION 686 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 687 t.Fatal("Should have returned false") 688 } 689 690 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 691 t.Fatal("Should have returned true") 692 } 693 694 // WHEN default is NONE and channel is MENTION 695 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE 696 user.NotifyProps = userNotifyProps 697 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION 698 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 699 t.Fatal("Should have returned false") 700 } 701 702 if !DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 703 t.Fatal("Should have returned true") 704 } 705 706 // WHEN default is ALL and channel is NONE 707 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_ALL 708 user.NotifyProps = userNotifyProps 709 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_NONE 710 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 711 t.Fatal("Should have returned false") 712 } 713 714 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 715 t.Fatal("Should have returned false") 716 } 717 718 // WHEN default is MENTION and channel is NONE 719 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_MENTION 720 user.NotifyProps = userNotifyProps 721 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_NONE 722 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 723 t.Fatal("Should have returned false") 724 } 725 726 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 727 t.Fatal("Should have returned false") 728 } 729 730 // WHEN default is NONE and channel is NONE 731 userNotifyProps[model.PUSH_NOTIFY_PROP] = model.USER_NOTIFY_NONE 732 user.NotifyProps = userNotifyProps 733 channelNotifyProps[model.PUSH_NOTIFY_PROP] = model.CHANNEL_NOTIFY_NONE 734 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, false) { 735 t.Fatal("Should have returned false") 736 } 737 738 if DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, true) { 739 t.Fatal("Should have returned false") 740 } 741 } 742 743 func TestDoesStatusAllowPushNotification(t *testing.T) { 744 userNotifyProps := make(map[string]string) 745 userId := model.NewId() 746 channelId := model.NewId() 747 748 offline := &model.Status{UserId: userId, Status: model.STATUS_OFFLINE, Manual: false, LastActivityAt: 0, ActiveChannel: ""} 749 away := &model.Status{UserId: userId, Status: model.STATUS_AWAY, Manual: false, LastActivityAt: 0, ActiveChannel: ""} 750 online := &model.Status{UserId: userId, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: ""} 751 dnd := &model.Status{UserId: userId, Status: model.STATUS_DND, Manual: true, LastActivityAt: model.GetMillis(), ActiveChannel: ""} 752 753 userNotifyProps["push_status"] = model.STATUS_ONLINE 754 // WHEN props is ONLINE and user is offline 755 if !DoesStatusAllowPushNotification(userNotifyProps, offline, channelId) { 756 t.Fatal("Should have been true") 757 } 758 759 if !DoesStatusAllowPushNotification(userNotifyProps, offline, "") { 760 t.Fatal("Should have been true") 761 } 762 763 // WHEN props is ONLINE and user is away 764 if !DoesStatusAllowPushNotification(userNotifyProps, away, channelId) { 765 t.Fatal("Should have been true") 766 } 767 768 if !DoesStatusAllowPushNotification(userNotifyProps, away, "") { 769 t.Fatal("Should have been true") 770 } 771 772 // WHEN props is ONLINE and user is online 773 if !DoesStatusAllowPushNotification(userNotifyProps, online, channelId) { 774 t.Fatal("Should have been true") 775 } 776 777 if DoesStatusAllowPushNotification(userNotifyProps, online, "") { 778 t.Fatal("Should have been false") 779 } 780 781 // WHEN props is ONLINE and user is dnd 782 if DoesStatusAllowPushNotification(userNotifyProps, dnd, channelId) { 783 t.Fatal("Should have been false") 784 } 785 786 if DoesStatusAllowPushNotification(userNotifyProps, dnd, "") { 787 t.Fatal("Should have been false") 788 } 789 790 userNotifyProps["push_status"] = model.STATUS_AWAY 791 // WHEN props is AWAY and user is offline 792 if !DoesStatusAllowPushNotification(userNotifyProps, offline, channelId) { 793 t.Fatal("Should have been true") 794 } 795 796 if !DoesStatusAllowPushNotification(userNotifyProps, offline, "") { 797 t.Fatal("Should have been true") 798 } 799 800 // WHEN props is AWAY and user is away 801 if !DoesStatusAllowPushNotification(userNotifyProps, away, channelId) { 802 t.Fatal("Should have been true") 803 } 804 805 if !DoesStatusAllowPushNotification(userNotifyProps, away, "") { 806 t.Fatal("Should have been true") 807 } 808 809 // WHEN props is AWAY and user is online 810 if DoesStatusAllowPushNotification(userNotifyProps, online, channelId) { 811 t.Fatal("Should have been false") 812 } 813 814 if DoesStatusAllowPushNotification(userNotifyProps, online, "") { 815 t.Fatal("Should have been false") 816 } 817 818 // WHEN props is AWAY and user is dnd 819 if DoesStatusAllowPushNotification(userNotifyProps, dnd, channelId) { 820 t.Fatal("Should have been false") 821 } 822 823 if DoesStatusAllowPushNotification(userNotifyProps, dnd, "") { 824 t.Fatal("Should have been false") 825 } 826 827 userNotifyProps["push_status"] = model.STATUS_OFFLINE 828 // WHEN props is OFFLINE and user is offline 829 if !DoesStatusAllowPushNotification(userNotifyProps, offline, channelId) { 830 t.Fatal("Should have been true") 831 } 832 833 if !DoesStatusAllowPushNotification(userNotifyProps, offline, "") { 834 t.Fatal("Should have been true") 835 } 836 837 // WHEN props is OFFLINE and user is away 838 if DoesStatusAllowPushNotification(userNotifyProps, away, channelId) { 839 t.Fatal("Should have been false") 840 } 841 842 if DoesStatusAllowPushNotification(userNotifyProps, away, "") { 843 t.Fatal("Should have been false") 844 } 845 846 // WHEN props is OFFLINE and user is online 847 if DoesStatusAllowPushNotification(userNotifyProps, online, channelId) { 848 t.Fatal("Should have been false") 849 } 850 851 if DoesStatusAllowPushNotification(userNotifyProps, online, "") { 852 t.Fatal("Should have been false") 853 } 854 855 // WHEN props is OFFLINE and user is dnd 856 if DoesStatusAllowPushNotification(userNotifyProps, dnd, channelId) { 857 t.Fatal("Should have been false") 858 } 859 860 if DoesStatusAllowPushNotification(userNotifyProps, dnd, "") { 861 t.Fatal("Should have been false") 862 } 863 864 } 865 866 func TestGetDirectMessageNotificationEmailSubject(t *testing.T) { 867 th := Setup() 868 defer th.TearDown() 869 870 expectedPrefix := "[http://localhost:8065] New Direct Message from sender on" 871 post := &model.Post{ 872 CreateAt: 1501804801000, 873 } 874 translateFunc := utils.GetUserTranslations("en") 875 subject := getDirectMessageNotificationEmailSubject(post, translateFunc, "http://localhost:8065", "sender") 876 if !strings.HasPrefix(subject, expectedPrefix) { 877 t.Fatal("Expected subject line prefix '" + expectedPrefix + "', got " + subject) 878 } 879 } 880 881 func TestGetNotificationEmailSubject(t *testing.T) { 882 th := Setup() 883 defer th.TearDown() 884 885 expectedPrefix := "[http://localhost:8065] Notification in team on" 886 post := &model.Post{ 887 CreateAt: 1501804801000, 888 } 889 translateFunc := utils.GetUserTranslations("en") 890 subject := getNotificationEmailSubject(post, translateFunc, "http://localhost:8065", "team") 891 if !strings.HasPrefix(subject, expectedPrefix) { 892 t.Fatal("Expected subject line prefix '" + expectedPrefix + "', got " + subject) 893 } 894 } 895 896 func TestGetNotificationEmailBodyFullNotificationPublicChannel(t *testing.T) { 897 th := Setup() 898 defer th.TearDown() 899 900 recipient := &model.User{} 901 post := &model.Post{ 902 Message: "This is the message", 903 } 904 channel := &model.Channel{ 905 DisplayName: "ChannelName", 906 Type: model.CHANNEL_OPEN, 907 } 908 senderName := "sender" 909 teamName := "team" 910 teamURL := "http://localhost:8065/" + teamName 911 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL 912 translateFunc := utils.GetUserTranslations("en") 913 914 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 915 if !strings.Contains(body, "You have a new notification.") { 916 t.Fatal("Expected email text 'You have a new notification. Got " + body) 917 } 918 if !strings.Contains(body, "CHANNEL: "+channel.DisplayName) { 919 t.Fatal("Expected email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body) 920 } 921 if !strings.Contains(body, senderName+" - ") { 922 t.Fatal("Expected email text '" + senderName + " - '. Got " + body) 923 } 924 if !strings.Contains(body, post.Message) { 925 t.Fatal("Expected email text '" + post.Message + "'. Got " + body) 926 } 927 if !strings.Contains(body, teamURL) { 928 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 929 } 930 } 931 932 func TestGetNotificationEmailBodyFullNotificationGroupChannel(t *testing.T) { 933 th := Setup() 934 defer th.TearDown() 935 936 recipient := &model.User{} 937 post := &model.Post{ 938 Message: "This is the message", 939 } 940 channel := &model.Channel{ 941 DisplayName: "ChannelName", 942 Type: model.CHANNEL_GROUP, 943 } 944 senderName := "sender" 945 teamName := "team" 946 teamURL := "http://localhost:8065/" + teamName 947 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL 948 translateFunc := utils.GetUserTranslations("en") 949 950 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 951 if !strings.Contains(body, "You have a new notification.") { 952 t.Fatal("Expected email text 'You have a new notification. Got " + body) 953 } 954 if !strings.Contains(body, "CHANNEL: Group Message") { 955 t.Fatal("Expected email text 'CHANNEL: Group Message'. Got " + body) 956 } 957 if !strings.Contains(body, senderName+" - ") { 958 t.Fatal("Expected email text '" + senderName + " - '. Got " + body) 959 } 960 if !strings.Contains(body, post.Message) { 961 t.Fatal("Expected email text '" + post.Message + "'. Got " + body) 962 } 963 if !strings.Contains(body, teamURL) { 964 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 965 } 966 } 967 968 func TestGetNotificationEmailBodyFullNotificationPrivateChannel(t *testing.T) { 969 th := Setup() 970 defer th.TearDown() 971 972 recipient := &model.User{} 973 post := &model.Post{ 974 Message: "This is the message", 975 } 976 channel := &model.Channel{ 977 DisplayName: "ChannelName", 978 Type: model.CHANNEL_PRIVATE, 979 } 980 senderName := "sender" 981 teamName := "team" 982 teamURL := "http://localhost:8065/" + teamName 983 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL 984 translateFunc := utils.GetUserTranslations("en") 985 986 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 987 if !strings.Contains(body, "You have a new notification.") { 988 t.Fatal("Expected email text 'You have a new notification. Got " + body) 989 } 990 if !strings.Contains(body, "CHANNEL: "+channel.DisplayName) { 991 t.Fatal("Expected email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body) 992 } 993 if !strings.Contains(body, senderName+" - ") { 994 t.Fatal("Expected email text '" + senderName + " - '. Got " + body) 995 } 996 if !strings.Contains(body, post.Message) { 997 t.Fatal("Expected email text '" + post.Message + "'. Got " + body) 998 } 999 if !strings.Contains(body, teamURL) { 1000 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 1001 } 1002 } 1003 1004 func TestGetNotificationEmailBodyFullNotificationDirectChannel(t *testing.T) { 1005 th := Setup() 1006 defer th.TearDown() 1007 1008 recipient := &model.User{} 1009 post := &model.Post{ 1010 Message: "This is the message", 1011 } 1012 channel := &model.Channel{ 1013 DisplayName: "ChannelName", 1014 Type: model.CHANNEL_DIRECT, 1015 } 1016 senderName := "sender" 1017 teamName := "team" 1018 teamURL := "http://localhost:8065/" + teamName 1019 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL 1020 translateFunc := utils.GetUserTranslations("en") 1021 1022 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 1023 if !strings.Contains(body, "You have a new direct message.") { 1024 t.Fatal("Expected email text 'You have a new direct message. Got " + body) 1025 } 1026 if !strings.Contains(body, senderName+" - ") { 1027 t.Fatal("Expected email text '" + senderName + " - '. Got " + body) 1028 } 1029 if !strings.Contains(body, post.Message) { 1030 t.Fatal("Expected email text '" + post.Message + "'. Got " + body) 1031 } 1032 if !strings.Contains(body, teamURL) { 1033 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 1034 } 1035 } 1036 1037 // from here 1038 func TestGetNotificationEmailBodyGenericNotificationPublicChannel(t *testing.T) { 1039 th := Setup() 1040 defer th.TearDown() 1041 1042 recipient := &model.User{} 1043 post := &model.Post{ 1044 Message: "This is the message", 1045 } 1046 channel := &model.Channel{ 1047 DisplayName: "ChannelName", 1048 Type: model.CHANNEL_OPEN, 1049 } 1050 senderName := "sender" 1051 teamName := "team" 1052 teamURL := "http://localhost:8065/" + teamName 1053 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC 1054 translateFunc := utils.GetUserTranslations("en") 1055 1056 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 1057 if !strings.Contains(body, "You have a new notification from "+senderName) { 1058 t.Fatal("Expected email text 'You have a new notification from " + senderName + "'. Got " + body) 1059 } 1060 if strings.Contains(body, "CHANNEL: "+channel.DisplayName) { 1061 t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body) 1062 } 1063 if strings.Contains(body, post.Message) { 1064 t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body) 1065 } 1066 if !strings.Contains(body, teamURL) { 1067 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 1068 } 1069 } 1070 1071 func TestGetNotificationEmailBodyGenericNotificationGroupChannel(t *testing.T) { 1072 th := Setup() 1073 defer th.TearDown() 1074 1075 recipient := &model.User{} 1076 post := &model.Post{ 1077 Message: "This is the message", 1078 } 1079 channel := &model.Channel{ 1080 DisplayName: "ChannelName", 1081 Type: model.CHANNEL_GROUP, 1082 } 1083 senderName := "sender" 1084 teamName := "team" 1085 teamURL := "http://localhost:8065/" + teamName 1086 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC 1087 translateFunc := utils.GetUserTranslations("en") 1088 1089 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 1090 if !strings.Contains(body, "You have a new notification from "+senderName) { 1091 t.Fatal("Expected email text 'You have a new notification from " + senderName + "'. Got " + body) 1092 } 1093 if strings.Contains(body, "CHANNEL: "+channel.DisplayName) { 1094 t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body) 1095 } 1096 if strings.Contains(body, post.Message) { 1097 t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body) 1098 } 1099 if !strings.Contains(body, teamURL) { 1100 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 1101 } 1102 } 1103 1104 func TestGetNotificationEmailBodyGenericNotificationPrivateChannel(t *testing.T) { 1105 th := Setup() 1106 defer th.TearDown() 1107 1108 recipient := &model.User{} 1109 post := &model.Post{ 1110 Message: "This is the message", 1111 } 1112 channel := &model.Channel{ 1113 DisplayName: "ChannelName", 1114 Type: model.CHANNEL_PRIVATE, 1115 } 1116 senderName := "sender" 1117 teamName := "team" 1118 teamURL := "http://localhost:8065/" + teamName 1119 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC 1120 translateFunc := utils.GetUserTranslations("en") 1121 1122 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 1123 if !strings.Contains(body, "You have a new notification from "+senderName) { 1124 t.Fatal("Expected email text 'You have a new notification from " + senderName + "'. Got " + body) 1125 } 1126 if strings.Contains(body, "CHANNEL: "+channel.DisplayName) { 1127 t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body) 1128 } 1129 if strings.Contains(body, post.Message) { 1130 t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body) 1131 } 1132 if !strings.Contains(body, teamURL) { 1133 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 1134 } 1135 } 1136 1137 func TestGetNotificationEmailBodyGenericNotificationDirectChannel(t *testing.T) { 1138 th := Setup() 1139 defer th.TearDown() 1140 1141 recipient := &model.User{} 1142 post := &model.Post{ 1143 Message: "This is the message", 1144 } 1145 channel := &model.Channel{ 1146 DisplayName: "ChannelName", 1147 Type: model.CHANNEL_DIRECT, 1148 } 1149 senderName := "sender" 1150 teamName := "team" 1151 teamURL := "http://localhost:8065/" + teamName 1152 emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC 1153 translateFunc := utils.GetUserTranslations("en") 1154 1155 body := th.App.getNotificationEmailBody(recipient, post, channel, senderName, teamName, teamURL, emailNotificationContentsType, translateFunc) 1156 if !strings.Contains(body, "You have a new direct message from "+senderName) { 1157 t.Fatal("Expected email text 'You have a new direct message from " + senderName + "'. Got " + body) 1158 } 1159 if strings.Contains(body, "CHANNEL: "+channel.DisplayName) { 1160 t.Fatal("Did not expect email text 'CHANNEL: " + channel.DisplayName + "'. Got " + body) 1161 } 1162 if strings.Contains(body, post.Message) { 1163 t.Fatal("Did not expect email text '" + post.Message + "'. Got " + body) 1164 } 1165 if !strings.Contains(body, teamURL) { 1166 t.Fatal("Expected email text '" + teamURL + "'. Got " + body) 1167 } 1168 }