github.com/spline-fu/mattermost-server@v4.10.10+incompatible/app/import_test.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "path/filepath" 8 "runtime/debug" 9 "strings" 10 "testing" 11 12 "github.com/mattermost/mattermost-server/model" 13 "github.com/mattermost/mattermost-server/store" 14 "github.com/mattermost/mattermost-server/utils" 15 ) 16 17 func ptrStr(s string) *string { 18 return &s 19 } 20 21 func ptrInt64(i int64) *int64 { 22 return &i 23 } 24 25 func ptrInt(i int) *int { 26 return &i 27 } 28 29 func ptrBool(b bool) *bool { 30 return &b 31 } 32 33 func checkPreference(t *testing.T, a *App, userId string, category string, name string, value string) { 34 if res := <-a.Srv.Store.Preference().GetCategory(userId, category); res.Err != nil { 35 debug.PrintStack() 36 t.Fatalf("Failed to get preferences for user %v with category %v", userId, category) 37 } else { 38 preferences := res.Data.(model.Preferences) 39 found := false 40 for _, preference := range preferences { 41 if preference.Name == name { 42 found = true 43 if preference.Value != value { 44 debug.PrintStack() 45 t.Fatalf("Preference for user %v in category %v with name %v has value %v, expected %v", userId, category, name, preference.Value, value) 46 } 47 break 48 } 49 } 50 if !found { 51 debug.PrintStack() 52 t.Fatalf("Did not find preference for user %v in category %v with name %v", userId, category, name) 53 } 54 } 55 } 56 57 func checkNotifyProp(t *testing.T, user *model.User, key string, value string) { 58 if actual, ok := user.NotifyProps[key]; !ok { 59 debug.PrintStack() 60 t.Fatalf("Notify prop %v not found. User: %v", key, user.Id) 61 } else if actual != value { 62 debug.PrintStack() 63 t.Fatalf("Notify Prop %v was %v but expected %v. User: %v", key, actual, value, user.Id) 64 } 65 } 66 67 func checkError(t *testing.T, err *model.AppError) { 68 if err == nil { 69 debug.PrintStack() 70 t.Fatal("Should have returned an error.") 71 } 72 } 73 74 func checkNoError(t *testing.T, err *model.AppError) { 75 if err != nil { 76 debug.PrintStack() 77 t.Fatalf("Unexpected Error: %v", err.Error()) 78 } 79 } 80 81 func TestImportValidateTeamImportData(t *testing.T) { 82 83 // Test with minimum required valid properties. 84 data := TeamImportData{ 85 Name: ptrStr("teamname"), 86 DisplayName: ptrStr("Display Name"), 87 Type: ptrStr("O"), 88 } 89 if err := validateTeamImportData(&data); err != nil { 90 t.Fatal("Validation failed but should have been valid.") 91 } 92 93 // Test with various invalid names. 94 data = TeamImportData{ 95 DisplayName: ptrStr("Display Name"), 96 Type: ptrStr("O"), 97 } 98 if err := validateTeamImportData(&data); err == nil { 99 t.Fatal("Should have failed due to missing name.") 100 } 101 102 data.Name = ptrStr(strings.Repeat("abcdefghij", 7)) 103 if err := validateTeamImportData(&data); err == nil { 104 t.Fatal("Should have failed due to too long name.") 105 } 106 107 data.Name = ptrStr("login") 108 if err := validateTeamImportData(&data); err == nil { 109 t.Fatal("Should have failed due to reserved word in name.") 110 } 111 112 data.Name = ptrStr("Test::''ASD") 113 if err := validateTeamImportData(&data); err == nil { 114 t.Fatal("Should have failed due to non alphanum characters in name.") 115 } 116 117 data.Name = ptrStr("A") 118 if err := validateTeamImportData(&data); err == nil { 119 t.Fatal("Should have failed due to short name.") 120 } 121 122 // Test team various invalid display names. 123 data = TeamImportData{ 124 Name: ptrStr("teamname"), 125 Type: ptrStr("O"), 126 } 127 if err := validateTeamImportData(&data); err == nil { 128 t.Fatal("Should have failed due to missing display_name.") 129 } 130 131 data.DisplayName = ptrStr("") 132 if err := validateTeamImportData(&data); err == nil { 133 t.Fatal("Should have failed due to empty display_name.") 134 } 135 136 data.DisplayName = ptrStr(strings.Repeat("abcdefghij", 7)) 137 if err := validateTeamImportData(&data); err == nil { 138 t.Fatal("Should have failed due to too long display_name.") 139 } 140 141 // Test with various valid and invalid types. 142 data = TeamImportData{ 143 Name: ptrStr("teamname"), 144 DisplayName: ptrStr("Display Name"), 145 } 146 if err := validateTeamImportData(&data); err == nil { 147 t.Fatal("Should have failed due to missing type.") 148 } 149 150 data.Type = ptrStr("A") 151 if err := validateTeamImportData(&data); err == nil { 152 t.Fatal("Should have failed due to invalid type.") 153 } 154 155 data.Type = ptrStr("I") 156 if err := validateTeamImportData(&data); err != nil { 157 t.Fatal("Should have succeeded with valid type.") 158 } 159 160 // Test with all the combinations of optional parameters. 161 data = TeamImportData{ 162 Name: ptrStr("teamname"), 163 DisplayName: ptrStr("Display Name"), 164 Type: ptrStr("O"), 165 Description: ptrStr("The team description."), 166 AllowOpenInvite: ptrBool(true), 167 } 168 if err := validateTeamImportData(&data); err != nil { 169 t.Fatal("Should have succeeded with valid optional properties.") 170 } 171 172 data.AllowOpenInvite = ptrBool(false) 173 if err := validateTeamImportData(&data); err != nil { 174 t.Fatal("Should have succeeded with allow open invites false.") 175 } 176 177 data.Description = ptrStr(strings.Repeat("abcdefghij ", 26)) 178 if err := validateTeamImportData(&data); err == nil { 179 t.Fatal("Should have failed due to too long description.") 180 } 181 } 182 183 func TestImportValidateChannelImportData(t *testing.T) { 184 185 // Test with minimum required valid properties. 186 data := ChannelImportData{ 187 Team: ptrStr("teamname"), 188 Name: ptrStr("channelname"), 189 DisplayName: ptrStr("Display Name"), 190 Type: ptrStr("O"), 191 } 192 if err := validateChannelImportData(&data); err != nil { 193 t.Fatal("Validation failed but should have been valid.") 194 } 195 196 // Test with missing team. 197 data = ChannelImportData{ 198 Name: ptrStr("channelname"), 199 DisplayName: ptrStr("Display Name"), 200 Type: ptrStr("O"), 201 } 202 if err := validateChannelImportData(&data); err == nil { 203 t.Fatal("Should have failed due to missing team.") 204 } 205 206 // Test with various invalid names. 207 data = ChannelImportData{ 208 Team: ptrStr("teamname"), 209 DisplayName: ptrStr("Display Name"), 210 Type: ptrStr("O"), 211 } 212 if err := validateChannelImportData(&data); err == nil { 213 t.Fatal("Should have failed due to missing name.") 214 } 215 216 data.Name = ptrStr(strings.Repeat("abcdefghij", 7)) 217 if err := validateChannelImportData(&data); err == nil { 218 t.Fatal("Should have failed due to too long name.") 219 } 220 221 data.Name = ptrStr("Test::''ASD") 222 if err := validateChannelImportData(&data); err == nil { 223 t.Fatal("Should have failed due to non alphanum characters in name.") 224 } 225 226 data.Name = ptrStr("A") 227 if err := validateChannelImportData(&data); err == nil { 228 t.Fatal("Should have failed due to short name.") 229 } 230 231 // Test team various invalid display names. 232 data = ChannelImportData{ 233 Team: ptrStr("teamname"), 234 Name: ptrStr("channelname"), 235 Type: ptrStr("O"), 236 } 237 if err := validateChannelImportData(&data); err == nil { 238 t.Fatal("Should have failed due to missing display_name.") 239 } 240 241 data.DisplayName = ptrStr("") 242 if err := validateChannelImportData(&data); err == nil { 243 t.Fatal("Should have failed due to empty display_name.") 244 } 245 246 data.DisplayName = ptrStr(strings.Repeat("abcdefghij", 7)) 247 if err := validateChannelImportData(&data); err == nil { 248 t.Fatal("Should have failed due to too long display_name.") 249 } 250 251 // Test with various valid and invalid types. 252 data = ChannelImportData{ 253 Team: ptrStr("teamname"), 254 Name: ptrStr("channelname"), 255 DisplayName: ptrStr("Display Name"), 256 } 257 if err := validateChannelImportData(&data); err == nil { 258 t.Fatal("Should have failed due to missing type.") 259 } 260 261 data.Type = ptrStr("A") 262 if err := validateChannelImportData(&data); err == nil { 263 t.Fatal("Should have failed due to invalid type.") 264 } 265 266 data.Type = ptrStr("P") 267 if err := validateChannelImportData(&data); err != nil { 268 t.Fatal("Should have succeeded with valid type.") 269 } 270 271 // Test with all the combinations of optional parameters. 272 data = ChannelImportData{ 273 Team: ptrStr("teamname"), 274 Name: ptrStr("channelname"), 275 DisplayName: ptrStr("Display Name"), 276 Type: ptrStr("O"), 277 Header: ptrStr("Channel Header Here"), 278 Purpose: ptrStr("Channel Purpose Here"), 279 } 280 if err := validateChannelImportData(&data); err != nil { 281 t.Fatal("Should have succeeded with valid optional properties.") 282 } 283 284 data.Header = ptrStr(strings.Repeat("abcdefghij ", 103)) 285 if err := validateChannelImportData(&data); err == nil { 286 t.Fatal("Should have failed due to too long header.") 287 } 288 289 data.Header = ptrStr("Channel Header Here") 290 data.Purpose = ptrStr(strings.Repeat("abcdefghij ", 26)) 291 if err := validateChannelImportData(&data); err == nil { 292 t.Fatal("Should have failed due to too long purpose.") 293 } 294 } 295 296 func TestImportValidateUserImportData(t *testing.T) { 297 298 // Test with minimum required valid properties. 299 data := UserImportData{ 300 Username: ptrStr("bob"), 301 Email: ptrStr("bob@example.com"), 302 } 303 if err := validateUserImportData(&data); err != nil { 304 t.Fatal("Validation failed but should have been valid.") 305 } 306 307 // Invalid Usernames. 308 data.Username = nil 309 if err := validateUserImportData(&data); err == nil { 310 t.Fatal("Validation should have failed due to nil Username.") 311 } 312 313 data.Username = ptrStr("") 314 if err := validateUserImportData(&data); err == nil { 315 t.Fatal("Validation should have failed due to 0 length Username.") 316 } 317 318 data.Username = ptrStr(strings.Repeat("abcdefghij", 7)) 319 if err := validateUserImportData(&data); err == nil { 320 t.Fatal("Validation should have failed due to too long Username.") 321 } 322 323 data.Username = ptrStr("i am a username with spaces and !!!") 324 if err := validateUserImportData(&data); err == nil { 325 t.Fatal("Validation should have failed due to invalid characters in Username.") 326 } 327 328 data.Username = ptrStr("bob") 329 330 // Unexisting Picture Image 331 data.ProfileImage = ptrStr("not-existing-file") 332 if err := validateUserImportData(&data); err == nil { 333 t.Fatal("Validation should have failed due to not existing profile image file.") 334 } 335 data.ProfileImage = nil 336 337 // Invalid Emails 338 data.Email = nil 339 if err := validateUserImportData(&data); err == nil { 340 t.Fatal("Validation should have failed due to nil Email.") 341 } 342 343 data.Email = ptrStr("") 344 if err := validateUserImportData(&data); err == nil { 345 t.Fatal("Validation should have failed due to 0 length Email.") 346 } 347 348 data.Email = ptrStr(strings.Repeat("abcdefghij", 13)) 349 if err := validateUserImportData(&data); err == nil { 350 t.Fatal("Validation should have failed due to too long Email.") 351 } 352 353 data.Email = ptrStr("bob@example.com") 354 355 data.AuthService = ptrStr("") 356 if err := validateUserImportData(&data); err == nil { 357 t.Fatal("Validation should have failed due to 0-length auth service.") 358 } 359 360 data.AuthService = ptrStr("saml") 361 data.AuthData = ptrStr(strings.Repeat("abcdefghij", 15)) 362 if err := validateUserImportData(&data); err == nil { 363 t.Fatal("Validation should have failed due to too long auth data.") 364 } 365 366 data.AuthData = ptrStr("bobbytables") 367 if err := validateUserImportData(&data); err != nil { 368 t.Fatal("Validation should have succeeded with valid auth service and auth data.") 369 } 370 371 // Test a valid User with all fields populated. 372 testsDir, _ := utils.FindDir("tests") 373 data = UserImportData{ 374 ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")), 375 Username: ptrStr("bob"), 376 Email: ptrStr("bob@example.com"), 377 AuthService: ptrStr("ldap"), 378 AuthData: ptrStr("bob"), 379 Nickname: ptrStr("BobNick"), 380 FirstName: ptrStr("Bob"), 381 LastName: ptrStr("Blob"), 382 Position: ptrStr("The Boss"), 383 Roles: ptrStr("system_user"), 384 Locale: ptrStr("en"), 385 } 386 if err := validateUserImportData(&data); err != nil { 387 t.Fatal("Validation failed but should have been valid.") 388 } 389 390 // Test various invalid optional field values. 391 data.Nickname = ptrStr(strings.Repeat("abcdefghij", 7)) 392 if err := validateUserImportData(&data); err == nil { 393 t.Fatal("Validation should have failed due to too long Nickname.") 394 } 395 data.Nickname = ptrStr("BobNick") 396 397 data.FirstName = ptrStr(strings.Repeat("abcdefghij", 7)) 398 if err := validateUserImportData(&data); err == nil { 399 t.Fatal("Validation should have failed due to too long First Name.") 400 } 401 data.FirstName = ptrStr("Bob") 402 403 data.LastName = ptrStr(strings.Repeat("abcdefghij", 7)) 404 if err := validateUserImportData(&data); err == nil { 405 t.Fatal("Validation should have failed due to too long Last name.") 406 } 407 data.LastName = ptrStr("Blob") 408 409 data.Position = ptrStr(strings.Repeat("abcdefghij", 13)) 410 if err := validateUserImportData(&data); err == nil { 411 t.Fatal("Validation should have failed due to too long Position.") 412 } 413 data.Position = ptrStr("The Boss") 414 415 data.Roles = nil 416 if err := validateUserImportData(&data); err != nil { 417 t.Fatal("Validation failed but should have been valid.") 418 } 419 420 data.Roles = ptrStr("") 421 if err := validateUserImportData(&data); err != nil { 422 t.Fatal("Validation failed but should have been valid.") 423 } 424 data.Roles = ptrStr("system_user") 425 426 // Try various valid/invalid notify props. 427 data.NotifyProps = &UserNotifyPropsImportData{} 428 429 data.NotifyProps.Desktop = ptrStr("invalid") 430 checkError(t, validateUserImportData(&data)) 431 432 data.NotifyProps.Desktop = ptrStr(model.USER_NOTIFY_ALL) 433 data.NotifyProps.DesktopDuration = ptrStr("invalid") 434 checkError(t, validateUserImportData(&data)) 435 436 data.NotifyProps.DesktopDuration = ptrStr("5") 437 data.NotifyProps.DesktopSound = ptrStr("invalid") 438 checkError(t, validateUserImportData(&data)) 439 440 data.NotifyProps.DesktopSound = ptrStr("true") 441 data.NotifyProps.Email = ptrStr("invalid") 442 checkError(t, validateUserImportData(&data)) 443 444 data.NotifyProps.Email = ptrStr("true") 445 data.NotifyProps.Mobile = ptrStr("invalid") 446 checkError(t, validateUserImportData(&data)) 447 448 data.NotifyProps.Mobile = ptrStr(model.USER_NOTIFY_ALL) 449 data.NotifyProps.MobilePushStatus = ptrStr("invalid") 450 checkError(t, validateUserImportData(&data)) 451 452 data.NotifyProps.MobilePushStatus = ptrStr(model.STATUS_ONLINE) 453 data.NotifyProps.ChannelTrigger = ptrStr("invalid") 454 checkError(t, validateUserImportData(&data)) 455 456 data.NotifyProps.ChannelTrigger = ptrStr("true") 457 data.NotifyProps.CommentsTrigger = ptrStr("invalid") 458 checkError(t, validateUserImportData(&data)) 459 460 data.NotifyProps.CommentsTrigger = ptrStr(model.COMMENTS_NOTIFY_ROOT) 461 data.NotifyProps.MentionKeys = ptrStr("valid") 462 checkNoError(t, validateUserImportData(&data)) 463 } 464 465 func TestImportValidateUserTeamsImportData(t *testing.T) { 466 467 // Invalid Name. 468 data := []UserTeamImportData{ 469 { 470 Roles: ptrStr("team_admin team_user"), 471 }, 472 } 473 if err := validateUserTeamsImportData(&data); err == nil { 474 t.Fatal("Should have failed due to invalid name.") 475 } 476 data[0].Name = ptrStr("teamname") 477 478 // Valid (nil roles) 479 data[0].Roles = nil 480 if err := validateUserTeamsImportData(&data); err != nil { 481 t.Fatal("Should have succeeded with empty roles.") 482 } 483 484 // Valid (empty roles) 485 data[0].Roles = ptrStr("") 486 if err := validateUserTeamsImportData(&data); err != nil { 487 t.Fatal("Should have succeeded with empty roles.") 488 } 489 490 // Valid (with roles) 491 data[0].Roles = ptrStr("team_admin team_user") 492 if err := validateUserTeamsImportData(&data); err != nil { 493 t.Fatal("Should have succeeded with valid roles.") 494 } 495 } 496 497 func TestImportValidateUserChannelsImportData(t *testing.T) { 498 499 // Invalid Name. 500 data := []UserChannelImportData{ 501 { 502 Roles: ptrStr("channel_admin channel_user"), 503 }, 504 } 505 if err := validateUserChannelsImportData(&data); err == nil { 506 t.Fatal("Should have failed due to invalid name.") 507 } 508 data[0].Name = ptrStr("channelname") 509 510 // Valid (nil roles) 511 data[0].Roles = nil 512 if err := validateUserChannelsImportData(&data); err != nil { 513 t.Fatal("Should have succeeded with empty roles.") 514 } 515 516 // Valid (empty roles) 517 data[0].Roles = ptrStr("") 518 if err := validateUserChannelsImportData(&data); err != nil { 519 t.Fatal("Should have succeeded with empty roles.") 520 } 521 522 // Valid (with roles) 523 data[0].Roles = ptrStr("channel_admin channel_user") 524 if err := validateUserChannelsImportData(&data); err != nil { 525 t.Fatal("Should have succeeded with valid roles.") 526 } 527 528 // Empty notify props. 529 data[0].NotifyProps = &UserChannelNotifyPropsImportData{} 530 if err := validateUserChannelsImportData(&data); err != nil { 531 t.Fatal("Should have succeeded with empty notify props.") 532 } 533 534 // Invalid desktop notify props. 535 data[0].NotifyProps.Desktop = ptrStr("invalid") 536 if err := validateUserChannelsImportData(&data); err == nil { 537 t.Fatal("Should have failed with invalid desktop notify props.") 538 } 539 540 // Invalid mobile notify props. 541 data[0].NotifyProps.Desktop = ptrStr("mention") 542 data[0].NotifyProps.Mobile = ptrStr("invalid") 543 if err := validateUserChannelsImportData(&data); err == nil { 544 t.Fatal("Should have failed with invalid mobile notify props.") 545 } 546 547 // Invalid mark_unread notify props. 548 data[0].NotifyProps.Mobile = ptrStr("mention") 549 data[0].NotifyProps.MarkUnread = ptrStr("invalid") 550 if err := validateUserChannelsImportData(&data); err == nil { 551 t.Fatal("Should have failed with invalid mark_unread notify props.") 552 } 553 554 // Valid notify props. 555 data[0].NotifyProps.MarkUnread = ptrStr("mention") 556 if err := validateUserChannelsImportData(&data); err != nil { 557 t.Fatal("Should have succeeded with valid notify props.") 558 } 559 } 560 561 func TestImportValidateReactionImportData(t *testing.T) { 562 // Test with minimum required valid properties. 563 parentCreateAt := model.GetMillis() - 100 564 data := ReactionImportData{ 565 User: ptrStr("username"), 566 EmojiName: ptrStr("emoji"), 567 CreateAt: ptrInt64(model.GetMillis()), 568 } 569 if err := validateReactionImportData(&data, parentCreateAt); err != nil { 570 t.Fatal("Validation failed but should have been valid.") 571 } 572 573 // Test with missing required properties. 574 data = ReactionImportData{ 575 EmojiName: ptrStr("emoji"), 576 CreateAt: ptrInt64(model.GetMillis()), 577 } 578 if err := validateReactionImportData(&data, parentCreateAt); err == nil { 579 t.Fatal("Should have failed due to missing required property.") 580 } 581 582 data = ReactionImportData{ 583 User: ptrStr("username"), 584 CreateAt: ptrInt64(model.GetMillis()), 585 } 586 if err := validateReactionImportData(&data, parentCreateAt); err == nil { 587 t.Fatal("Should have failed due to missing required property.") 588 } 589 590 data = ReactionImportData{ 591 User: ptrStr("username"), 592 EmojiName: ptrStr("emoji"), 593 } 594 if err := validateReactionImportData(&data, parentCreateAt); err == nil { 595 t.Fatal("Should have failed due to missing required property.") 596 } 597 598 // Test with invalid emoji name. 599 data = ReactionImportData{ 600 User: ptrStr("username"), 601 EmojiName: ptrStr(strings.Repeat("1234567890", 500)), 602 CreateAt: ptrInt64(model.GetMillis()), 603 } 604 if err := validateReactionImportData(&data, parentCreateAt); err == nil { 605 t.Fatal("Should have failed due to too long emoji name.") 606 } 607 608 // Test with invalid CreateAt 609 data = ReactionImportData{ 610 User: ptrStr("username"), 611 EmojiName: ptrStr("emoji"), 612 CreateAt: ptrInt64(0), 613 } 614 if err := validateReactionImportData(&data, parentCreateAt); err == nil { 615 t.Fatal("Should have failed due to 0 create-at value.") 616 } 617 618 data = ReactionImportData{ 619 User: ptrStr("username"), 620 EmojiName: ptrStr("emoji"), 621 CreateAt: ptrInt64(parentCreateAt - 100), 622 } 623 if err := validateReactionImportData(&data, parentCreateAt); err == nil { 624 t.Fatal("Should have failed due parent with newer create-at value.") 625 } 626 } 627 628 func TestImportValidateReplyImportData(t *testing.T) { 629 // Test with minimum required valid properties. 630 parentCreateAt := model.GetMillis() - 100 631 maxPostSize := 10000 632 data := ReplyImportData{ 633 User: ptrStr("username"), 634 Message: ptrStr("message"), 635 CreateAt: ptrInt64(model.GetMillis()), 636 } 637 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err != nil { 638 t.Fatal("Validation failed but should have been valid.") 639 } 640 641 // Test with missing required properties. 642 data = ReplyImportData{ 643 Message: ptrStr("message"), 644 CreateAt: ptrInt64(model.GetMillis()), 645 } 646 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil { 647 t.Fatal("Should have failed due to missing required property.") 648 } 649 650 data = ReplyImportData{ 651 User: ptrStr("username"), 652 CreateAt: ptrInt64(model.GetMillis()), 653 } 654 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil { 655 t.Fatal("Should have failed due to missing required property.") 656 } 657 658 data = ReplyImportData{ 659 User: ptrStr("username"), 660 Message: ptrStr("message"), 661 } 662 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil { 663 t.Fatal("Should have failed due to missing required property.") 664 } 665 666 // Test with invalid message. 667 data = ReplyImportData{ 668 User: ptrStr("username"), 669 Message: ptrStr(strings.Repeat("0", maxPostSize+1)), 670 CreateAt: ptrInt64(model.GetMillis()), 671 } 672 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil { 673 t.Fatal("Should have failed due to too long message.") 674 } 675 676 // Test with invalid CreateAt 677 data = ReplyImportData{ 678 User: ptrStr("username"), 679 Message: ptrStr("message"), 680 CreateAt: ptrInt64(0), 681 } 682 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil { 683 t.Fatal("Should have failed due to 0 create-at value.") 684 } 685 686 data = ReplyImportData{ 687 User: ptrStr("username"), 688 Message: ptrStr("message"), 689 CreateAt: ptrInt64(parentCreateAt - 100), 690 } 691 if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil { 692 t.Fatal("Should have failed due parent with newer create-at value.") 693 } 694 } 695 696 func TestImportValidatePostImportData(t *testing.T) { 697 maxPostSize := 10000 698 699 // Test with minimum required valid properties. 700 data := PostImportData{ 701 Team: ptrStr("teamname"), 702 Channel: ptrStr("channelname"), 703 User: ptrStr("username"), 704 Message: ptrStr("message"), 705 CreateAt: ptrInt64(model.GetMillis()), 706 } 707 if err := validatePostImportData(&data, maxPostSize); err != nil { 708 t.Fatal("Validation failed but should have been valid.") 709 } 710 711 // Test with missing required properties. 712 data = PostImportData{ 713 Channel: ptrStr("channelname"), 714 User: ptrStr("username"), 715 Message: ptrStr("message"), 716 CreateAt: ptrInt64(model.GetMillis()), 717 } 718 if err := validatePostImportData(&data, maxPostSize); err == nil { 719 t.Fatal("Should have failed due to missing required property.") 720 } 721 722 data = PostImportData{ 723 Team: ptrStr("teamname"), 724 User: ptrStr("username"), 725 Message: ptrStr("message"), 726 CreateAt: ptrInt64(model.GetMillis()), 727 } 728 if err := validatePostImportData(&data, maxPostSize); err == nil { 729 t.Fatal("Should have failed due to missing required property.") 730 } 731 732 data = PostImportData{ 733 Team: ptrStr("teamname"), 734 Channel: ptrStr("channelname"), 735 Message: ptrStr("message"), 736 CreateAt: ptrInt64(model.GetMillis()), 737 } 738 if err := validatePostImportData(&data, maxPostSize); err == nil { 739 t.Fatal("Should have failed due to missing required property.") 740 } 741 742 data = PostImportData{ 743 Team: ptrStr("teamname"), 744 Channel: ptrStr("channelname"), 745 User: ptrStr("username"), 746 CreateAt: ptrInt64(model.GetMillis()), 747 } 748 if err := validatePostImportData(&data, maxPostSize); err == nil { 749 t.Fatal("Should have failed due to missing required property.") 750 } 751 752 data = PostImportData{ 753 Team: ptrStr("teamname"), 754 Channel: ptrStr("channelname"), 755 User: ptrStr("username"), 756 Message: ptrStr("message"), 757 } 758 if err := validatePostImportData(&data, maxPostSize); err == nil { 759 t.Fatal("Should have failed due to missing required property.") 760 } 761 762 // Test with invalid message. 763 data = PostImportData{ 764 Team: ptrStr("teamname"), 765 Channel: ptrStr("channelname"), 766 User: ptrStr("username"), 767 Message: ptrStr(strings.Repeat("0", maxPostSize+1)), 768 CreateAt: ptrInt64(model.GetMillis()), 769 } 770 if err := validatePostImportData(&data, maxPostSize); err == nil { 771 t.Fatal("Should have failed due to too long message.") 772 } 773 774 // Test with invalid CreateAt 775 data = PostImportData{ 776 Team: ptrStr("teamname"), 777 Channel: ptrStr("channelname"), 778 User: ptrStr("username"), 779 Message: ptrStr("message"), 780 CreateAt: ptrInt64(0), 781 } 782 if err := validatePostImportData(&data, maxPostSize); err == nil { 783 t.Fatal("Should have failed due to 0 create-at value.") 784 } 785 786 // Test with valid all optional parameters. 787 reactions := []ReactionImportData{ReactionImportData{ 788 User: ptrStr("username"), 789 EmojiName: ptrStr("emoji"), 790 CreateAt: ptrInt64(model.GetMillis()), 791 }} 792 replies := []ReplyImportData{ReplyImportData{ 793 User: ptrStr("username"), 794 Message: ptrStr("message"), 795 CreateAt: ptrInt64(model.GetMillis()), 796 }} 797 data = PostImportData{ 798 Team: ptrStr("teamname"), 799 Channel: ptrStr("channelname"), 800 User: ptrStr("username"), 801 Message: ptrStr("message"), 802 CreateAt: ptrInt64(model.GetMillis()), 803 Reactions: &reactions, 804 Replies: &replies, 805 } 806 if err := validatePostImportData(&data, maxPostSize); err != nil { 807 t.Fatal("Should have succeeded.") 808 } 809 } 810 811 func TestImportValidateDirectChannelImportData(t *testing.T) { 812 813 // Test with valid number of members for direct message. 814 data := DirectChannelImportData{ 815 Members: &[]string{ 816 model.NewId(), 817 model.NewId(), 818 }, 819 } 820 if err := validateDirectChannelImportData(&data); err != nil { 821 t.Fatal("Validation failed but should have been valid.") 822 } 823 824 // Test with valid number of members for group message. 825 data = DirectChannelImportData{ 826 Members: &[]string{ 827 model.NewId(), 828 model.NewId(), 829 model.NewId(), 830 }, 831 } 832 if err := validateDirectChannelImportData(&data); err != nil { 833 t.Fatal("Validation failed but should have been valid.") 834 } 835 836 // Test with all the combinations of optional parameters. 837 data = DirectChannelImportData{ 838 Members: &[]string{ 839 model.NewId(), 840 model.NewId(), 841 }, 842 Header: ptrStr("Channel Header Here"), 843 } 844 if err := validateDirectChannelImportData(&data); err != nil { 845 t.Fatal("Should have succeeded with valid optional properties.") 846 } 847 848 // Test with invalid Header. 849 data.Header = ptrStr(strings.Repeat("abcdefghij ", 103)) 850 if err := validateDirectChannelImportData(&data); err == nil { 851 t.Fatal("Should have failed due to too long header.") 852 } 853 854 // Test with different combinations of invalid member counts. 855 data = DirectChannelImportData{ 856 Members: &[]string{}, 857 } 858 if err := validateDirectChannelImportData(&data); err == nil { 859 t.Fatal("Validation should have failed due to invalid number of members.") 860 } 861 862 data = DirectChannelImportData{ 863 Members: &[]string{ 864 model.NewId(), 865 }, 866 } 867 if err := validateDirectChannelImportData(&data); err == nil { 868 t.Fatal("Validation should have failed due to invalid number of members.") 869 } 870 871 data = DirectChannelImportData{ 872 Members: &[]string{ 873 model.NewId(), 874 model.NewId(), 875 model.NewId(), 876 model.NewId(), 877 model.NewId(), 878 model.NewId(), 879 model.NewId(), 880 model.NewId(), 881 model.NewId(), 882 }, 883 } 884 if err := validateDirectChannelImportData(&data); err == nil { 885 t.Fatal("Validation should have failed due to invalid number of members.") 886 } 887 888 // Test with invalid FavoritedBy 889 member1 := model.NewId() 890 member2 := model.NewId() 891 data = DirectChannelImportData{ 892 Members: &[]string{ 893 member1, 894 member2, 895 }, 896 FavoritedBy: &[]string{ 897 member1, 898 model.NewId(), 899 }, 900 } 901 if err := validateDirectChannelImportData(&data); err == nil { 902 t.Fatal("Validation should have failed due to non-member favorited.") 903 } 904 905 // Test with valid FavoritedBy 906 data = DirectChannelImportData{ 907 Members: &[]string{ 908 member1, 909 member2, 910 }, 911 FavoritedBy: &[]string{ 912 member1, 913 member2, 914 }, 915 } 916 if err := validateDirectChannelImportData(&data); err != nil { 917 t.Fatal(err) 918 } 919 } 920 921 func TestImportValidateDirectPostImportData(t *testing.T) { 922 maxPostSize := 10000 923 924 // Test with minimum required valid properties. 925 data := DirectPostImportData{ 926 ChannelMembers: &[]string{ 927 model.NewId(), 928 model.NewId(), 929 }, 930 User: ptrStr("username"), 931 Message: ptrStr("message"), 932 CreateAt: ptrInt64(model.GetMillis()), 933 } 934 if err := validateDirectPostImportData(&data, maxPostSize); err != nil { 935 t.Fatal("Validation failed but should have been valid.") 936 } 937 938 // Test with missing required properties. 939 data = DirectPostImportData{ 940 User: ptrStr("username"), 941 Message: ptrStr("message"), 942 CreateAt: ptrInt64(model.GetMillis()), 943 } 944 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 945 t.Fatal("Should have failed due to missing required property.") 946 } 947 948 data = DirectPostImportData{ 949 ChannelMembers: &[]string{ 950 model.NewId(), 951 model.NewId(), 952 }, 953 Message: ptrStr("message"), 954 CreateAt: ptrInt64(model.GetMillis()), 955 } 956 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 957 t.Fatal("Should have failed due to missing required property.") 958 } 959 960 data = DirectPostImportData{ 961 ChannelMembers: &[]string{ 962 model.NewId(), 963 model.NewId(), 964 }, 965 User: ptrStr("username"), 966 CreateAt: ptrInt64(model.GetMillis()), 967 } 968 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 969 t.Fatal("Should have failed due to missing required property.") 970 } 971 972 data = DirectPostImportData{ 973 ChannelMembers: &[]string{ 974 model.NewId(), 975 model.NewId(), 976 }, 977 User: ptrStr("username"), 978 Message: ptrStr("message"), 979 } 980 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 981 t.Fatal("Should have failed due to missing required property.") 982 } 983 984 // Test with invalid numbers of channel members. 985 data = DirectPostImportData{ 986 ChannelMembers: &[]string{}, 987 User: ptrStr("username"), 988 Message: ptrStr("message"), 989 CreateAt: ptrInt64(model.GetMillis()), 990 } 991 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 992 t.Fatal("Should have failed due to unsuitable number of members.") 993 } 994 995 data = DirectPostImportData{ 996 ChannelMembers: &[]string{ 997 model.NewId(), 998 }, 999 User: ptrStr("username"), 1000 Message: ptrStr("message"), 1001 CreateAt: ptrInt64(model.GetMillis()), 1002 } 1003 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 1004 t.Fatal("Should have failed due to unsuitable number of members.") 1005 } 1006 1007 data = DirectPostImportData{ 1008 ChannelMembers: &[]string{ 1009 model.NewId(), 1010 model.NewId(), 1011 model.NewId(), 1012 model.NewId(), 1013 model.NewId(), 1014 model.NewId(), 1015 model.NewId(), 1016 model.NewId(), 1017 model.NewId(), 1018 model.NewId(), 1019 }, 1020 User: ptrStr("username"), 1021 Message: ptrStr("message"), 1022 CreateAt: ptrInt64(model.GetMillis()), 1023 } 1024 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 1025 t.Fatal("Should have failed due to unsuitable number of members.") 1026 } 1027 1028 // Test with group message number of members. 1029 data = DirectPostImportData{ 1030 ChannelMembers: &[]string{ 1031 model.NewId(), 1032 model.NewId(), 1033 model.NewId(), 1034 }, 1035 User: ptrStr("username"), 1036 Message: ptrStr("message"), 1037 CreateAt: ptrInt64(model.GetMillis()), 1038 } 1039 if err := validateDirectPostImportData(&data, maxPostSize); err != nil { 1040 t.Fatal("Validation failed but should have been valid.") 1041 } 1042 1043 // Test with invalid message. 1044 data = DirectPostImportData{ 1045 ChannelMembers: &[]string{ 1046 model.NewId(), 1047 model.NewId(), 1048 }, 1049 User: ptrStr("username"), 1050 Message: ptrStr(strings.Repeat("0", maxPostSize+1)), 1051 CreateAt: ptrInt64(model.GetMillis()), 1052 } 1053 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 1054 t.Fatal("Should have failed due to too long message.") 1055 } 1056 1057 // Test with invalid CreateAt 1058 data = DirectPostImportData{ 1059 ChannelMembers: &[]string{ 1060 model.NewId(), 1061 model.NewId(), 1062 }, 1063 User: ptrStr("username"), 1064 Message: ptrStr("message"), 1065 CreateAt: ptrInt64(0), 1066 } 1067 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 1068 t.Fatal("Should have failed due to 0 create-at value.") 1069 } 1070 1071 // Test with invalid FlaggedBy 1072 member1 := model.NewId() 1073 member2 := model.NewId() 1074 data = DirectPostImportData{ 1075 ChannelMembers: &[]string{ 1076 member1, 1077 member2, 1078 }, 1079 FlaggedBy: &[]string{ 1080 member1, 1081 model.NewId(), 1082 }, 1083 User: ptrStr("username"), 1084 Message: ptrStr("message"), 1085 CreateAt: ptrInt64(model.GetMillis()), 1086 } 1087 if err := validateDirectPostImportData(&data, maxPostSize); err == nil { 1088 t.Fatal("Validation should have failed due to non-member flagged.") 1089 } 1090 1091 // Test with valid FlaggedBy 1092 data = DirectPostImportData{ 1093 ChannelMembers: &[]string{ 1094 member1, 1095 member2, 1096 }, 1097 FlaggedBy: &[]string{ 1098 member1, 1099 member2, 1100 }, 1101 User: ptrStr("username"), 1102 Message: ptrStr("message"), 1103 CreateAt: ptrInt64(model.GetMillis()), 1104 } 1105 if err := validateDirectPostImportData(&data, maxPostSize); err != nil { 1106 t.Fatal(err) 1107 } 1108 1109 // Test with valid all optional parameters. 1110 reactions := []ReactionImportData{ReactionImportData{ 1111 User: ptrStr("username"), 1112 EmojiName: ptrStr("emoji"), 1113 CreateAt: ptrInt64(model.GetMillis()), 1114 }} 1115 replies := []ReplyImportData{ReplyImportData{ 1116 User: ptrStr("username"), 1117 Message: ptrStr("message"), 1118 CreateAt: ptrInt64(model.GetMillis()), 1119 }} 1120 data = DirectPostImportData{ 1121 ChannelMembers: &[]string{ 1122 member1, 1123 member2, 1124 }, 1125 FlaggedBy: &[]string{ 1126 member1, 1127 member2, 1128 }, 1129 User: ptrStr("username"), 1130 Message: ptrStr("message"), 1131 CreateAt: ptrInt64(model.GetMillis()), 1132 Reactions: &reactions, 1133 Replies: &replies, 1134 } 1135 1136 if err := validateDirectPostImportData(&data, maxPostSize); err != nil { 1137 t.Fatal(err) 1138 } 1139 } 1140 1141 func TestImportImportTeam(t *testing.T) { 1142 th := Setup() 1143 defer th.TearDown() 1144 1145 // Check how many teams are in the database. 1146 var teamsCount int64 1147 if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil { 1148 teamsCount = r.Data.(int64) 1149 } else { 1150 t.Fatalf("Failed to get team count.") 1151 } 1152 1153 data := TeamImportData{ 1154 Name: ptrStr(model.NewId()), 1155 DisplayName: ptrStr("Display Name"), 1156 Type: ptrStr("XYZ"), 1157 Description: ptrStr("The team description."), 1158 AllowOpenInvite: ptrBool(true), 1159 } 1160 1161 // Try importing an invalid team in dryRun mode. 1162 if err := th.App.ImportTeam(&data, true); err == nil { 1163 t.Fatalf("Should have received an error importing an invalid team.") 1164 } 1165 1166 // Do a valid team in dry-run mode. 1167 data.Type = ptrStr("O") 1168 if err := th.App.ImportTeam(&data, true); err != nil { 1169 t.Fatalf("Received an error validating valid team.") 1170 } 1171 1172 // Check that no more teams are in the DB. 1173 if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil { 1174 if r.Data.(int64) != teamsCount { 1175 t.Fatalf("Teams got persisted in dry run mode.") 1176 } 1177 } else { 1178 t.Fatalf("Failed to get team count.") 1179 } 1180 1181 // Do an invalid team in apply mode, check db changes. 1182 data.Type = ptrStr("XYZ") 1183 if err := th.App.ImportTeam(&data, false); err == nil { 1184 t.Fatalf("Import should have failed on invalid team.") 1185 } 1186 1187 // Check that no more teams are in the DB. 1188 if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil { 1189 if r.Data.(int64) != teamsCount { 1190 t.Fatalf("Invalid team got persisted.") 1191 } 1192 } else { 1193 t.Fatalf("Failed to get team count.") 1194 } 1195 1196 // Do a valid team in apply mode, check db changes. 1197 data.Type = ptrStr("O") 1198 if err := th.App.ImportTeam(&data, false); err != nil { 1199 t.Fatalf("Received an error importing valid team.") 1200 } 1201 1202 // Check that one more team is in the DB. 1203 if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil { 1204 if r.Data.(int64)-1 != teamsCount { 1205 t.Fatalf("Team did not get saved in apply run mode. analytics=%v teamcount=%v", r.Data.(int64), teamsCount) 1206 } 1207 } else { 1208 t.Fatalf("Failed to get team count.") 1209 } 1210 1211 // Get the team and check that all the fields are correct. 1212 if team, err := th.App.GetTeamByName(*data.Name); err != nil { 1213 t.Fatalf("Failed to get team from database.") 1214 } else { 1215 if team.DisplayName != *data.DisplayName || team.Type != *data.Type || team.Description != *data.Description || team.AllowOpenInvite != *data.AllowOpenInvite { 1216 t.Fatalf("Imported team properties do not match import data.") 1217 } 1218 } 1219 1220 // Alter all the fields of that team (apart from unique identifier) and import again. 1221 data.DisplayName = ptrStr("Display Name 2") 1222 data.Type = ptrStr("P") 1223 data.Description = ptrStr("The new description") 1224 data.AllowOpenInvite = ptrBool(false) 1225 1226 // Check that the original number of teams are again in the DB (because this query doesn't include deleted). 1227 data.Type = ptrStr("O") 1228 if err := th.App.ImportTeam(&data, false); err != nil { 1229 t.Fatalf("Received an error importing updated valid team.") 1230 } 1231 1232 if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil { 1233 if r.Data.(int64)-1 != teamsCount { 1234 t.Fatalf("Team alterations did not get saved in apply run mode. analytics=%v teamcount=%v", r.Data.(int64), teamsCount) 1235 } 1236 } else { 1237 t.Fatalf("Failed to get team count.") 1238 } 1239 1240 // Get the team and check that all fields are correct. 1241 if team, err := th.App.GetTeamByName(*data.Name); err != nil { 1242 t.Fatalf("Failed to get team from database.") 1243 } else { 1244 if team.DisplayName != *data.DisplayName || team.Type != *data.Type || team.Description != *data.Description || team.AllowOpenInvite != *data.AllowOpenInvite { 1245 t.Fatalf("Updated team properties do not match import data.") 1246 } 1247 } 1248 } 1249 1250 func TestImportImportChannel(t *testing.T) { 1251 th := Setup() 1252 defer th.TearDown() 1253 1254 // Import a Team. 1255 teamName := model.NewId() 1256 th.App.ImportTeam(&TeamImportData{ 1257 Name: &teamName, 1258 DisplayName: ptrStr("Display Name"), 1259 Type: ptrStr("O"), 1260 }, false) 1261 team, err := th.App.GetTeamByName(teamName) 1262 if err != nil { 1263 t.Fatalf("Failed to get team from database.") 1264 } 1265 1266 // Check how many channels are in the database. 1267 var channelCount int64 1268 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1269 channelCount = r.Data.(int64) 1270 } else { 1271 t.Fatalf("Failed to get team count.") 1272 } 1273 1274 // Do an invalid channel in dry-run mode. 1275 data := ChannelImportData{ 1276 Team: &teamName, 1277 DisplayName: ptrStr("Display Name"), 1278 Type: ptrStr("O"), 1279 Header: ptrStr("Channe Header"), 1280 Purpose: ptrStr("Channel Purpose"), 1281 } 1282 if err := th.App.ImportChannel(&data, true); err == nil { 1283 t.Fatalf("Expected error due to invalid name.") 1284 } 1285 1286 // Check that no more channels are in the DB. 1287 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1288 if r.Data.(int64) != channelCount { 1289 t.Fatalf("Channels got persisted in dry run mode.") 1290 } 1291 } else { 1292 t.Fatalf("Failed to get channel count.") 1293 } 1294 1295 // Do a valid channel with a nonexistent team in dry-run mode. 1296 data.Name = ptrStr("channelname") 1297 data.Team = ptrStr(model.NewId()) 1298 if err := th.App.ImportChannel(&data, true); err != nil { 1299 t.Fatalf("Expected success as cannot validate channel name in dry run mode.") 1300 } 1301 1302 // Check that no more channels are in the DB. 1303 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1304 if r.Data.(int64) != channelCount { 1305 t.Fatalf("Channels got persisted in dry run mode.") 1306 } 1307 } else { 1308 t.Fatalf("Failed to get channel count.") 1309 } 1310 1311 // Do a valid channel in dry-run mode. 1312 data.Team = &teamName 1313 if err := th.App.ImportChannel(&data, true); err != nil { 1314 t.Fatalf("Expected success as valid team.") 1315 } 1316 1317 // Check that no more channels are in the DB. 1318 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1319 if r.Data.(int64) != channelCount { 1320 t.Fatalf("Channels got persisted in dry run mode.") 1321 } 1322 } else { 1323 t.Fatalf("Failed to get channel count.") 1324 } 1325 1326 // Do an invalid channel in apply mode. 1327 data.Name = nil 1328 if err := th.App.ImportChannel(&data, false); err == nil { 1329 t.Fatalf("Expected error due to invalid name (apply mode).") 1330 } 1331 1332 // Check that no more channels are in the DB. 1333 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1334 if r.Data.(int64) != channelCount { 1335 t.Fatalf("Invalid channel got persisted in apply mode.") 1336 } 1337 } else { 1338 t.Fatalf("Failed to get channel count.") 1339 } 1340 1341 // Do a valid channel in apply mode with a non-existent team. 1342 data.Name = ptrStr("channelname") 1343 data.Team = ptrStr(model.NewId()) 1344 if err := th.App.ImportChannel(&data, false); err == nil { 1345 t.Fatalf("Expected error due to non-existent team (apply mode).") 1346 } 1347 1348 // Check that no more channels are in the DB. 1349 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1350 if r.Data.(int64) != channelCount { 1351 t.Fatalf("Invalid team channel got persisted in apply mode.") 1352 } 1353 } else { 1354 t.Fatalf("Failed to get channel count.") 1355 } 1356 1357 // Do a valid channel in apply mode. 1358 data.Team = &teamName 1359 if err := th.App.ImportChannel(&data, false); err != nil { 1360 t.Fatalf("Expected success in apply mode: %v", err.Error()) 1361 } 1362 1363 // Check that no more channels are in the DB. 1364 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1365 if r.Data.(int64) != channelCount+1 { 1366 t.Fatalf("Channels did not get persisted in apply mode: found %v expected %v + 1", r.Data.(int64), channelCount) 1367 } 1368 } else { 1369 t.Fatalf("Failed to get channel count.") 1370 } 1371 1372 // Get the Channel and check all the fields are correct. 1373 if channel, err := th.App.GetChannelByName(*data.Name, team.Id); err != nil { 1374 t.Fatalf("Failed to get channel from database.") 1375 } else { 1376 if channel.Name != *data.Name || channel.DisplayName != *data.DisplayName || channel.Type != *data.Type || channel.Header != *data.Header || channel.Purpose != *data.Purpose { 1377 t.Fatalf("Imported team properties do not match Import Data.") 1378 } 1379 } 1380 1381 // Alter all the fields of that channel. 1382 data.DisplayName = ptrStr("Chaned Disp Name") 1383 data.Type = ptrStr(model.CHANNEL_PRIVATE) 1384 data.Header = ptrStr("New Header") 1385 data.Purpose = ptrStr("New Purpose") 1386 if err := th.App.ImportChannel(&data, false); err != nil { 1387 t.Fatalf("Expected success in apply mode: %v", err.Error()) 1388 } 1389 1390 // Check channel count the same. 1391 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 1392 if r.Data.(int64) != channelCount { 1393 t.Fatalf("Updated channel did not get correctly persisted in apply mode.") 1394 } 1395 } else { 1396 t.Fatalf("Failed to get channel count.") 1397 } 1398 1399 // Get the Channel and check all the fields are correct. 1400 if channel, err := th.App.GetChannelByName(*data.Name, team.Id); err != nil { 1401 t.Fatalf("Failed to get channel from database.") 1402 } else { 1403 if channel.Name != *data.Name || channel.DisplayName != *data.DisplayName || channel.Type != *data.Type || channel.Header != *data.Header || channel.Purpose != *data.Purpose { 1404 t.Fatalf("Updated team properties do not match Import Data.") 1405 } 1406 } 1407 1408 } 1409 1410 func TestImportImportUser(t *testing.T) { 1411 th := Setup() 1412 defer th.TearDown() 1413 1414 // Check how many users are in the database. 1415 var userCount int64 1416 if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil { 1417 userCount = r.Data.(int64) 1418 } else { 1419 t.Fatalf("Failed to get user count.") 1420 } 1421 1422 // Do an invalid user in dry-run mode. 1423 data := UserImportData{ 1424 Username: ptrStr(model.NewId()), 1425 } 1426 if err := th.App.ImportUser(&data, true); err == nil { 1427 t.Fatalf("Should have failed to import invalid user.") 1428 } 1429 1430 // Check that no more users are in the DB. 1431 if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil { 1432 if r.Data.(int64) != userCount { 1433 t.Fatalf("Unexpected number of users") 1434 } 1435 } else { 1436 t.Fatalf("Failed to get user count.") 1437 } 1438 1439 // Do a valid user in dry-run mode. 1440 data = UserImportData{ 1441 Username: ptrStr(model.NewId()), 1442 Email: ptrStr(model.NewId() + "@example.com"), 1443 } 1444 if err := th.App.ImportUser(&data, true); err != nil { 1445 t.Fatalf("Should have succeeded to import valid user.") 1446 } 1447 1448 // Check that no more users are in the DB. 1449 if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil { 1450 if r.Data.(int64) != userCount { 1451 t.Fatalf("Unexpected number of users") 1452 } 1453 } else { 1454 t.Fatalf("Failed to get user count.") 1455 } 1456 1457 // Do an invalid user in apply mode. 1458 data = UserImportData{ 1459 Username: ptrStr(model.NewId()), 1460 } 1461 if err := th.App.ImportUser(&data, false); err == nil { 1462 t.Fatalf("Should have failed to import invalid user.") 1463 } 1464 1465 // Check that no more users are in the DB. 1466 if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil { 1467 if r.Data.(int64) != userCount { 1468 t.Fatalf("Unexpected number of users") 1469 } 1470 } else { 1471 t.Fatalf("Failed to get user count.") 1472 } 1473 1474 // Do a valid user in apply mode. 1475 username := model.NewId() 1476 testsDir, _ := utils.FindDir("tests") 1477 data = UserImportData{ 1478 ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")), 1479 Username: &username, 1480 Email: ptrStr(model.NewId() + "@example.com"), 1481 Nickname: ptrStr(model.NewId()), 1482 FirstName: ptrStr(model.NewId()), 1483 LastName: ptrStr(model.NewId()), 1484 Position: ptrStr(model.NewId()), 1485 } 1486 if err := th.App.ImportUser(&data, false); err != nil { 1487 t.Fatalf("Should have succeeded to import valid user.") 1488 } 1489 1490 // Check that one more user is in the DB. 1491 if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil { 1492 if r.Data.(int64) != userCount+1 { 1493 t.Fatalf("Unexpected number of users") 1494 } 1495 } else { 1496 t.Fatalf("Failed to get user count.") 1497 } 1498 1499 // Get the user and check all the fields are correct. 1500 if user, err := th.App.GetUserByUsername(username); err != nil { 1501 t.Fatalf("Failed to get user from database.") 1502 } else { 1503 if user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position { 1504 t.Fatalf("User properties do not match Import Data.") 1505 } 1506 // Check calculated properties. 1507 if user.AuthService != "" { 1508 t.Fatalf("Expected Auth Service to be empty.") 1509 } 1510 1511 if !(user.AuthData == nil || *user.AuthData == "") { 1512 t.Fatalf("Expected AuthData to be empty.") 1513 } 1514 1515 if len(user.Password) == 0 { 1516 t.Fatalf("Expected password to be set.") 1517 } 1518 1519 if !user.EmailVerified { 1520 t.Fatalf("Expected EmailVerified to be true.") 1521 } 1522 1523 if user.Locale != *th.App.Config().LocalizationSettings.DefaultClientLocale { 1524 t.Fatalf("Expected Locale to be the default.") 1525 } 1526 1527 if user.Roles != "system_user" { 1528 t.Fatalf("Expected roles to be system_user") 1529 } 1530 } 1531 1532 // Alter all the fields of that user. 1533 data.Email = ptrStr(model.NewId() + "@example.com") 1534 data.ProfileImage = ptrStr(filepath.Join(testsDir, "testgif.gif")) 1535 data.AuthService = ptrStr("ldap") 1536 data.AuthData = &username 1537 data.Nickname = ptrStr(model.NewId()) 1538 data.FirstName = ptrStr(model.NewId()) 1539 data.LastName = ptrStr(model.NewId()) 1540 data.Position = ptrStr(model.NewId()) 1541 data.Roles = ptrStr("system_admin system_user") 1542 data.Locale = ptrStr("zh_CN") 1543 if err := th.App.ImportUser(&data, false); err != nil { 1544 t.Fatalf("Should have succeeded to update valid user %v", err) 1545 } 1546 1547 // Check user count the same. 1548 if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil { 1549 if r.Data.(int64) != userCount+1 { 1550 t.Fatalf("Unexpected number of users") 1551 } 1552 } else { 1553 t.Fatalf("Failed to get user count.") 1554 } 1555 1556 // Get the user and check all the fields are correct. 1557 if user, err := th.App.GetUserByUsername(username); err != nil { 1558 t.Fatalf("Failed to get user from database.") 1559 } else { 1560 if user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position { 1561 t.Fatalf("Updated User properties do not match Import Data.") 1562 } 1563 // Check calculated properties. 1564 if user.AuthService != "ldap" { 1565 t.Fatalf("Expected Auth Service to be ldap \"%v\"", user.AuthService) 1566 } 1567 1568 if !(user.AuthData == data.AuthData || *user.AuthData == *data.AuthData) { 1569 t.Fatalf("Expected AuthData to be set.") 1570 } 1571 1572 if len(user.Password) != 0 { 1573 t.Fatalf("Expected password to be empty.") 1574 } 1575 1576 if !user.EmailVerified { 1577 t.Fatalf("Expected EmailVerified to be true.") 1578 } 1579 1580 if user.Locale != *data.Locale { 1581 t.Fatalf("Expected Locale to be the set.") 1582 } 1583 1584 if user.Roles != *data.Roles { 1585 t.Fatalf("Expected roles to be set: %v", user.Roles) 1586 } 1587 } 1588 1589 // Check Password and AuthData together. 1590 data.Password = ptrStr("PasswordTest") 1591 if err := th.App.ImportUser(&data, false); err == nil { 1592 t.Fatalf("Should have failed to import invalid user.") 1593 } 1594 1595 data.AuthData = nil 1596 if err := th.App.ImportUser(&data, false); err != nil { 1597 t.Fatalf("Should have succeeded to update valid user %v", err) 1598 } 1599 1600 data.Password = ptrStr("") 1601 if err := th.App.ImportUser(&data, false); err == nil { 1602 t.Fatalf("Should have failed to import invalid user.") 1603 } 1604 1605 data.Password = ptrStr(strings.Repeat("0123456789", 10)) 1606 if err := th.App.ImportUser(&data, false); err == nil { 1607 t.Fatalf("Should have failed to import invalid user.") 1608 } 1609 1610 data.Password = ptrStr("TestPassword") 1611 1612 // Test team and channel memberships 1613 teamName := model.NewId() 1614 th.App.ImportTeam(&TeamImportData{ 1615 Name: &teamName, 1616 DisplayName: ptrStr("Display Name"), 1617 Type: ptrStr("O"), 1618 }, false) 1619 team, err := th.App.GetTeamByName(teamName) 1620 if err != nil { 1621 t.Fatalf("Failed to get team from database.") 1622 } 1623 1624 channelName := model.NewId() 1625 th.App.ImportChannel(&ChannelImportData{ 1626 Team: &teamName, 1627 Name: &channelName, 1628 DisplayName: ptrStr("Display Name"), 1629 Type: ptrStr("O"), 1630 }, false) 1631 channel, err := th.App.GetChannelByName(channelName, team.Id) 1632 if err != nil { 1633 t.Fatalf("Failed to get channel from database.") 1634 } 1635 1636 username = model.NewId() 1637 data = UserImportData{ 1638 Username: &username, 1639 Email: ptrStr(model.NewId() + "@example.com"), 1640 Nickname: ptrStr(model.NewId()), 1641 FirstName: ptrStr(model.NewId()), 1642 LastName: ptrStr(model.NewId()), 1643 Position: ptrStr(model.NewId()), 1644 } 1645 1646 teamMembers, err := th.App.GetTeamMembers(team.Id, 0, 1000) 1647 if err != nil { 1648 t.Fatalf("Failed to get team member count") 1649 } 1650 teamMemberCount := len(teamMembers) 1651 1652 channelMemberCount, err := th.App.GetChannelMemberCount(channel.Id) 1653 if err != nil { 1654 t.Fatalf("Failed to get channel member count") 1655 } 1656 1657 // Test with an invalid team & channel membership in dry-run mode. 1658 data.Teams = &[]UserTeamImportData{ 1659 { 1660 Roles: ptrStr("invalid"), 1661 Channels: &[]UserChannelImportData{ 1662 { 1663 Roles: ptrStr("invalid"), 1664 }, 1665 }, 1666 }, 1667 } 1668 if err := th.App.ImportUser(&data, true); err == nil { 1669 t.Fatalf("Should have failed.") 1670 } 1671 1672 // Test with an unknown team name & invalid channel membership in dry-run mode. 1673 data.Teams = &[]UserTeamImportData{ 1674 { 1675 Name: ptrStr(model.NewId()), 1676 Channels: &[]UserChannelImportData{ 1677 { 1678 Roles: ptrStr("invalid"), 1679 }, 1680 }, 1681 }, 1682 } 1683 if err := th.App.ImportUser(&data, true); err == nil { 1684 t.Fatalf("Should have failed.") 1685 } 1686 1687 // Test with a valid team & invalid channel membership in dry-run mode. 1688 data.Teams = &[]UserTeamImportData{ 1689 { 1690 Name: &teamName, 1691 Channels: &[]UserChannelImportData{ 1692 { 1693 Roles: ptrStr("invalid"), 1694 }, 1695 }, 1696 }, 1697 } 1698 if err := th.App.ImportUser(&data, true); err == nil { 1699 t.Fatalf("Should have failed.") 1700 } 1701 1702 // Test with a valid team & unknown channel name in dry-run mode. 1703 data.Teams = &[]UserTeamImportData{ 1704 { 1705 Name: &teamName, 1706 Channels: &[]UserChannelImportData{ 1707 { 1708 Name: ptrStr(model.NewId()), 1709 }, 1710 }, 1711 }, 1712 } 1713 if err := th.App.ImportUser(&data, true); err != nil { 1714 t.Fatalf("Should have succeeded.") 1715 } 1716 1717 // Test with a valid team & valid channel name in dry-run mode. 1718 data.Teams = &[]UserTeamImportData{ 1719 { 1720 Name: &teamName, 1721 Channels: &[]UserChannelImportData{ 1722 { 1723 Name: &channelName, 1724 }, 1725 }, 1726 }, 1727 } 1728 if err := th.App.ImportUser(&data, true); err != nil { 1729 t.Fatalf("Should have succeeded.") 1730 } 1731 1732 // Check no new member objects were created because dry run mode. 1733 if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil { 1734 t.Fatalf("Failed to get Team Member Count") 1735 } else if len(tmc) != teamMemberCount { 1736 t.Fatalf("Number of team members not as expected") 1737 } 1738 1739 if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil { 1740 t.Fatalf("Failed to get Channel Member Count") 1741 } else if cmc != channelMemberCount { 1742 t.Fatalf("Number of channel members not as expected") 1743 } 1744 1745 // Test with an invalid team & channel membership in apply mode. 1746 data.Teams = &[]UserTeamImportData{ 1747 { 1748 Roles: ptrStr("invalid"), 1749 Channels: &[]UserChannelImportData{ 1750 { 1751 Roles: ptrStr("invalid"), 1752 }, 1753 }, 1754 }, 1755 } 1756 if err := th.App.ImportUser(&data, false); err == nil { 1757 t.Fatalf("Should have failed.") 1758 } 1759 1760 // Test with an unknown team name & invalid channel membership in apply mode. 1761 data.Teams = &[]UserTeamImportData{ 1762 { 1763 Name: ptrStr(model.NewId()), 1764 Channels: &[]UserChannelImportData{ 1765 { 1766 Roles: ptrStr("invalid"), 1767 }, 1768 }, 1769 }, 1770 } 1771 if err := th.App.ImportUser(&data, false); err == nil { 1772 t.Fatalf("Should have failed.") 1773 } 1774 1775 // Test with a valid team & invalid channel membership in apply mode. 1776 data.Teams = &[]UserTeamImportData{ 1777 { 1778 Name: &teamName, 1779 Channels: &[]UserChannelImportData{ 1780 { 1781 Roles: ptrStr("invalid"), 1782 }, 1783 }, 1784 }, 1785 } 1786 if err := th.App.ImportUser(&data, false); err == nil { 1787 t.Fatalf("Should have failed.") 1788 } 1789 1790 // Check no new member objects were created because all tests should have failed so far. 1791 if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil { 1792 t.Fatalf("Failed to get Team Member Count") 1793 } else if len(tmc) != teamMemberCount { 1794 t.Fatalf("Number of team members not as expected") 1795 } 1796 1797 if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil { 1798 t.Fatalf("Failed to get Channel Member Count") 1799 } else if cmc != channelMemberCount { 1800 t.Fatalf("Number of channel members not as expected") 1801 } 1802 1803 // Test with a valid team & unknown channel name in apply mode. 1804 data.Teams = &[]UserTeamImportData{ 1805 { 1806 Name: &teamName, 1807 Channels: &[]UserChannelImportData{ 1808 { 1809 Name: ptrStr(model.NewId()), 1810 }, 1811 }, 1812 }, 1813 } 1814 if err := th.App.ImportUser(&data, false); err == nil { 1815 t.Fatalf("Should have failed.") 1816 } 1817 1818 // Check only new team member object created because dry run mode. 1819 if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil { 1820 t.Fatalf("Failed to get Team Member Count") 1821 } else if len(tmc) != teamMemberCount+1 { 1822 t.Fatalf("Number of team members not as expected") 1823 } 1824 1825 if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil { 1826 t.Fatalf("Failed to get Channel Member Count") 1827 } else if cmc != channelMemberCount { 1828 t.Fatalf("Number of channel members not as expected") 1829 } 1830 1831 // Check team member properties. 1832 user, err := th.App.GetUserByUsername(username) 1833 if err != nil { 1834 t.Fatalf("Failed to get user from database.") 1835 } 1836 if teamMember, err := th.App.GetTeamMember(team.Id, user.Id); err != nil { 1837 t.Fatalf("Failed to get team member from database.") 1838 } else if teamMember.Roles != "team_user" { 1839 t.Fatalf("Team member properties not as expected") 1840 } 1841 1842 // Test with a valid team & valid channel name in apply mode. 1843 data.Teams = &[]UserTeamImportData{ 1844 { 1845 Name: &teamName, 1846 Channels: &[]UserChannelImportData{ 1847 { 1848 Name: &channelName, 1849 }, 1850 }, 1851 }, 1852 } 1853 if err := th.App.ImportUser(&data, false); err != nil { 1854 t.Fatalf("Should have succeeded.") 1855 } 1856 1857 // Check only new channel member object created because dry run mode. 1858 if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil { 1859 t.Fatalf("Failed to get Team Member Count") 1860 } else if len(tmc) != teamMemberCount+1 { 1861 t.Fatalf("Number of team members not as expected") 1862 } 1863 1864 if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil { 1865 t.Fatalf("Failed to get Channel Member Count") 1866 } else if cmc != channelMemberCount+1 { 1867 t.Fatalf("Number of channel members not as expected") 1868 } 1869 1870 // Check channel member properties. 1871 if channelMember, err := th.App.GetChannelMember(channel.Id, user.Id); err != nil { 1872 t.Fatalf("Failed to get channel member from database.") 1873 } else if channelMember.Roles != "channel_user" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.PUSH_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != "all" { 1874 t.Fatalf("Channel member properties not as expected") 1875 } 1876 1877 // Test with the properties of the team and channel membership changed. 1878 data.Teams = &[]UserTeamImportData{ 1879 { 1880 Name: &teamName, 1881 Roles: ptrStr("team_user team_admin"), 1882 Channels: &[]UserChannelImportData{ 1883 { 1884 Name: &channelName, 1885 Roles: ptrStr("channel_user channel_admin"), 1886 NotifyProps: &UserChannelNotifyPropsImportData{ 1887 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 1888 Mobile: ptrStr(model.USER_NOTIFY_MENTION), 1889 MarkUnread: ptrStr(model.USER_NOTIFY_MENTION), 1890 }, 1891 Favorite: ptrBool(true), 1892 }, 1893 }, 1894 }, 1895 } 1896 if err := th.App.ImportUser(&data, false); err != nil { 1897 t.Fatalf("Should have succeeded.") 1898 } 1899 1900 // Check both member properties. 1901 if teamMember, err := th.App.GetTeamMember(team.Id, user.Id); err != nil { 1902 t.Fatalf("Failed to get team member from database.") 1903 } else if teamMember.Roles != "team_user team_admin" { 1904 t.Fatalf("Team member properties not as expected: %v", teamMember.Roles) 1905 } 1906 1907 if channelMember, err := th.App.GetChannelMember(channel.Id, user.Id); err != nil { 1908 t.Fatalf("Failed to get channel member Desktop from database.") 1909 } else if channelMember.Roles != "channel_user channel_admin" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != model.USER_NOTIFY_MENTION || channelMember.NotifyProps[model.PUSH_NOTIFY_PROP] != model.USER_NOTIFY_MENTION || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.USER_NOTIFY_MENTION { 1910 t.Fatalf("Channel member properties not as expected") 1911 } 1912 1913 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true") 1914 1915 // No more new member objects. 1916 if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil { 1917 t.Fatalf("Failed to get Team Member Count") 1918 } else if len(tmc) != teamMemberCount+1 { 1919 t.Fatalf("Number of team members not as expected") 1920 } 1921 1922 if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil { 1923 t.Fatalf("Failed to get Channel Member Count") 1924 } else if cmc != channelMemberCount+1 { 1925 t.Fatalf("Number of channel members not as expected") 1926 } 1927 1928 // Add a user with some preferences. 1929 username = model.NewId() 1930 data = UserImportData{ 1931 Username: &username, 1932 Email: ptrStr(model.NewId() + "@example.com"), 1933 Theme: ptrStr(`{"awayIndicator":"#DCBD4E","buttonBg":"#23A2FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBj":"#2389d7","mentionColor":"#ffffff","mentionHighlightBg":"#fff2bb","mentionHighlightLink":"#2f81b7","newMessageSeparator":"#FF8800","onlineIndicator":"#7DBE00","sidebarBg":"#fafafa","sidebarHeaderBg":"#3481B9","sidebarHeaderTextColor":"#ffffff","sidebarText":"#333333","sidebarTextActiveBorder":"#378FD2","sidebarTextActiveColor":"#111111","sidebarTextHoverBg":"#e6f2fa","sidebarUnreadText":"#333333","type":"Mattermost"}`), 1934 UseMilitaryTime: ptrStr("true"), 1935 CollapsePreviews: ptrStr("true"), 1936 MessageDisplay: ptrStr("compact"), 1937 ChannelDisplayMode: ptrStr("centered"), 1938 TutorialStep: ptrStr("3"), 1939 } 1940 if err := th.App.ImportUser(&data, false); err != nil { 1941 t.Fatalf("Should have succeeded.") 1942 } 1943 1944 // Check their values. 1945 user, err = th.App.GetUserByUsername(username) 1946 if err != nil { 1947 t.Fatalf("Failed to get user from database.") 1948 } 1949 1950 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme) 1951 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "use_military_time", *data.UseMilitaryTime) 1952 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "collapse_previews", *data.CollapsePreviews) 1953 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "message_display", *data.MessageDisplay) 1954 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "channel_display_mode", *data.ChannelDisplayMode) 1955 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep) 1956 1957 // Change those preferences. 1958 data = UserImportData{ 1959 Username: &username, 1960 Email: ptrStr(model.NewId() + "@example.com"), 1961 Theme: ptrStr(`{"awayIndicator":"#123456","buttonBg":"#23A2FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBj":"#2389d7","mentionColor":"#ffffff","mentionHighlightBg":"#fff2bb","mentionHighlightLink":"#2f81b7","newMessageSeparator":"#FF8800","onlineIndicator":"#7DBE00","sidebarBg":"#fafafa","sidebarHeaderBg":"#3481B9","sidebarHeaderTextColor":"#ffffff","sidebarText":"#333333","sidebarTextActiveBorder":"#378FD2","sidebarTextActiveColor":"#111111","sidebarTextHoverBg":"#e6f2fa","sidebarUnreadText":"#333333","type":"Mattermost"}`), 1962 UseMilitaryTime: ptrStr("false"), 1963 CollapsePreviews: ptrStr("false"), 1964 MessageDisplay: ptrStr("clean"), 1965 ChannelDisplayMode: ptrStr("full"), 1966 TutorialStep: ptrStr("2"), 1967 } 1968 if err := th.App.ImportUser(&data, false); err != nil { 1969 t.Fatalf("Should have succeeded.") 1970 } 1971 1972 // Check their values again. 1973 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme) 1974 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "use_military_time", *data.UseMilitaryTime) 1975 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "collapse_previews", *data.CollapsePreviews) 1976 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "message_display", *data.MessageDisplay) 1977 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "channel_display_mode", *data.ChannelDisplayMode) 1978 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep) 1979 1980 // Set Notify Props 1981 data.NotifyProps = &UserNotifyPropsImportData{ 1982 Desktop: ptrStr(model.USER_NOTIFY_ALL), 1983 DesktopDuration: ptrStr("5"), 1984 DesktopSound: ptrStr("true"), 1985 Email: ptrStr("true"), 1986 Mobile: ptrStr(model.USER_NOTIFY_ALL), 1987 MobilePushStatus: ptrStr(model.STATUS_ONLINE), 1988 ChannelTrigger: ptrStr("true"), 1989 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ROOT), 1990 MentionKeys: ptrStr("valid,misc"), 1991 } 1992 if err := th.App.ImportUser(&data, false); err != nil { 1993 t.Fatalf("Should have succeeded.") 1994 } 1995 1996 user, err = th.App.GetUserByUsername(username) 1997 if err != nil { 1998 t.Fatalf("Failed to get user from database.") 1999 } 2000 2001 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL) 2002 checkNotifyProp(t, user, model.DESKTOP_DURATION_NOTIFY_PROP, "5") 2003 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true") 2004 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true") 2005 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL) 2006 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE) 2007 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true") 2008 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT) 2009 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "valid,misc") 2010 2011 // Change Notify Props 2012 data.NotifyProps = &UserNotifyPropsImportData{ 2013 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 2014 DesktopDuration: ptrStr("3"), 2015 DesktopSound: ptrStr("false"), 2016 Email: ptrStr("false"), 2017 Mobile: ptrStr(model.USER_NOTIFY_NONE), 2018 MobilePushStatus: ptrStr(model.STATUS_AWAY), 2019 ChannelTrigger: ptrStr("false"), 2020 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), 2021 MentionKeys: ptrStr("misc"), 2022 } 2023 if err := th.App.ImportUser(&data, false); err != nil { 2024 t.Fatalf("Should have succeeded.") 2025 } 2026 2027 user, err = th.App.GetUserByUsername(username) 2028 if err != nil { 2029 t.Fatalf("Failed to get user from database.") 2030 } 2031 2032 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) 2033 checkNotifyProp(t, user, model.DESKTOP_DURATION_NOTIFY_PROP, "3") 2034 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") 2035 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") 2036 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) 2037 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) 2038 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") 2039 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) 2040 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") 2041 2042 // Check Notify Props get set on *create* user. 2043 username = model.NewId() 2044 data = UserImportData{ 2045 Username: &username, 2046 Email: ptrStr(model.NewId() + "@example.com"), 2047 } 2048 data.NotifyProps = &UserNotifyPropsImportData{ 2049 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 2050 DesktopDuration: ptrStr("3"), 2051 DesktopSound: ptrStr("false"), 2052 Email: ptrStr("false"), 2053 Mobile: ptrStr(model.USER_NOTIFY_NONE), 2054 MobilePushStatus: ptrStr(model.STATUS_AWAY), 2055 ChannelTrigger: ptrStr("false"), 2056 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), 2057 MentionKeys: ptrStr("misc"), 2058 } 2059 2060 if err := th.App.ImportUser(&data, false); err != nil { 2061 t.Fatalf("Should have succeeded.") 2062 } 2063 2064 user, err = th.App.GetUserByUsername(username) 2065 if err != nil { 2066 t.Fatalf("Failed to get user from database.") 2067 } 2068 2069 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) 2070 checkNotifyProp(t, user, model.DESKTOP_DURATION_NOTIFY_PROP, "3") 2071 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") 2072 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") 2073 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) 2074 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) 2075 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") 2076 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) 2077 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") 2078 } 2079 2080 func AssertAllPostsCount(t *testing.T, a *App, initialCount int64, change int64, teamName string) { 2081 if result := <-a.Srv.Store.Post().AnalyticsPostCount(teamName, false, false); result.Err != nil { 2082 t.Fatal(result.Err) 2083 } else { 2084 if initialCount+change != result.Data.(int64) { 2085 debug.PrintStack() 2086 t.Fatalf("Did not find the expected number of posts.") 2087 } 2088 } 2089 } 2090 2091 func TestImportImportPost(t *testing.T) { 2092 th := Setup() 2093 defer th.TearDown() 2094 2095 // Create a Team. 2096 teamName := model.NewId() 2097 th.App.ImportTeam(&TeamImportData{ 2098 Name: &teamName, 2099 DisplayName: ptrStr("Display Name"), 2100 Type: ptrStr("O"), 2101 }, false) 2102 team, err := th.App.GetTeamByName(teamName) 2103 if err != nil { 2104 t.Fatalf("Failed to get team from database.") 2105 } 2106 2107 // Create a Channel. 2108 channelName := model.NewId() 2109 th.App.ImportChannel(&ChannelImportData{ 2110 Team: &teamName, 2111 Name: &channelName, 2112 DisplayName: ptrStr("Display Name"), 2113 Type: ptrStr("O"), 2114 }, false) 2115 channel, err := th.App.GetChannelByName(channelName, team.Id) 2116 if err != nil { 2117 t.Fatalf("Failed to get channel from database.") 2118 } 2119 2120 // Create a user. 2121 username := model.NewId() 2122 th.App.ImportUser(&UserImportData{ 2123 Username: &username, 2124 Email: ptrStr(model.NewId() + "@example.com"), 2125 }, false) 2126 user, err := th.App.GetUserByUsername(username) 2127 if err != nil { 2128 t.Fatalf("Failed to get user from database.") 2129 } 2130 2131 // Count the number of posts in the testing team. 2132 var initialPostCount int64 2133 if result := <-th.App.Srv.Store.Post().AnalyticsPostCount(team.Id, false, false); result.Err != nil { 2134 t.Fatal(result.Err) 2135 } else { 2136 initialPostCount = result.Data.(int64) 2137 } 2138 2139 // Try adding an invalid post in dry run mode. 2140 data := &PostImportData{ 2141 Team: &teamName, 2142 Channel: &channelName, 2143 User: &username, 2144 } 2145 if err := th.App.ImportPost(data, true); err == nil { 2146 t.Fatalf("Expected error.") 2147 } 2148 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 2149 2150 // Try adding a valid post in dry run mode. 2151 data = &PostImportData{ 2152 Team: &teamName, 2153 Channel: &channelName, 2154 User: &username, 2155 Message: ptrStr("Hello"), 2156 CreateAt: ptrInt64(model.GetMillis()), 2157 } 2158 if err := th.App.ImportPost(data, true); err != nil { 2159 t.Fatalf("Expected success.") 2160 } 2161 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 2162 2163 // Try adding an invalid post in apply mode. 2164 data = &PostImportData{ 2165 Team: &teamName, 2166 Channel: &channelName, 2167 User: &username, 2168 CreateAt: ptrInt64(model.GetMillis()), 2169 } 2170 if err := th.App.ImportPost(data, false); err == nil { 2171 t.Fatalf("Expected error.") 2172 } 2173 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 2174 2175 // Try adding a valid post with invalid team in apply mode. 2176 data = &PostImportData{ 2177 Team: ptrStr(model.NewId()), 2178 Channel: &channelName, 2179 User: &username, 2180 Message: ptrStr("Message"), 2181 CreateAt: ptrInt64(model.GetMillis()), 2182 } 2183 if err := th.App.ImportPost(data, false); err == nil { 2184 t.Fatalf("Expected error.") 2185 } 2186 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 2187 2188 // Try adding a valid post with invalid channel in apply mode. 2189 data = &PostImportData{ 2190 Team: &teamName, 2191 Channel: ptrStr(model.NewId()), 2192 User: &username, 2193 Message: ptrStr("Message"), 2194 CreateAt: ptrInt64(model.GetMillis()), 2195 } 2196 if err := th.App.ImportPost(data, false); err == nil { 2197 t.Fatalf("Expected error.") 2198 } 2199 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 2200 2201 // Try adding a valid post with invalid user in apply mode. 2202 data = &PostImportData{ 2203 Team: &teamName, 2204 Channel: &channelName, 2205 User: ptrStr(model.NewId()), 2206 Message: ptrStr("Message"), 2207 CreateAt: ptrInt64(model.GetMillis()), 2208 } 2209 if err := th.App.ImportPost(data, false); err == nil { 2210 t.Fatalf("Expected error.") 2211 } 2212 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 2213 2214 // Try adding a valid post in apply mode. 2215 time := model.GetMillis() 2216 data = &PostImportData{ 2217 Team: &teamName, 2218 Channel: &channelName, 2219 User: &username, 2220 Message: ptrStr("Message"), 2221 CreateAt: &time, 2222 } 2223 if err := th.App.ImportPost(data, false); err != nil { 2224 t.Fatalf("Expected success.") 2225 } 2226 AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id) 2227 2228 // Check the post values. 2229 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, time); result.Err != nil { 2230 t.Fatal(result.Err.Error()) 2231 } else { 2232 posts := result.Data.([]*model.Post) 2233 if len(posts) != 1 { 2234 t.Fatal("Unexpected number of posts found.") 2235 } 2236 post := posts[0] 2237 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 2238 t.Fatal("Post properties not as expected") 2239 } 2240 } 2241 2242 // Update the post. 2243 data = &PostImportData{ 2244 Team: &teamName, 2245 Channel: &channelName, 2246 User: &username, 2247 Message: ptrStr("Message"), 2248 CreateAt: &time, 2249 } 2250 if err := th.App.ImportPost(data, false); err != nil { 2251 t.Fatalf("Expected success.") 2252 } 2253 AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id) 2254 2255 // Check the post values. 2256 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, time); result.Err != nil { 2257 t.Fatal(result.Err.Error()) 2258 } else { 2259 posts := result.Data.([]*model.Post) 2260 if len(posts) != 1 { 2261 t.Fatal("Unexpected number of posts found.") 2262 } 2263 post := posts[0] 2264 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 2265 t.Fatal("Post properties not as expected") 2266 } 2267 } 2268 2269 // Save the post with a different time. 2270 newTime := time + 1 2271 data = &PostImportData{ 2272 Team: &teamName, 2273 Channel: &channelName, 2274 User: &username, 2275 Message: ptrStr("Message"), 2276 CreateAt: &newTime, 2277 } 2278 if err := th.App.ImportPost(data, false); err != nil { 2279 t.Fatalf("Expected success.") 2280 } 2281 AssertAllPostsCount(t, th.App, initialPostCount, 2, team.Id) 2282 2283 // Save the post with a different message. 2284 data = &PostImportData{ 2285 Team: &teamName, 2286 Channel: &channelName, 2287 User: &username, 2288 Message: ptrStr("Message 2"), 2289 CreateAt: &time, 2290 } 2291 if err := th.App.ImportPost(data, false); err != nil { 2292 t.Fatalf("Expected success.") 2293 } 2294 AssertAllPostsCount(t, th.App, initialPostCount, 3, team.Id) 2295 2296 // Test with hashtags 2297 hashtagTime := time + 2 2298 data = &PostImportData{ 2299 Team: &teamName, 2300 Channel: &channelName, 2301 User: &username, 2302 Message: ptrStr("Message 2 #hashtagmashupcity"), 2303 CreateAt: &hashtagTime, 2304 } 2305 if err := th.App.ImportPost(data, false); err != nil { 2306 t.Fatalf("Expected success.") 2307 } 2308 AssertAllPostsCount(t, th.App, initialPostCount, 4, team.Id) 2309 2310 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, hashtagTime); result.Err != nil { 2311 t.Fatal(result.Err.Error()) 2312 } else { 2313 posts := result.Data.([]*model.Post) 2314 if len(posts) != 1 { 2315 t.Fatal("Unexpected number of posts found.") 2316 } 2317 post := posts[0] 2318 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 2319 t.Fatal("Post properties not as expected") 2320 } 2321 if post.Hashtags != "#hashtagmashupcity" { 2322 t.Fatalf("Hashtags not as expected: %s", post.Hashtags) 2323 } 2324 } 2325 2326 // Post with flags. 2327 username2 := model.NewId() 2328 th.App.ImportUser(&UserImportData{ 2329 Username: &username2, 2330 Email: ptrStr(model.NewId() + "@example.com"), 2331 }, false) 2332 user2, err := th.App.GetUserByUsername(username2) 2333 if err != nil { 2334 t.Fatalf("Failed to get user from database.") 2335 } 2336 2337 flagsTime := hashtagTime + 1 2338 data = &PostImportData{ 2339 Team: &teamName, 2340 Channel: &channelName, 2341 User: &username, 2342 Message: ptrStr("Message with Favorites"), 2343 CreateAt: &flagsTime, 2344 FlaggedBy: &[]string{ 2345 username, 2346 username2, 2347 }, 2348 } 2349 if err := th.App.ImportPost(data, false); err != nil { 2350 t.Fatalf("Expected success.") 2351 } 2352 AssertAllPostsCount(t, th.App, initialPostCount, 5, team.Id) 2353 2354 // Check the post values. 2355 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, flagsTime); result.Err != nil { 2356 t.Fatal(result.Err.Error()) 2357 } else { 2358 posts := result.Data.([]*model.Post) 2359 if len(posts) != 1 { 2360 t.Fatal("Unexpected number of posts found.") 2361 } 2362 post := posts[0] 2363 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 2364 t.Fatal("Post properties not as expected") 2365 } 2366 2367 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2368 checkPreference(t, th.App, user2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2369 } 2370 2371 // Post with reaction. 2372 reactionPostTime := hashtagTime + 2 2373 reactionTime := hashtagTime + 3 2374 data = &PostImportData{ 2375 Team: &teamName, 2376 Channel: &channelName, 2377 User: &username, 2378 Message: ptrStr("Message with reaction"), 2379 CreateAt: &reactionPostTime, 2380 Reactions: &[]ReactionImportData{{ 2381 User: &user2.Username, 2382 EmojiName: ptrStr("+1"), 2383 CreateAt: &reactionTime, 2384 }}, 2385 } 2386 if err := th.App.ImportPost(data, false); err != nil { 2387 t.Fatalf("Expected success.") 2388 } 2389 AssertAllPostsCount(t, th.App, initialPostCount, 6, team.Id) 2390 2391 // Check the post values. 2392 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, reactionPostTime); result.Err != nil { 2393 t.Fatal(result.Err.Error()) 2394 } else { 2395 posts := result.Data.([]*model.Post) 2396 if len(posts) != 1 { 2397 t.Fatal("Unexpected number of posts found.") 2398 } 2399 post := posts[0] 2400 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id || !post.HasReactions { 2401 t.Fatal("Post properties not as expected") 2402 } 2403 2404 if result := <-th.App.Srv.Store.Reaction().GetForPost(post.Id, false); result.Err != nil { 2405 t.Fatal("Can't get reaction") 2406 } else if len(result.Data.([]*model.Reaction)) != 1 { 2407 t.Fatal("Invalid number of reactions") 2408 } 2409 } 2410 2411 // Post with reply. 2412 replyPostTime := hashtagTime + 4 2413 replyTime := hashtagTime + 5 2414 data = &PostImportData{ 2415 Team: &teamName, 2416 Channel: &channelName, 2417 User: &username, 2418 Message: ptrStr("Message with reply"), 2419 CreateAt: &replyPostTime, 2420 Replies: &[]ReplyImportData{{ 2421 User: &user2.Username, 2422 Message: ptrStr("Message reply"), 2423 CreateAt: &replyTime, 2424 }}, 2425 } 2426 if err := th.App.ImportPost(data, false); err != nil { 2427 t.Fatalf("Expected success.") 2428 } 2429 AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id) 2430 2431 // Check the post values. 2432 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyPostTime); result.Err != nil { 2433 t.Fatal(result.Err.Error()) 2434 } else { 2435 posts := result.Data.([]*model.Post) 2436 if len(posts) != 1 { 2437 t.Fatal("Unexpected number of posts found.") 2438 } 2439 post := posts[0] 2440 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 2441 t.Fatal("Post properties not as expected") 2442 } 2443 2444 // Check the reply values. 2445 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyTime); result.Err != nil { 2446 t.Fatal(result.Err.Error()) 2447 } else { 2448 replies := result.Data.([]*model.Post) 2449 if len(replies) != 1 { 2450 t.Fatal("Unexpected number of posts found.") 2451 } 2452 reply := replies[0] 2453 if reply.Message != *(*data.Replies)[0].Message || reply.CreateAt != *(*data.Replies)[0].CreateAt || reply.UserId != user2.Id { 2454 t.Fatal("Post properties not as expected") 2455 } 2456 2457 if reply.RootId != post.Id { 2458 t.Fatal("Unexpected reply RootId") 2459 } 2460 } 2461 } 2462 } 2463 2464 func TestImportImportDirectChannel(t *testing.T) { 2465 th := Setup().InitBasic() 2466 defer th.TearDown() 2467 2468 // Check how many channels are in the database. 2469 var directChannelCount int64 2470 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_DIRECT); r.Err == nil { 2471 directChannelCount = r.Data.(int64) 2472 } else { 2473 t.Fatalf("Failed to get direct channel count.") 2474 } 2475 2476 var groupChannelCount int64 2477 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_GROUP); r.Err == nil { 2478 groupChannelCount = r.Data.(int64) 2479 } else { 2480 t.Fatalf("Failed to get group channel count.") 2481 } 2482 2483 // Do an invalid channel in dry-run mode. 2484 data := DirectChannelImportData{ 2485 Members: &[]string{ 2486 model.NewId(), 2487 }, 2488 Header: ptrStr("Channel Header"), 2489 } 2490 if err := th.App.ImportDirectChannel(&data, true); err == nil { 2491 t.Fatalf("Expected error due to invalid name.") 2492 } 2493 2494 // Check that no more channels are in the DB. 2495 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 2496 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2497 2498 // Do a valid DIRECT channel with a nonexistent member in dry-run mode. 2499 data.Members = &[]string{ 2500 model.NewId(), 2501 model.NewId(), 2502 } 2503 if err := th.App.ImportDirectChannel(&data, true); err != nil { 2504 t.Fatalf("Expected success as cannot validate existence of channel members in dry run mode.") 2505 } 2506 2507 // Check that no more channels are in the DB. 2508 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 2509 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2510 2511 // Do a valid GROUP channel with a nonexistent member in dry-run mode. 2512 data.Members = &[]string{ 2513 model.NewId(), 2514 model.NewId(), 2515 model.NewId(), 2516 } 2517 if err := th.App.ImportDirectChannel(&data, true); err != nil { 2518 t.Fatalf("Expected success as cannot validate existence of channel members in dry run mode.") 2519 } 2520 2521 // Check that no more channels are in the DB. 2522 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 2523 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2524 2525 // Do an invalid channel in apply mode. 2526 data.Members = &[]string{ 2527 model.NewId(), 2528 } 2529 if err := th.App.ImportDirectChannel(&data, false); err == nil { 2530 t.Fatalf("Expected error due to invalid member (apply mode).") 2531 } 2532 2533 // Check that no more channels are in the DB. 2534 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 2535 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2536 2537 // Do a valid DIRECT channel. 2538 data.Members = &[]string{ 2539 th.BasicUser.Username, 2540 th.BasicUser2.Username, 2541 } 2542 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2543 t.Fatalf("Expected success: %v", err.Error()) 2544 } 2545 2546 // Check that one more DIRECT channel is in the DB. 2547 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2548 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2549 2550 // Do the same DIRECT channel again. 2551 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2552 t.Fatalf("Expected success.") 2553 } 2554 2555 // Check that no more channels are in the DB. 2556 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2557 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2558 2559 // Update the channel's HEADER 2560 data.Header = ptrStr("New Channel Header 2") 2561 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2562 t.Fatalf("Expected success.") 2563 } 2564 2565 // Check that no more channels are in the DB. 2566 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2567 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2568 2569 // Get the channel to check that the header was updated. 2570 if channel, err := th.App.createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err == nil || err.Id != store.CHANNEL_EXISTS_ERROR { 2571 t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR") 2572 } else { 2573 if channel.Header != *data.Header { 2574 t.Fatal("Channel header has not been updated successfully.") 2575 } 2576 } 2577 2578 // Do a GROUP channel with an extra invalid member. 2579 user3 := th.CreateUser() 2580 data.Members = &[]string{ 2581 th.BasicUser.Username, 2582 th.BasicUser2.Username, 2583 user3.Username, 2584 model.NewId(), 2585 } 2586 if err := th.App.ImportDirectChannel(&data, false); err == nil { 2587 t.Fatalf("Should have failed due to invalid member in list.") 2588 } 2589 2590 // Check that no more channels are in the DB. 2591 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2592 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 2593 2594 // Do a valid GROUP channel. 2595 data.Members = &[]string{ 2596 th.BasicUser.Username, 2597 th.BasicUser2.Username, 2598 user3.Username, 2599 } 2600 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2601 t.Fatalf("Expected success.") 2602 } 2603 2604 // Check that one more GROUP channel is in the DB. 2605 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2606 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1) 2607 2608 // Do the same DIRECT channel again. 2609 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2610 t.Fatalf("Expected success.") 2611 } 2612 2613 // Check that no more channels are in the DB. 2614 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2615 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1) 2616 2617 // Update the channel's HEADER 2618 data.Header = ptrStr("New Channel Header 3") 2619 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2620 t.Fatalf("Expected success.") 2621 } 2622 2623 // Check that no more channels are in the DB. 2624 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2625 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1) 2626 2627 // Get the channel to check that the header was updated. 2628 userIds := []string{ 2629 th.BasicUser.Id, 2630 th.BasicUser2.Id, 2631 user3.Id, 2632 } 2633 if channel, err := th.App.createGroupChannel(userIds, th.BasicUser.Id); err.Id != store.CHANNEL_EXISTS_ERROR { 2634 t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR") 2635 } else { 2636 if channel.Header != *data.Header { 2637 t.Fatal("Channel header has not been updated successfully.") 2638 } 2639 } 2640 2641 // Import a channel with some favorites. 2642 data.Members = &[]string{ 2643 th.BasicUser.Username, 2644 th.BasicUser2.Username, 2645 } 2646 data.FavoritedBy = &[]string{ 2647 th.BasicUser.Username, 2648 th.BasicUser2.Username, 2649 } 2650 if err := th.App.ImportDirectChannel(&data, false); err != nil { 2651 t.Fatal(err) 2652 } 2653 2654 if channel, err := th.App.createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err == nil || err.Id != store.CHANNEL_EXISTS_ERROR { 2655 t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR") 2656 } else { 2657 checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true") 2658 checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true") 2659 } 2660 } 2661 2662 func AssertChannelCount(t *testing.T, a *App, channelType string, expectedCount int64) { 2663 if r := <-a.Srv.Store.Channel().AnalyticsTypeCount("", channelType); r.Err == nil { 2664 count := r.Data.(int64) 2665 if count != expectedCount { 2666 debug.PrintStack() 2667 t.Fatalf("Channel count of type: %v. Expected: %v, Got: %v", channelType, expectedCount, count) 2668 } 2669 } else { 2670 debug.PrintStack() 2671 t.Fatalf("Failed to get channel count.") 2672 } 2673 } 2674 2675 func TestImportImportDirectPost(t *testing.T) { 2676 th := Setup().InitBasic() 2677 defer th.TearDown() 2678 2679 // Create the DIRECT channel. 2680 channelData := DirectChannelImportData{ 2681 Members: &[]string{ 2682 th.BasicUser.Username, 2683 th.BasicUser2.Username, 2684 }, 2685 } 2686 if err := th.App.ImportDirectChannel(&channelData, false); err != nil { 2687 t.Fatalf("Expected success: %v", err.Error()) 2688 } 2689 2690 // Get the channel. 2691 var directChannel *model.Channel 2692 if channel, err := th.App.createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err.Id != store.CHANNEL_EXISTS_ERROR { 2693 t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR") 2694 } else { 2695 directChannel = channel 2696 } 2697 2698 // Get the number of posts in the system. 2699 var initialPostCount int64 2700 if result := <-th.App.Srv.Store.Post().AnalyticsPostCount("", false, false); result.Err != nil { 2701 t.Fatal(result.Err) 2702 } else { 2703 initialPostCount = result.Data.(int64) 2704 } 2705 2706 // Try adding an invalid post in dry run mode. 2707 data := &DirectPostImportData{ 2708 ChannelMembers: &[]string{ 2709 th.BasicUser.Username, 2710 th.BasicUser2.Username, 2711 }, 2712 User: ptrStr(th.BasicUser.Username), 2713 CreateAt: ptrInt64(model.GetMillis()), 2714 } 2715 if err := th.App.ImportDirectPost(data, true); err == nil { 2716 t.Fatalf("Expected error.") 2717 } 2718 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2719 2720 // Try adding a valid post in dry run mode. 2721 data = &DirectPostImportData{ 2722 ChannelMembers: &[]string{ 2723 th.BasicUser.Username, 2724 th.BasicUser2.Username, 2725 }, 2726 User: ptrStr(th.BasicUser.Username), 2727 Message: ptrStr("Message"), 2728 CreateAt: ptrInt64(model.GetMillis()), 2729 } 2730 if err := th.App.ImportDirectPost(data, true); err != nil { 2731 t.Fatalf("Expected success.") 2732 } 2733 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2734 2735 // Try adding an invalid post in apply mode. 2736 data = &DirectPostImportData{ 2737 ChannelMembers: &[]string{ 2738 th.BasicUser.Username, 2739 model.NewId(), 2740 }, 2741 User: ptrStr(th.BasicUser.Username), 2742 Message: ptrStr("Message"), 2743 CreateAt: ptrInt64(model.GetMillis()), 2744 } 2745 if err := th.App.ImportDirectPost(data, false); err == nil { 2746 t.Fatalf("Expected error.") 2747 } 2748 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2749 2750 // Try adding a valid post in apply mode. 2751 data = &DirectPostImportData{ 2752 ChannelMembers: &[]string{ 2753 th.BasicUser.Username, 2754 th.BasicUser2.Username, 2755 }, 2756 User: ptrStr(th.BasicUser.Username), 2757 Message: ptrStr("Message"), 2758 CreateAt: ptrInt64(model.GetMillis()), 2759 } 2760 if err := th.App.ImportDirectPost(data, false); err != nil { 2761 t.Fatalf("Expected success: %v", err.Error()) 2762 } 2763 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2764 2765 // Check the post values. 2766 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil { 2767 t.Fatal(result.Err.Error()) 2768 } else { 2769 posts := result.Data.([]*model.Post) 2770 if len(posts) != 1 { 2771 t.Fatal("Unexpected number of posts found.") 2772 } 2773 post := posts[0] 2774 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id { 2775 t.Fatal("Post properties not as expected") 2776 } 2777 } 2778 2779 // Import the post again. 2780 if err := th.App.ImportDirectPost(data, false); err != nil { 2781 t.Fatalf("Expected success.") 2782 } 2783 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2784 2785 // Check the post values. 2786 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil { 2787 t.Fatal(result.Err.Error()) 2788 } else { 2789 posts := result.Data.([]*model.Post) 2790 if len(posts) != 1 { 2791 t.Fatal("Unexpected number of posts found.") 2792 } 2793 post := posts[0] 2794 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id { 2795 t.Fatal("Post properties not as expected") 2796 } 2797 } 2798 2799 // Save the post with a different time. 2800 data.CreateAt = ptrInt64(*data.CreateAt + 1) 2801 if err := th.App.ImportDirectPost(data, false); err != nil { 2802 t.Fatalf("Expected success.") 2803 } 2804 AssertAllPostsCount(t, th.App, initialPostCount, 2, "") 2805 2806 // Save the post with a different message. 2807 data.Message = ptrStr("Message 2") 2808 if err := th.App.ImportDirectPost(data, false); err != nil { 2809 t.Fatalf("Expected success.") 2810 } 2811 AssertAllPostsCount(t, th.App, initialPostCount, 3, "") 2812 2813 // Test with hashtags 2814 data.Message = ptrStr("Message 2 #hashtagmashupcity") 2815 data.CreateAt = ptrInt64(*data.CreateAt + 1) 2816 if err := th.App.ImportDirectPost(data, false); err != nil { 2817 t.Fatalf("Expected success.") 2818 } 2819 AssertAllPostsCount(t, th.App, initialPostCount, 4, "") 2820 2821 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil { 2822 t.Fatal(result.Err.Error()) 2823 } else { 2824 posts := result.Data.([]*model.Post) 2825 if len(posts) != 1 { 2826 t.Fatal("Unexpected number of posts found.") 2827 } 2828 post := posts[0] 2829 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id { 2830 t.Fatal("Post properties not as expected") 2831 } 2832 if post.Hashtags != "#hashtagmashupcity" { 2833 t.Fatalf("Hashtags not as expected: %s", post.Hashtags) 2834 } 2835 } 2836 2837 // Test with some flags. 2838 data = &DirectPostImportData{ 2839 ChannelMembers: &[]string{ 2840 th.BasicUser.Username, 2841 th.BasicUser2.Username, 2842 }, 2843 FlaggedBy: &[]string{ 2844 th.BasicUser.Username, 2845 th.BasicUser2.Username, 2846 }, 2847 User: ptrStr(th.BasicUser.Username), 2848 Message: ptrStr("Message"), 2849 CreateAt: ptrInt64(model.GetMillis()), 2850 } 2851 2852 if err := th.App.ImportDirectPost(data, false); err != nil { 2853 t.Fatalf("Expected success: %v", err.Error()) 2854 } 2855 2856 // Check the post values. 2857 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil { 2858 t.Fatal(result.Err.Error()) 2859 } else { 2860 posts := result.Data.([]*model.Post) 2861 if len(posts) != 1 { 2862 t.Fatal("Unexpected number of posts found.") 2863 } 2864 post := posts[0] 2865 checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2866 checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2867 } 2868 2869 // ------------------ Group Channel ------------------------- 2870 2871 // Create the GROUP channel. 2872 user3 := th.CreateUser() 2873 channelData = DirectChannelImportData{ 2874 Members: &[]string{ 2875 th.BasicUser.Username, 2876 th.BasicUser2.Username, 2877 user3.Username, 2878 }, 2879 } 2880 if err := th.App.ImportDirectChannel(&channelData, false); err != nil { 2881 t.Fatalf("Expected success: %v", err.Error()) 2882 } 2883 2884 // Get the channel. 2885 var groupChannel *model.Channel 2886 userIds := []string{ 2887 th.BasicUser.Id, 2888 th.BasicUser2.Id, 2889 user3.Id, 2890 } 2891 if channel, err := th.App.createGroupChannel(userIds, th.BasicUser.Id); err.Id != store.CHANNEL_EXISTS_ERROR { 2892 t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR") 2893 } else { 2894 groupChannel = channel 2895 } 2896 2897 // Get the number of posts in the system. 2898 if result := <-th.App.Srv.Store.Post().AnalyticsPostCount("", false, false); result.Err != nil { 2899 t.Fatal(result.Err) 2900 } else { 2901 initialPostCount = result.Data.(int64) 2902 } 2903 2904 // Try adding an invalid post in dry run mode. 2905 data = &DirectPostImportData{ 2906 ChannelMembers: &[]string{ 2907 th.BasicUser.Username, 2908 th.BasicUser2.Username, 2909 user3.Username, 2910 }, 2911 User: ptrStr(th.BasicUser.Username), 2912 CreateAt: ptrInt64(model.GetMillis()), 2913 } 2914 if err := th.App.ImportDirectPost(data, true); err == nil { 2915 t.Fatalf("Expected error.") 2916 } 2917 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2918 2919 // Try adding a valid post in dry run mode. 2920 data = &DirectPostImportData{ 2921 ChannelMembers: &[]string{ 2922 th.BasicUser.Username, 2923 th.BasicUser2.Username, 2924 user3.Username, 2925 }, 2926 User: ptrStr(th.BasicUser.Username), 2927 Message: ptrStr("Message"), 2928 CreateAt: ptrInt64(model.GetMillis()), 2929 } 2930 if err := th.App.ImportDirectPost(data, true); err != nil { 2931 t.Fatalf("Expected success.") 2932 } 2933 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2934 2935 // Try adding an invalid post in apply mode. 2936 data = &DirectPostImportData{ 2937 ChannelMembers: &[]string{ 2938 th.BasicUser.Username, 2939 th.BasicUser2.Username, 2940 user3.Username, 2941 model.NewId(), 2942 }, 2943 User: ptrStr(th.BasicUser.Username), 2944 Message: ptrStr("Message"), 2945 CreateAt: ptrInt64(model.GetMillis()), 2946 } 2947 if err := th.App.ImportDirectPost(data, false); err == nil { 2948 t.Fatalf("Expected error.") 2949 } 2950 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2951 2952 // Try adding a valid post in apply mode. 2953 data = &DirectPostImportData{ 2954 ChannelMembers: &[]string{ 2955 th.BasicUser.Username, 2956 th.BasicUser2.Username, 2957 user3.Username, 2958 }, 2959 User: ptrStr(th.BasicUser.Username), 2960 Message: ptrStr("Message"), 2961 CreateAt: ptrInt64(model.GetMillis()), 2962 } 2963 if err := th.App.ImportDirectPost(data, false); err != nil { 2964 t.Fatalf("Expected success: %v", err.Error()) 2965 } 2966 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2967 2968 // Check the post values. 2969 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil { 2970 t.Fatal(result.Err.Error()) 2971 } else { 2972 posts := result.Data.([]*model.Post) 2973 if len(posts) != 1 { 2974 t.Fatal("Unexpected number of posts found.") 2975 } 2976 post := posts[0] 2977 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id { 2978 t.Fatal("Post properties not as expected") 2979 } 2980 } 2981 2982 // Import the post again. 2983 if err := th.App.ImportDirectPost(data, false); err != nil { 2984 t.Fatalf("Expected success.") 2985 } 2986 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2987 2988 // Check the post values. 2989 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil { 2990 t.Fatal(result.Err.Error()) 2991 } else { 2992 posts := result.Data.([]*model.Post) 2993 if len(posts) != 1 { 2994 t.Fatal("Unexpected number of posts found.") 2995 } 2996 post := posts[0] 2997 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id { 2998 t.Fatal("Post properties not as expected") 2999 } 3000 } 3001 3002 // Save the post with a different time. 3003 data.CreateAt = ptrInt64(*data.CreateAt + 1) 3004 if err := th.App.ImportDirectPost(data, false); err != nil { 3005 t.Fatalf("Expected success.") 3006 } 3007 AssertAllPostsCount(t, th.App, initialPostCount, 2, "") 3008 3009 // Save the post with a different message. 3010 data.Message = ptrStr("Message 2") 3011 if err := th.App.ImportDirectPost(data, false); err != nil { 3012 t.Fatalf("Expected success.") 3013 } 3014 AssertAllPostsCount(t, th.App, initialPostCount, 3, "") 3015 3016 // Test with hashtags 3017 data.Message = ptrStr("Message 2 #hashtagmashupcity") 3018 data.CreateAt = ptrInt64(*data.CreateAt + 1) 3019 if err := th.App.ImportDirectPost(data, false); err != nil { 3020 t.Fatalf("Expected success.") 3021 } 3022 AssertAllPostsCount(t, th.App, initialPostCount, 4, "") 3023 3024 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil { 3025 t.Fatal(result.Err.Error()) 3026 } else { 3027 posts := result.Data.([]*model.Post) 3028 if len(posts) != 1 { 3029 t.Fatal("Unexpected number of posts found.") 3030 } 3031 post := posts[0] 3032 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id { 3033 t.Fatal("Post properties not as expected") 3034 } 3035 if post.Hashtags != "#hashtagmashupcity" { 3036 t.Fatalf("Hashtags not as expected: %s", post.Hashtags) 3037 } 3038 } 3039 3040 // Test with some flags. 3041 data = &DirectPostImportData{ 3042 ChannelMembers: &[]string{ 3043 th.BasicUser.Username, 3044 th.BasicUser2.Username, 3045 user3.Username, 3046 }, 3047 FlaggedBy: &[]string{ 3048 th.BasicUser.Username, 3049 th.BasicUser2.Username, 3050 }, 3051 User: ptrStr(th.BasicUser.Username), 3052 Message: ptrStr("Message"), 3053 CreateAt: ptrInt64(model.GetMillis()), 3054 } 3055 3056 if err := th.App.ImportDirectPost(data, false); err != nil { 3057 t.Fatalf("Expected success: %v", err.Error()) 3058 } 3059 3060 // Check the post values. 3061 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil { 3062 t.Fatal(result.Err.Error()) 3063 } else { 3064 posts := result.Data.([]*model.Post) 3065 if len(posts) != 1 { 3066 t.Fatal("Unexpected number of posts found.") 3067 } 3068 post := posts[0] 3069 checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 3070 checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 3071 } 3072 } 3073 3074 func TestImportImportLine(t *testing.T) { 3075 th := Setup() 3076 defer th.TearDown() 3077 3078 // Try import line with an invalid type. 3079 line := LineImportData{ 3080 Type: "gibberish", 3081 } 3082 3083 if err := th.App.ImportLine(line, false); err == nil { 3084 t.Fatalf("Expected an error when importing a line with invalid type.") 3085 } 3086 3087 // Try import line with team type but nil team. 3088 line.Type = "team" 3089 if err := th.App.ImportLine(line, false); err == nil { 3090 t.Fatalf("Expected an error when importing a line of type team with a nil team.") 3091 } 3092 3093 // Try import line with channel type but nil channel. 3094 line.Type = "channel" 3095 if err := th.App.ImportLine(line, false); err == nil { 3096 t.Fatalf("Expected an error when importing a line with type channel with a nil channel.") 3097 } 3098 3099 // Try import line with user type but nil user. 3100 line.Type = "user" 3101 if err := th.App.ImportLine(line, false); err == nil { 3102 t.Fatalf("Expected an error when importing a line with type uesr with a nil user.") 3103 } 3104 3105 // Try import line with post type but nil post. 3106 line.Type = "post" 3107 if err := th.App.ImportLine(line, false); err == nil { 3108 t.Fatalf("Expected an error when importing a line with type post with a nil post.") 3109 } 3110 3111 // Try import line with direct_channel type but nil direct_channel. 3112 line.Type = "direct_channel" 3113 if err := th.App.ImportLine(line, false); err == nil { 3114 t.Fatalf("Expected an error when importing a line with type direct_channel with a nil direct_channel.") 3115 } 3116 3117 // Try import line with direct_post type but nil direct_post. 3118 line.Type = "direct_post" 3119 if err := th.App.ImportLine(line, false); err == nil { 3120 t.Fatalf("Expected an error when importing a line with type direct_post with a nil direct_post.") 3121 } 3122 } 3123 3124 func TestImportBulkImport(t *testing.T) { 3125 th := Setup() 3126 defer th.TearDown() 3127 3128 teamName := model.NewId() 3129 channelName := model.NewId() 3130 username := model.NewId() 3131 username2 := model.NewId() 3132 username3 := model.NewId() 3133 3134 // Run bulk import with a valid 1 of everything. 3135 data1 := `{"type": "version", "version": 1} 3136 {"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}} 3137 {"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}} 3138 {"type": "user", "user": {"username": "` + username + `", "email": "` + username + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}} 3139 {"type": "user", "user": {"username": "` + username2 + `", "email": "` + username2 + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}} 3140 {"type": "user", "user": {"username": "` + username3 + `", "email": "` + username3 + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}} 3141 {"type": "post", "post": {"team": "` + teamName + `", "channel": "` + channelName + `", "user": "` + username + `", "message": "Hello World", "create_at": 123456789012}} 3142 {"type": "direct_channel", "direct_channel": {"members": ["` + username + `", "` + username2 + `"]}} 3143 {"type": "direct_channel", "direct_channel": {"members": ["` + username + `", "` + username2 + `", "` + username3 + `"]}} 3144 {"type": "direct_post", "direct_post": {"channel_members": ["` + username + `", "` + username2 + `"], "user": "` + username + `", "message": "Hello Direct Channel", "create_at": 123456789013}} 3145 {"type": "direct_post", "direct_post": {"channel_members": ["` + username + `", "` + username2 + `", "` + username3 + `"], "user": "` + username + `", "message": "Hello Group Channel", "create_at": 123456789014}}` 3146 3147 if err, line := th.App.BulkImport(strings.NewReader(data1), false, 2); err != nil || line != 0 { 3148 t.Fatalf("BulkImport should have succeeded: %v, %v", err.Error(), line) 3149 } 3150 3151 // Run bulk import using a string that contains a line with invalid json. 3152 data2 := `{"type": "version", "version": 1` 3153 if err, line := th.App.BulkImport(strings.NewReader(data2), false, 2); err == nil || line != 1 { 3154 t.Fatalf("Should have failed due to invalid JSON on line 1.") 3155 } 3156 3157 // Run bulk import using valid JSON but missing version line at the start. 3158 data3 := `{"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}} 3159 {"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}} 3160 {"type": "user", "user": {"username": "kufjgnkxkrhhfgbrip6qxkfsaa", "email": "kufjgnkxkrhhfgbrip6qxkfsaa@example.com"}} 3161 {"type": "user", "user": {"username": "bwshaim6qnc2ne7oqkd5b2s2rq", "email": "bwshaim6qnc2ne7oqkd5b2s2rq@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}}` 3162 if err, line := th.App.BulkImport(strings.NewReader(data3), false, 2); err == nil || line != 1 { 3163 t.Fatalf("Should have failed due to missing version line on line 1.") 3164 } 3165 } 3166 3167 func TestImportProcessImportDataFileVersionLine(t *testing.T) { 3168 data := LineImportData{ 3169 Type: "version", 3170 Version: ptrInt(1), 3171 } 3172 if version, err := processImportDataFileVersionLine(data); err != nil || version != 1 { 3173 t.Fatalf("Expected no error and version 1.") 3174 } 3175 3176 data.Type = "NotVersion" 3177 if _, err := processImportDataFileVersionLine(data); err == nil { 3178 t.Fatalf("Expected error on invalid version line.") 3179 } 3180 3181 data.Type = "version" 3182 data.Version = nil 3183 if _, err := processImportDataFileVersionLine(data); err == nil { 3184 t.Fatalf("Expected error on invalid version line.") 3185 } 3186 }