github.com/nhannv/mattermost-server@v5.11.1+incompatible/app/import_functions_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 15 "github.com/mattermost/mattermost-server/model" 16 "github.com/mattermost/mattermost-server/store" 17 "github.com/mattermost/mattermost-server/utils/fileutils" 18 ) 19 20 func TestImportImportScheme(t *testing.T) { 21 th := Setup(t) 22 defer th.TearDown() 23 24 // Mark the phase 2 permissions migration as completed. 25 <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) 26 27 defer func() { 28 <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) 29 }() 30 31 // Try importing an invalid scheme in dryRun mode. 32 data := SchemeImportData{ 33 Name: ptrStr(model.NewId()), 34 Scope: ptrStr("team"), 35 DefaultTeamUserRole: &RoleImportData{ 36 Name: ptrStr(model.NewId()), 37 DisplayName: ptrStr(model.NewId()), 38 }, 39 DefaultTeamAdminRole: &RoleImportData{ 40 Name: ptrStr(model.NewId()), 41 DisplayName: ptrStr(model.NewId()), 42 }, 43 DefaultChannelUserRole: &RoleImportData{ 44 Name: ptrStr(model.NewId()), 45 DisplayName: ptrStr(model.NewId()), 46 }, 47 DefaultChannelAdminRole: &RoleImportData{ 48 Name: ptrStr(model.NewId()), 49 DisplayName: ptrStr(model.NewId()), 50 }, 51 Description: ptrStr("description"), 52 } 53 54 if err := th.App.ImportScheme(&data, true); err == nil { 55 t.Fatalf("Should have failed to import.") 56 } 57 58 if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil { 59 t.Fatalf("Scheme should not have imported.") 60 } 61 62 // Try importing a valid scheme in dryRun mode. 63 data.DisplayName = ptrStr("display name") 64 65 if err := th.App.ImportScheme(&data, true); err != nil { 66 t.Fatalf("Should have succeeded.") 67 } 68 69 if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil { 70 t.Fatalf("Scheme should not have imported.") 71 } 72 73 // Try importing an invalid scheme. 74 data.DisplayName = nil 75 76 if err := th.App.ImportScheme(&data, false); err == nil { 77 t.Fatalf("Should have failed to import.") 78 } 79 80 if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil { 81 t.Fatalf("Scheme should not have imported.") 82 } 83 84 // Try importing a valid scheme with all params set. 85 data.DisplayName = ptrStr("display name") 86 87 if err := th.App.ImportScheme(&data, false); err != nil { 88 t.Fatalf("Should have succeeded.") 89 } 90 91 if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil { 92 t.Fatalf("Failed to import scheme: %v", res.Err) 93 } else { 94 scheme := res.Data.(*model.Scheme) 95 assert.Equal(t, *data.Name, scheme.Name) 96 assert.Equal(t, *data.DisplayName, scheme.DisplayName) 97 assert.Equal(t, *data.Description, scheme.Description) 98 assert.Equal(t, *data.Scope, scheme.Scope) 99 100 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamAdminRole); res.Err != nil { 101 t.Fatalf("Should have found the imported role.") 102 } else { 103 role := res.Data.(*model.Role) 104 assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName) 105 assert.False(t, role.BuiltIn) 106 assert.True(t, role.SchemeManaged) 107 } 108 109 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamUserRole); res.Err != nil { 110 t.Fatalf("Should have found the imported role.") 111 } else { 112 role := res.Data.(*model.Role) 113 assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName) 114 assert.False(t, role.BuiltIn) 115 assert.True(t, role.SchemeManaged) 116 } 117 118 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelAdminRole); res.Err != nil { 119 t.Fatalf("Should have found the imported role.") 120 } else { 121 role := res.Data.(*model.Role) 122 assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName) 123 assert.False(t, role.BuiltIn) 124 assert.True(t, role.SchemeManaged) 125 } 126 127 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelUserRole); res.Err != nil { 128 t.Fatalf("Should have found the imported role.") 129 } else { 130 role := res.Data.(*model.Role) 131 assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName) 132 assert.False(t, role.BuiltIn) 133 assert.True(t, role.SchemeManaged) 134 } 135 } 136 137 // Try modifying all the fields and re-importing. 138 data.DisplayName = ptrStr("new display name") 139 data.Description = ptrStr("new description") 140 141 if err := th.App.ImportScheme(&data, false); err != nil { 142 t.Fatalf("Should have succeeded: %v", err) 143 } 144 145 if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil { 146 t.Fatalf("Failed to import scheme: %v", res.Err) 147 } else { 148 scheme := res.Data.(*model.Scheme) 149 assert.Equal(t, *data.Name, scheme.Name) 150 assert.Equal(t, *data.DisplayName, scheme.DisplayName) 151 assert.Equal(t, *data.Description, scheme.Description) 152 assert.Equal(t, *data.Scope, scheme.Scope) 153 154 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamAdminRole); res.Err != nil { 155 t.Fatalf("Should have found the imported role.") 156 } else { 157 role := res.Data.(*model.Role) 158 assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName) 159 assert.False(t, role.BuiltIn) 160 assert.True(t, role.SchemeManaged) 161 } 162 163 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamUserRole); res.Err != nil { 164 t.Fatalf("Should have found the imported role.") 165 } else { 166 role := res.Data.(*model.Role) 167 assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName) 168 assert.False(t, role.BuiltIn) 169 assert.True(t, role.SchemeManaged) 170 } 171 172 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelAdminRole); res.Err != nil { 173 t.Fatalf("Should have found the imported role.") 174 } else { 175 role := res.Data.(*model.Role) 176 assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName) 177 assert.False(t, role.BuiltIn) 178 assert.True(t, role.SchemeManaged) 179 } 180 181 if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelUserRole); res.Err != nil { 182 t.Fatalf("Should have found the imported role.") 183 } else { 184 role := res.Data.(*model.Role) 185 assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName) 186 assert.False(t, role.BuiltIn) 187 assert.True(t, role.SchemeManaged) 188 } 189 } 190 191 // Try changing the scope of the scheme and reimporting. 192 data.Scope = ptrStr("channel") 193 194 if err := th.App.ImportScheme(&data, false); err == nil { 195 t.Fatalf("Should have failed to import.") 196 } 197 198 if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil { 199 t.Fatalf("Failed to import scheme: %v", res.Err) 200 } else { 201 scheme := res.Data.(*model.Scheme) 202 assert.Equal(t, *data.Name, scheme.Name) 203 assert.Equal(t, *data.DisplayName, scheme.DisplayName) 204 assert.Equal(t, *data.Description, scheme.Description) 205 assert.Equal(t, "team", scheme.Scope) 206 } 207 } 208 209 func TestImportImportRole(t *testing.T) { 210 th := Setup(t) 211 defer th.TearDown() 212 213 // Try importing an invalid role in dryRun mode. 214 rid1 := model.NewId() 215 data := RoleImportData{ 216 Name: &rid1, 217 } 218 219 if err := th.App.ImportRole(&data, true, false); err == nil { 220 t.Fatalf("Should have failed to import.") 221 } 222 223 if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil { 224 t.Fatalf("Role should not have imported.") 225 } 226 227 // Try importing the valid role in dryRun mode. 228 data.DisplayName = ptrStr("display name") 229 230 if err := th.App.ImportRole(&data, true, false); err != nil { 231 t.Fatalf("Should have succeeded.") 232 } 233 234 if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil { 235 t.Fatalf("Role should not have imported as we are in dry run mode.") 236 } 237 238 // Try importing an invalid role. 239 data.DisplayName = nil 240 241 if err := th.App.ImportRole(&data, false, false); err == nil { 242 t.Fatalf("Should have failed to import.") 243 } 244 245 if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil { 246 t.Fatalf("Role should not have imported.") 247 } 248 249 // Try importing a valid role with all params set. 250 data.DisplayName = ptrStr("display name") 251 data.Description = ptrStr("description") 252 data.Permissions = &[]string{"invite_user", "add_user_to_team"} 253 254 if err := th.App.ImportRole(&data, false, false); err != nil { 255 t.Fatalf("Should have succeeded.") 256 } 257 258 if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil { 259 t.Fatalf("Should have found the imported role.") 260 } else { 261 role := res.Data.(*model.Role) 262 assert.Equal(t, *data.Name, role.Name) 263 assert.Equal(t, *data.DisplayName, role.DisplayName) 264 assert.Equal(t, *data.Description, role.Description) 265 assert.Equal(t, *data.Permissions, role.Permissions) 266 assert.False(t, role.BuiltIn) 267 assert.False(t, role.SchemeManaged) 268 } 269 270 // Try changing all the params and reimporting. 271 data.DisplayName = ptrStr("new display name") 272 data.Description = ptrStr("description") 273 data.Permissions = &[]string{"use_slash_commands"} 274 275 if err := th.App.ImportRole(&data, false, true); err != nil { 276 t.Fatalf("Should have succeeded. %v", err) 277 } 278 279 if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil { 280 t.Fatalf("Should have found the imported role.") 281 } else { 282 role := res.Data.(*model.Role) 283 assert.Equal(t, *data.Name, role.Name) 284 assert.Equal(t, *data.DisplayName, role.DisplayName) 285 assert.Equal(t, *data.Description, role.Description) 286 assert.Equal(t, *data.Permissions, role.Permissions) 287 assert.False(t, role.BuiltIn) 288 assert.True(t, role.SchemeManaged) 289 } 290 291 // Check that re-importing with only required fields doesn't update the others. 292 data2 := RoleImportData{ 293 Name: &rid1, 294 DisplayName: ptrStr("new display name again"), 295 } 296 297 if err := th.App.ImportRole(&data2, false, false); err != nil { 298 t.Fatalf("Should have succeeded.") 299 } 300 301 if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil { 302 t.Fatalf("Should have found the imported role.") 303 } else { 304 role := res.Data.(*model.Role) 305 assert.Equal(t, *data2.Name, role.Name) 306 assert.Equal(t, *data2.DisplayName, role.DisplayName) 307 assert.Equal(t, *data.Description, role.Description) 308 assert.Equal(t, *data.Permissions, role.Permissions) 309 assert.False(t, role.BuiltIn) 310 assert.False(t, role.SchemeManaged) 311 } 312 } 313 314 func TestImportImportTeam(t *testing.T) { 315 th := Setup(t) 316 defer th.TearDown() 317 318 // Mark the phase 2 permissions migration as completed. 319 <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) 320 321 defer func() { 322 <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) 323 }() 324 325 scheme1 := th.SetupTeamScheme() 326 scheme2 := th.SetupTeamScheme() 327 328 // Check how many teams are in the database. 329 var teamsCount int64 330 if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil { 331 teamsCount = r.Data.(int64) 332 } else { 333 t.Fatalf("Failed to get team count.") 334 } 335 336 data := TeamImportData{ 337 Name: ptrStr(model.NewId()), 338 DisplayName: ptrStr("Display Name"), 339 Type: ptrStr("XYZ"), 340 Description: ptrStr("The team description."), 341 AllowOpenInvite: ptrBool(true), 342 Scheme: &scheme1.Name, 343 } 344 345 // Try importing an invalid team in dryRun mode. 346 if err := th.App.ImportTeam(&data, true); err == nil { 347 t.Fatalf("Should have received an error importing an invalid team.") 348 } 349 350 // Do a valid team in dry-run mode. 351 data.Type = ptrStr("O") 352 if err := th.App.ImportTeam(&data, true); err != nil { 353 t.Fatalf("Received an error validating valid team.") 354 } 355 356 // Check that no more teams are in the DB. 357 th.CheckTeamCount(t, teamsCount) 358 359 // Do an invalid team in apply mode, check db changes. 360 data.Type = ptrStr("XYZ") 361 if err := th.App.ImportTeam(&data, false); err == nil { 362 t.Fatalf("Import should have failed on invalid team.") 363 } 364 365 // Check that no more teams are in the DB. 366 th.CheckTeamCount(t, teamsCount) 367 368 // Do a valid team in apply mode, check db changes. 369 data.Type = ptrStr("O") 370 if err := th.App.ImportTeam(&data, false); err != nil { 371 t.Fatalf("Received an error importing valid team: %v", err) 372 } 373 374 // Check that one more team is in the DB. 375 th.CheckTeamCount(t, teamsCount+1) 376 377 // Get the team and check that all the fields are correct. 378 if team, err := th.App.GetTeamByName(*data.Name); err != nil { 379 t.Fatalf("Failed to get team from database.") 380 } else { 381 assert.Equal(t, *data.DisplayName, team.DisplayName) 382 assert.Equal(t, *data.Type, team.Type) 383 assert.Equal(t, *data.Description, team.Description) 384 assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite) 385 assert.Equal(t, scheme1.Id, *team.SchemeId) 386 } 387 388 // Alter all the fields of that team (apart from unique identifier) and import again. 389 data.DisplayName = ptrStr("Display Name 2") 390 data.Type = ptrStr("P") 391 data.Description = ptrStr("The new description") 392 data.AllowOpenInvite = ptrBool(false) 393 data.Scheme = &scheme2.Name 394 395 // Check that the original number of teams are again in the DB (because this query doesn't include deleted). 396 data.Type = ptrStr("O") 397 if err := th.App.ImportTeam(&data, false); err != nil { 398 t.Fatalf("Received an error importing updated valid team.") 399 } 400 401 th.CheckTeamCount(t, teamsCount+1) 402 403 // Get the team and check that all fields are correct. 404 if team, err := th.App.GetTeamByName(*data.Name); err != nil { 405 t.Fatalf("Failed to get team from database.") 406 } else { 407 assert.Equal(t, *data.DisplayName, team.DisplayName) 408 assert.Equal(t, *data.Type, team.Type) 409 assert.Equal(t, *data.Description, team.Description) 410 assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite) 411 assert.Equal(t, scheme2.Id, *team.SchemeId) 412 } 413 } 414 415 func TestImportImportChannel(t *testing.T) { 416 th := Setup(t) 417 defer th.TearDown() 418 419 // Mark the phase 2 permissions migration as completed. 420 <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) 421 422 defer func() { 423 <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) 424 }() 425 426 scheme1 := th.SetupChannelScheme() 427 scheme2 := th.SetupChannelScheme() 428 429 // Import a Team. 430 teamName := model.NewId() 431 th.App.ImportTeam(&TeamImportData{ 432 Name: &teamName, 433 DisplayName: ptrStr("Display Name"), 434 Type: ptrStr("O"), 435 }, false) 436 team, err := th.App.GetTeamByName(teamName) 437 if err != nil { 438 t.Fatalf("Failed to get team from database.") 439 } 440 441 // Check how many channels are in the database. 442 var channelCount int64 443 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil { 444 channelCount = r.Data.(int64) 445 } else { 446 t.Fatalf("Failed to get team count.") 447 } 448 449 // Do an invalid channel in dry-run mode. 450 data := ChannelImportData{ 451 Team: &teamName, 452 DisplayName: ptrStr("Display Name"), 453 Type: ptrStr("O"), 454 Header: ptrStr("Channe Header"), 455 Purpose: ptrStr("Channel Purpose"), 456 Scheme: &scheme1.Name, 457 } 458 if err := th.App.ImportChannel(&data, true); err == nil { 459 t.Fatalf("Expected error due to invalid name.") 460 } 461 462 // Check that no more channels are in the DB. 463 th.CheckChannelsCount(t, channelCount) 464 465 // Do a valid channel with a nonexistent team in dry-run mode. 466 data.Name = ptrStr("channelname") 467 data.Team = ptrStr(model.NewId()) 468 if err := th.App.ImportChannel(&data, true); err != nil { 469 t.Fatalf("Expected success as cannot validate channel name in dry run mode.") 470 } 471 472 // Check that no more channels are in the DB. 473 th.CheckChannelsCount(t, channelCount) 474 475 // Do a valid channel in dry-run mode. 476 data.Team = &teamName 477 if err := th.App.ImportChannel(&data, true); err != nil { 478 t.Fatalf("Expected success as valid team.") 479 } 480 481 // Check that no more channels are in the DB. 482 th.CheckChannelsCount(t, channelCount) 483 484 // Do an invalid channel in apply mode. 485 data.Name = nil 486 if err := th.App.ImportChannel(&data, false); err == nil { 487 t.Fatalf("Expected error due to invalid name (apply mode).") 488 } 489 490 // Check that no more channels are in the DB. 491 th.CheckChannelsCount(t, channelCount) 492 493 // Do a valid channel in apply mode with a non-existent team. 494 data.Name = ptrStr("channelname") 495 data.Team = ptrStr(model.NewId()) 496 if err := th.App.ImportChannel(&data, false); err == nil { 497 t.Fatalf("Expected error due to non-existent team (apply mode).") 498 } 499 500 // Check that no more channels are in the DB. 501 th.CheckChannelsCount(t, channelCount) 502 503 // Do a valid channel in apply mode. 504 data.Team = &teamName 505 if err := th.App.ImportChannel(&data, false); err != nil { 506 t.Fatalf("Expected success in apply mode: %v", err.Error()) 507 } 508 509 // Check that 1 more channel is in the DB. 510 th.CheckChannelsCount(t, channelCount+1) 511 512 // Get the Channel and check all the fields are correct. 513 if channel, err := th.App.GetChannelByName(*data.Name, team.Id, false); err != nil { 514 t.Fatalf("Failed to get channel from database.") 515 } else { 516 assert.Equal(t, *data.Name, channel.Name) 517 assert.Equal(t, *data.DisplayName, channel.DisplayName) 518 assert.Equal(t, *data.Type, channel.Type) 519 assert.Equal(t, *data.Header, channel.Header) 520 assert.Equal(t, *data.Purpose, channel.Purpose) 521 assert.Equal(t, scheme1.Id, *channel.SchemeId) 522 } 523 524 // Alter all the fields of that channel. 525 data.DisplayName = ptrStr("Chaned Disp Name") 526 data.Type = ptrStr(model.CHANNEL_PRIVATE) 527 data.Header = ptrStr("New Header") 528 data.Purpose = ptrStr("New Purpose") 529 data.Scheme = &scheme2.Name 530 if err := th.App.ImportChannel(&data, false); err != nil { 531 t.Fatalf("Expected success in apply mode: %v", err.Error()) 532 } 533 534 // Check channel count the same. 535 th.CheckChannelsCount(t, channelCount) 536 537 // Get the Channel and check all the fields are correct. 538 if channel, err := th.App.GetChannelByName(*data.Name, team.Id, false); err != nil { 539 t.Fatalf("Failed to get channel from database.") 540 } else { 541 assert.Equal(t, *data.Name, channel.Name) 542 assert.Equal(t, *data.DisplayName, channel.DisplayName) 543 assert.Equal(t, *data.Type, channel.Type) 544 assert.Equal(t, *data.Header, channel.Header) 545 assert.Equal(t, *data.Purpose, channel.Purpose) 546 assert.Equal(t, scheme2.Id, *channel.SchemeId) 547 } 548 549 } 550 551 func TestImportImportUser(t *testing.T) { 552 th := Setup(t) 553 defer th.TearDown() 554 555 // Check how many users are in the database. 556 var userCount int64 557 if r := <-th.App.Srv.Store.User().Count(model.UserCountOptions{ 558 IncludeDeleted: true, 559 IncludeBotAccounts: false, 560 }); r.Err == nil { 561 userCount = r.Data.(int64) 562 } else { 563 t.Fatalf("Failed to get user count.") 564 } 565 566 // Do an invalid user in dry-run mode. 567 data := UserImportData{ 568 Username: ptrStr(model.NewId()), 569 } 570 if err := th.App.ImportUser(&data, true); err == nil { 571 t.Fatalf("Should have failed to import invalid user.") 572 } 573 574 // Check that no more users are in the DB. 575 if r := <-th.App.Srv.Store.User().Count(model.UserCountOptions{ 576 IncludeDeleted: true, 577 IncludeBotAccounts: false, 578 }); r.Err == nil { 579 if r.Data.(int64) != userCount { 580 t.Fatalf("Unexpected number of users") 581 } 582 } else { 583 t.Fatalf("Failed to get user count.") 584 } 585 586 // Do a valid user in dry-run mode. 587 data = UserImportData{ 588 Username: ptrStr(model.NewId()), 589 Email: ptrStr(model.NewId() + "@example.com"), 590 } 591 if err := th.App.ImportUser(&data, true); err != nil { 592 t.Fatalf("Should have succeeded to import valid user.") 593 } 594 595 // Check that no more users are in the DB. 596 if r := <-th.App.Srv.Store.User().Count(model.UserCountOptions{ 597 IncludeDeleted: true, 598 IncludeBotAccounts: false, 599 }); r.Err == nil { 600 if r.Data.(int64) != userCount { 601 t.Fatalf("Unexpected number of users") 602 } 603 } else { 604 t.Fatalf("Failed to get user count.") 605 } 606 607 // Do an invalid user in apply mode. 608 data = UserImportData{ 609 Username: ptrStr(model.NewId()), 610 } 611 if err := th.App.ImportUser(&data, false); err == nil { 612 t.Fatalf("Should have failed to import invalid user.") 613 } 614 615 // Check that no more users are in the DB. 616 if r := <-th.App.Srv.Store.User().Count(model.UserCountOptions{ 617 IncludeDeleted: true, 618 IncludeBotAccounts: false, 619 }); r.Err == nil { 620 if r.Data.(int64) != userCount { 621 t.Fatalf("Unexpected number of users") 622 } 623 } else { 624 t.Fatalf("Failed to get user count.") 625 } 626 627 // Do a valid user in apply mode. 628 username := model.NewId() 629 testsDir, _ := fileutils.FindDir("tests") 630 data = UserImportData{ 631 ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")), 632 Username: &username, 633 Email: ptrStr(model.NewId() + "@example.com"), 634 Nickname: ptrStr(model.NewId()), 635 FirstName: ptrStr(model.NewId()), 636 LastName: ptrStr(model.NewId()), 637 Position: ptrStr(model.NewId()), 638 } 639 if err := th.App.ImportUser(&data, false); err != nil { 640 t.Fatalf("Should have succeeded to import valid user.") 641 } 642 643 // Check that one more user is in the DB. 644 if r := <-th.App.Srv.Store.User().Count(model.UserCountOptions{ 645 IncludeDeleted: true, 646 IncludeBotAccounts: false, 647 }); r.Err == nil { 648 if r.Data.(int64) != userCount+1 { 649 t.Fatalf("Unexpected number of users") 650 } 651 } else { 652 t.Fatalf("Failed to get user count.") 653 } 654 655 // Get the user and check all the fields are correct. 656 if user, err := th.App.GetUserByUsername(username); err != nil { 657 t.Fatalf("Failed to get user from database.") 658 } else { 659 if user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position { 660 t.Fatalf("User properties do not match Import Data.") 661 } 662 // Check calculated properties. 663 if user.AuthService != "" { 664 t.Fatalf("Expected Auth Service to be empty.") 665 } 666 667 if !(user.AuthData == nil || *user.AuthData == "") { 668 t.Fatalf("Expected AuthData to be empty.") 669 } 670 671 if len(user.Password) == 0 { 672 t.Fatalf("Expected password to be set.") 673 } 674 675 if !user.EmailVerified { 676 t.Fatalf("Expected EmailVerified to be true.") 677 } 678 679 if user.Locale != *th.App.Config().LocalizationSettings.DefaultClientLocale { 680 t.Fatalf("Expected Locale to be the default.") 681 } 682 683 if user.Roles != "system_user" { 684 t.Fatalf("Expected roles to be system_user") 685 } 686 } 687 688 // Alter all the fields of that user. 689 data.Email = ptrStr(model.NewId() + "@example.com") 690 data.ProfileImage = ptrStr(filepath.Join(testsDir, "testgif.gif")) 691 data.AuthService = ptrStr("ldap") 692 data.AuthData = &username 693 data.Nickname = ptrStr(model.NewId()) 694 data.FirstName = ptrStr(model.NewId()) 695 data.LastName = ptrStr(model.NewId()) 696 data.Position = ptrStr(model.NewId()) 697 data.Roles = ptrStr("system_admin system_user") 698 data.Locale = ptrStr("zh_CN") 699 if err := th.App.ImportUser(&data, false); err != nil { 700 t.Fatalf("Should have succeeded to update valid user %v", err) 701 } 702 703 // Check user count the same. 704 if r := <-th.App.Srv.Store.User().Count(model.UserCountOptions{ 705 IncludeDeleted: true, 706 IncludeBotAccounts: false, 707 }); r.Err == nil { 708 if r.Data.(int64) != userCount+1 { 709 t.Fatalf("Unexpected number of users") 710 } 711 } else { 712 t.Fatalf("Failed to get user count.") 713 } 714 715 // Get the user and check all the fields are correct. 716 if user, err := th.App.GetUserByUsername(username); err != nil { 717 t.Fatalf("Failed to get user from database.") 718 } else { 719 if user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position { 720 t.Fatalf("Updated User properties do not match Import Data.") 721 } 722 // Check calculated properties. 723 if user.AuthService != "ldap" { 724 t.Fatalf("Expected Auth Service to be ldap \"%v\"", user.AuthService) 725 } 726 727 if !(user.AuthData == data.AuthData || *user.AuthData == *data.AuthData) { 728 t.Fatalf("Expected AuthData to be set.") 729 } 730 731 if len(user.Password) != 0 { 732 t.Fatalf("Expected password to be empty.") 733 } 734 735 if !user.EmailVerified { 736 t.Fatalf("Expected EmailVerified to be true.") 737 } 738 739 if user.Locale != *data.Locale { 740 t.Fatalf("Expected Locale to be the set.") 741 } 742 743 if user.Roles != *data.Roles { 744 t.Fatalf("Expected roles to be set: %v", user.Roles) 745 } 746 } 747 748 // Check Password and AuthData together. 749 data.Password = ptrStr("PasswordTest") 750 if err := th.App.ImportUser(&data, false); err == nil { 751 t.Fatalf("Should have failed to import invalid user.") 752 } 753 754 data.AuthData = nil 755 if err := th.App.ImportUser(&data, false); err != nil { 756 t.Fatalf("Should have succeeded to update valid user %v", err) 757 } 758 759 data.Password = ptrStr("") 760 if err := th.App.ImportUser(&data, false); err == nil { 761 t.Fatalf("Should have failed to import invalid user.") 762 } 763 764 data.Password = ptrStr(strings.Repeat("0123456789", 10)) 765 if err := th.App.ImportUser(&data, false); err == nil { 766 t.Fatalf("Should have failed to import invalid user.") 767 } 768 769 data.Password = ptrStr("TestPassword") 770 771 // Test team and channel memberships 772 teamName := model.NewId() 773 th.App.ImportTeam(&TeamImportData{ 774 Name: &teamName, 775 DisplayName: ptrStr("Display Name"), 776 Type: ptrStr("O"), 777 }, false) 778 team, err := th.App.GetTeamByName(teamName) 779 if err != nil { 780 t.Fatalf("Failed to get team from database.") 781 } 782 783 channelName := model.NewId() 784 th.App.ImportChannel(&ChannelImportData{ 785 Team: &teamName, 786 Name: &channelName, 787 DisplayName: ptrStr("Display Name"), 788 Type: ptrStr("O"), 789 }, false) 790 channel, err := th.App.GetChannelByName(channelName, team.Id, false) 791 if err != nil { 792 t.Fatalf("Failed to get channel from database.") 793 } 794 795 username = model.NewId() 796 data = UserImportData{ 797 Username: &username, 798 Email: ptrStr(model.NewId() + "@example.com"), 799 Nickname: ptrStr(model.NewId()), 800 FirstName: ptrStr(model.NewId()), 801 LastName: ptrStr(model.NewId()), 802 Position: ptrStr(model.NewId()), 803 } 804 805 teamMembers, err := th.App.GetTeamMembers(team.Id, 0, 1000) 806 if err != nil { 807 t.Fatalf("Failed to get team member count") 808 } 809 teamMemberCount := len(teamMembers) 810 811 channelMemberCount, err := th.App.GetChannelMemberCount(channel.Id) 812 if err != nil { 813 t.Fatalf("Failed to get channel member count") 814 } 815 816 // Test with an invalid team & channel membership in dry-run mode. 817 data.Teams = &[]UserTeamImportData{ 818 { 819 Roles: ptrStr("invalid"), 820 Channels: &[]UserChannelImportData{ 821 { 822 Roles: ptrStr("invalid"), 823 }, 824 }, 825 }, 826 } 827 err = th.App.ImportUser(&data, true) 828 assert.NotNil(t, err) 829 830 // Test with an unknown team name & invalid channel membership in dry-run mode. 831 data.Teams = &[]UserTeamImportData{ 832 { 833 Name: ptrStr(model.NewId()), 834 Channels: &[]UserChannelImportData{ 835 { 836 Roles: ptrStr("invalid"), 837 }, 838 }, 839 }, 840 } 841 err = th.App.ImportUser(&data, true) 842 assert.NotNil(t, err) 843 844 // Test with a valid team & invalid channel membership in dry-run mode. 845 data.Teams = &[]UserTeamImportData{ 846 { 847 Name: &teamName, 848 Channels: &[]UserChannelImportData{ 849 { 850 Roles: ptrStr("invalid"), 851 }, 852 }, 853 }, 854 } 855 err = th.App.ImportUser(&data, true) 856 assert.NotNil(t, err) 857 858 // Test with a valid team & unknown channel name in dry-run mode. 859 data.Teams = &[]UserTeamImportData{ 860 { 861 Name: &teamName, 862 Channels: &[]UserChannelImportData{ 863 { 864 Name: ptrStr(model.NewId()), 865 }, 866 }, 867 }, 868 } 869 err = th.App.ImportUser(&data, true) 870 assert.Nil(t, err) 871 872 // Test with a valid team & valid channel name in dry-run mode. 873 data.Teams = &[]UserTeamImportData{ 874 { 875 Name: &teamName, 876 Channels: &[]UserChannelImportData{ 877 { 878 Name: &channelName, 879 }, 880 }, 881 }, 882 } 883 err = th.App.ImportUser(&data, true) 884 assert.Nil(t, err) 885 886 // Check no new member objects were created because dry run mode. 887 tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000) 888 require.Nil(t, err, "Failed to get Team Member Count") 889 require.Len(t, tmc, teamMemberCount, "Number of team members not as expected") 890 891 cmc, err := th.App.GetChannelMemberCount(channel.Id) 892 require.Nil(t, err, "Failed to get Channel Member Count") 893 require.Equal(t, channelMemberCount, cmc, "Number of channel members not as expected") 894 895 // Test with an invalid team & channel membership in apply mode. 896 data.Teams = &[]UserTeamImportData{ 897 { 898 Roles: ptrStr("invalid"), 899 Channels: &[]UserChannelImportData{ 900 { 901 Roles: ptrStr("invalid"), 902 }, 903 }, 904 }, 905 } 906 err = th.App.ImportUser(&data, false) 907 assert.NotNil(t, err) 908 909 // Test with an unknown team name & invalid channel membership in apply mode. 910 data.Teams = &[]UserTeamImportData{ 911 { 912 Name: ptrStr(model.NewId()), 913 Channels: &[]UserChannelImportData{ 914 { 915 Roles: ptrStr("invalid"), 916 }, 917 }, 918 }, 919 } 920 err = th.App.ImportUser(&data, false) 921 assert.NotNil(t, err) 922 923 // Test with a valid team & invalid channel membership in apply mode. 924 data.Teams = &[]UserTeamImportData{ 925 { 926 Name: &teamName, 927 Channels: &[]UserChannelImportData{ 928 { 929 Roles: ptrStr("invalid"), 930 }, 931 }, 932 }, 933 } 934 err = th.App.ImportUser(&data, false) 935 assert.NotNil(t, err) 936 937 // Check no new member objects were created because all tests should have failed so far. 938 tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000) 939 require.Nil(t, err, "Failed to get Team Member Count") 940 require.Len(t, tmc, teamMemberCount) 941 942 cmc, err = th.App.GetChannelMemberCount(channel.Id) 943 require.Nil(t, err, "Failed to get Channel Member Count") 944 require.Equal(t, channelMemberCount, cmc) 945 946 // Test with a valid team & unknown channel name in apply mode. 947 data.Teams = &[]UserTeamImportData{ 948 { 949 Name: &teamName, 950 Channels: &[]UserChannelImportData{ 951 { 952 Name: ptrStr(model.NewId()), 953 }, 954 }, 955 }, 956 } 957 err = th.App.ImportUser(&data, false) 958 assert.NotNil(t, err) 959 960 // Check only new team member object created because dry run mode. 961 tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000) 962 require.Nil(t, err, "Failed to get Team Member Count") 963 require.Len(t, tmc, teamMemberCount+1) 964 965 cmc, err = th.App.GetChannelMemberCount(channel.Id) 966 require.Nil(t, err, "Failed to get Channel Member Count") 967 require.Equal(t, channelMemberCount, cmc) 968 969 // Check team member properties. 970 user, err := th.App.GetUserByUsername(username) 971 if err != nil { 972 t.Fatalf("Failed to get user from database.") 973 } 974 975 teamMember, err := th.App.GetTeamMember(team.Id, user.Id) 976 require.Nil(t, err, "Failed to get team member from database.") 977 require.Equal(t, "team_user", teamMember.Roles) 978 979 // Test with a valid team & valid channel name in apply mode. 980 data.Teams = &[]UserTeamImportData{ 981 { 982 Name: &teamName, 983 Channels: &[]UserChannelImportData{ 984 { 985 Name: &channelName, 986 }, 987 }, 988 }, 989 } 990 err = th.App.ImportUser(&data, false) 991 assert.Nil(t, err) 992 993 // Check only new channel member object created because dry run mode. 994 tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000) 995 require.Nil(t, err, "Failed to get Team Member Count") 996 require.Len(t, tmc, teamMemberCount+1, "Number of team members not as expected") 997 998 cmc, err = th.App.GetChannelMemberCount(channel.Id) 999 require.Nil(t, err, "Failed to get Channel Member Count") 1000 require.Equal(t, channelMemberCount+1, cmc, "Number of channel members not as expected") 1001 1002 // Check channel member properties. 1003 channelMember, err := th.App.GetChannelMember(channel.Id, user.Id) 1004 require.Nil(t, err, "Failed to get channel member from database.") 1005 assert.Equal(t, "channel_user", channelMember.Roles) 1006 assert.Equal(t, "default", channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP]) 1007 assert.Equal(t, "default", channelMember.NotifyProps[model.PUSH_NOTIFY_PROP]) 1008 assert.Equal(t, "all", channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP]) 1009 1010 // Test with the properties of the team and channel membership changed. 1011 data.Teams = &[]UserTeamImportData{ 1012 { 1013 Name: &teamName, 1014 Theme: ptrStr(`{"awayIndicator":"#DBBD4E","buttonBg":"#23A1FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBg":"#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"}`), 1015 Roles: ptrStr("team_user team_admin"), 1016 Channels: &[]UserChannelImportData{ 1017 { 1018 Name: &channelName, 1019 Roles: ptrStr("channel_user channel_admin"), 1020 NotifyProps: &UserChannelNotifyPropsImportData{ 1021 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 1022 Mobile: ptrStr(model.USER_NOTIFY_MENTION), 1023 MarkUnread: ptrStr(model.USER_NOTIFY_MENTION), 1024 }, 1025 Favorite: ptrBool(true), 1026 }, 1027 }, 1028 }, 1029 } 1030 err = th.App.ImportUser(&data, false) 1031 assert.Nil(t, err) 1032 1033 // Check both member properties. 1034 teamMember, err = th.App.GetTeamMember(team.Id, user.Id) 1035 require.Nil(t, err, "Failed to get team member from database.") 1036 require.Equal(t, "team_user team_admin", teamMember.Roles) 1037 1038 channelMember, err = th.App.GetChannelMember(channel.Id, user.Id) 1039 require.Nil(t, err, "Failed to get channel member Desktop from database.") 1040 assert.Equal(t, "channel_user channel_admin", channelMember.Roles) 1041 assert.Equal(t, model.USER_NOTIFY_MENTION, channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP]) 1042 assert.Equal(t, model.USER_NOTIFY_MENTION, channelMember.NotifyProps[model.PUSH_NOTIFY_PROP]) 1043 assert.Equal(t, model.USER_NOTIFY_MENTION, channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP]) 1044 1045 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true") 1046 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, team.Id, *(*data.Teams)[0].Theme) 1047 1048 // No more new member objects. 1049 tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000) 1050 require.Nil(t, err, "Failed to get Team Member Count") 1051 require.Len(t, tmc, teamMemberCount+1, "Number of team members not as expected") 1052 1053 cmc, err = th.App.GetChannelMemberCount(channel.Id) 1054 require.Nil(t, err, "Failed to get Channel Member Count") 1055 require.Equal(t, channelMemberCount+1, cmc, "Number of channel members not as expected") 1056 1057 // Add a user with some preferences. 1058 username = model.NewId() 1059 data = UserImportData{ 1060 Username: &username, 1061 Email: ptrStr(model.NewId() + "@example.com"), 1062 Theme: ptrStr(`{"awayIndicator":"#DCBD4E","buttonBg":"#23A2FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBg":"#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"}`), 1063 UseMilitaryTime: ptrStr("true"), 1064 CollapsePreviews: ptrStr("true"), 1065 MessageDisplay: ptrStr("compact"), 1066 ChannelDisplayMode: ptrStr("centered"), 1067 TutorialStep: ptrStr("3"), 1068 UseMarkdownPreview: ptrStr("true"), 1069 UseFormatting: ptrStr("true"), 1070 ShowUnreadSection: ptrStr("true"), 1071 EmailInterval: ptrStr("immediately"), 1072 } 1073 err = th.App.ImportUser(&data, false) 1074 assert.Nil(t, err) 1075 1076 // Check their values. 1077 user, err = th.App.GetUserByUsername(username) 1078 if err != nil { 1079 t.Fatalf("Failed to get user from database.") 1080 } 1081 1082 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme) 1083 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_USE_MILITARY_TIME, *data.UseMilitaryTime) 1084 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSE_SETTING, *data.CollapsePreviews) 1085 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_MESSAGE_DISPLAY, *data.MessageDisplay) 1086 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_CHANNEL_DISPLAY_MODE, *data.ChannelDisplayMode) 1087 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep) 1088 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_ADVANCED_SETTINGS, "feature_enabled_markdown_preview", *data.UseMarkdownPreview) 1089 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_ADVANCED_SETTINGS, "formatting", *data.UseFormatting) 1090 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_SIDEBAR_SETTINGS, "show_unread_section", *data.ShowUnreadSection) 1091 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL, "30") 1092 1093 // Change those preferences. 1094 data = UserImportData{ 1095 Username: &username, 1096 Email: ptrStr(model.NewId() + "@example.com"), 1097 Theme: ptrStr(`{"awayIndicator":"#123456","buttonBg":"#23A2FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBg":"#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"}`), 1098 UseMilitaryTime: ptrStr("false"), 1099 CollapsePreviews: ptrStr("false"), 1100 MessageDisplay: ptrStr("clean"), 1101 ChannelDisplayMode: ptrStr("full"), 1102 TutorialStep: ptrStr("2"), 1103 EmailInterval: ptrStr("hour"), 1104 } 1105 err = th.App.ImportUser(&data, false) 1106 assert.Nil(t, err) 1107 1108 // Check their values again. 1109 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme) 1110 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_USE_MILITARY_TIME, *data.UseMilitaryTime) 1111 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSE_SETTING, *data.CollapsePreviews) 1112 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_MESSAGE_DISPLAY, *data.MessageDisplay) 1113 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_CHANNEL_DISPLAY_MODE, *data.ChannelDisplayMode) 1114 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep) 1115 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL, "3600") 1116 1117 // Set Notify Without mention keys 1118 data.NotifyProps = &UserNotifyPropsImportData{ 1119 Desktop: ptrStr(model.USER_NOTIFY_ALL), 1120 DesktopSound: ptrStr("true"), 1121 Email: ptrStr("true"), 1122 Mobile: ptrStr(model.USER_NOTIFY_ALL), 1123 MobilePushStatus: ptrStr(model.STATUS_ONLINE), 1124 ChannelTrigger: ptrStr("true"), 1125 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ROOT), 1126 } 1127 err = th.App.ImportUser(&data, false) 1128 assert.Nil(t, err) 1129 1130 user, err = th.App.GetUserByUsername(username) 1131 if err != nil { 1132 t.Fatalf("Failed to get user from database.") 1133 } 1134 1135 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL) 1136 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true") 1137 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true") 1138 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL) 1139 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE) 1140 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true") 1141 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT) 1142 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, fmt.Sprintf("%s,@%s", username, username)) 1143 1144 // Set Notify Props with Mention keys 1145 data.NotifyProps = &UserNotifyPropsImportData{ 1146 Desktop: ptrStr(model.USER_NOTIFY_ALL), 1147 DesktopSound: ptrStr("true"), 1148 Email: ptrStr("true"), 1149 Mobile: ptrStr(model.USER_NOTIFY_ALL), 1150 MobilePushStatus: ptrStr(model.STATUS_ONLINE), 1151 ChannelTrigger: ptrStr("true"), 1152 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ROOT), 1153 MentionKeys: ptrStr("valid,misc"), 1154 } 1155 err = th.App.ImportUser(&data, false) 1156 assert.Nil(t, err) 1157 1158 user, err = th.App.GetUserByUsername(username) 1159 if err != nil { 1160 t.Fatalf("Failed to get user from database.") 1161 } 1162 1163 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL) 1164 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true") 1165 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true") 1166 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL) 1167 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE) 1168 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true") 1169 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT) 1170 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "valid,misc") 1171 1172 // Change Notify Props with mention keys 1173 data.NotifyProps = &UserNotifyPropsImportData{ 1174 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 1175 DesktopSound: ptrStr("false"), 1176 Email: ptrStr("false"), 1177 Mobile: ptrStr(model.USER_NOTIFY_NONE), 1178 MobilePushStatus: ptrStr(model.STATUS_AWAY), 1179 ChannelTrigger: ptrStr("false"), 1180 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), 1181 MentionKeys: ptrStr("misc"), 1182 } 1183 err = th.App.ImportUser(&data, false) 1184 assert.Nil(t, err) 1185 1186 user, err = th.App.GetUserByUsername(username) 1187 if err != nil { 1188 t.Fatalf("Failed to get user from database.") 1189 } 1190 1191 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) 1192 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") 1193 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") 1194 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) 1195 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) 1196 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") 1197 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) 1198 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") 1199 1200 // Change Notify Props without mention keys 1201 data.NotifyProps = &UserNotifyPropsImportData{ 1202 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 1203 DesktopSound: ptrStr("false"), 1204 Email: ptrStr("false"), 1205 Mobile: ptrStr(model.USER_NOTIFY_NONE), 1206 MobilePushStatus: ptrStr(model.STATUS_AWAY), 1207 ChannelTrigger: ptrStr("false"), 1208 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), 1209 } 1210 err = th.App.ImportUser(&data, false) 1211 assert.Nil(t, err) 1212 1213 user, err = th.App.GetUserByUsername(username) 1214 if err != nil { 1215 t.Fatalf("Failed to get user from database.") 1216 } 1217 1218 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) 1219 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") 1220 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") 1221 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) 1222 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) 1223 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") 1224 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) 1225 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") 1226 1227 // Check Notify Props get set on *create* user. 1228 username = model.NewId() 1229 data = UserImportData{ 1230 Username: &username, 1231 Email: ptrStr(model.NewId() + "@example.com"), 1232 } 1233 data.NotifyProps = &UserNotifyPropsImportData{ 1234 Desktop: ptrStr(model.USER_NOTIFY_MENTION), 1235 DesktopSound: ptrStr("false"), 1236 Email: ptrStr("false"), 1237 Mobile: ptrStr(model.USER_NOTIFY_NONE), 1238 MobilePushStatus: ptrStr(model.STATUS_AWAY), 1239 ChannelTrigger: ptrStr("false"), 1240 CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY), 1241 MentionKeys: ptrStr("misc"), 1242 } 1243 1244 err = th.App.ImportUser(&data, false) 1245 assert.Nil(t, err) 1246 1247 user, err = th.App.GetUserByUsername(username) 1248 if err != nil { 1249 t.Fatalf("Failed to get user from database.") 1250 } 1251 1252 checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION) 1253 checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false") 1254 checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false") 1255 checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE) 1256 checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY) 1257 checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false") 1258 checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY) 1259 checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc") 1260 1261 // Test importing a user with roles set to a team and a channel which are affected by an override scheme. 1262 // The import subsystem should translate `channel_admin/channel_user/team_admin/team_user` 1263 // to the appropriate scheme-managed-role booleans. 1264 1265 // Mark the phase 2 permissions migration as completed. 1266 <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) 1267 1268 defer func() { 1269 <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) 1270 }() 1271 1272 teamSchemeData := &SchemeImportData{ 1273 Name: ptrStr(model.NewId()), 1274 DisplayName: ptrStr(model.NewId()), 1275 Scope: ptrStr("team"), 1276 DefaultTeamUserRole: &RoleImportData{ 1277 Name: ptrStr(model.NewId()), 1278 DisplayName: ptrStr(model.NewId()), 1279 }, 1280 DefaultTeamAdminRole: &RoleImportData{ 1281 Name: ptrStr(model.NewId()), 1282 DisplayName: ptrStr(model.NewId()), 1283 }, 1284 DefaultChannelUserRole: &RoleImportData{ 1285 Name: ptrStr(model.NewId()), 1286 DisplayName: ptrStr(model.NewId()), 1287 }, 1288 DefaultChannelAdminRole: &RoleImportData{ 1289 Name: ptrStr(model.NewId()), 1290 DisplayName: ptrStr(model.NewId()), 1291 }, 1292 Description: ptrStr("description"), 1293 } 1294 1295 err = th.App.ImportScheme(teamSchemeData, false) 1296 assert.Nil(t, err) 1297 1298 var teamScheme *model.Scheme 1299 if res := <-th.App.Srv.Store.Scheme().GetByName(*teamSchemeData.Name); res.Err != nil { 1300 t.Fatalf("Failed to import scheme: %v", res.Err) 1301 } else { 1302 teamScheme = res.Data.(*model.Scheme) 1303 } 1304 1305 teamData := &TeamImportData{ 1306 Name: ptrStr(model.NewId()), 1307 DisplayName: ptrStr("Display Name"), 1308 Type: ptrStr("O"), 1309 Description: ptrStr("The team description."), 1310 AllowOpenInvite: ptrBool(true), 1311 Scheme: &teamScheme.Name, 1312 } 1313 err = th.App.ImportTeam(teamData, false) 1314 assert.Nil(t, err) 1315 team, err = th.App.GetTeamByName(teamName) 1316 if err != nil { 1317 t.Fatalf("Failed to get team from database.") 1318 } 1319 1320 channelData := &ChannelImportData{ 1321 Team: &teamName, 1322 Name: ptrStr(model.NewId()), 1323 DisplayName: ptrStr("Display Name"), 1324 Type: ptrStr("O"), 1325 Header: ptrStr("Channe Header"), 1326 Purpose: ptrStr("Channel Purpose"), 1327 } 1328 err = th.App.ImportChannel(channelData, false) 1329 assert.Nil(t, err) 1330 channel, err = th.App.GetChannelByName(*channelData.Name, team.Id, false) 1331 if err != nil { 1332 t.Fatalf("Failed to get channel from database: %v", err.Error()) 1333 } 1334 1335 // Test with a valid team & valid channel name in apply mode. 1336 userData := &UserImportData{ 1337 Username: &username, 1338 Email: ptrStr(model.NewId() + "@example.com"), 1339 Teams: &[]UserTeamImportData{ 1340 { 1341 Name: &team.Name, 1342 Roles: ptrStr("team_user team_admin"), 1343 Channels: &[]UserChannelImportData{ 1344 { 1345 Name: &channel.Name, 1346 Roles: ptrStr("channel_admin channel_user"), 1347 }, 1348 }, 1349 }, 1350 }, 1351 } 1352 err = th.App.ImportUser(userData, false) 1353 assert.Nil(t, err) 1354 1355 user, err = th.App.GetUserByUsername(*userData.Username) 1356 if err != nil { 1357 t.Fatalf("Failed to get user from database.") 1358 } 1359 1360 teamMember, err = th.App.GetTeamMember(team.Id, user.Id) 1361 if err != nil { 1362 t.Fatalf("Failed to get the team member") 1363 } 1364 assert.True(t, teamMember.SchemeAdmin) 1365 assert.True(t, teamMember.SchemeUser) 1366 assert.Equal(t, "", teamMember.ExplicitRoles) 1367 1368 channelMember, err = th.App.GetChannelMember(channel.Id, user.Id) 1369 if err != nil { 1370 t.Fatalf("Failed to get the channel member") 1371 } 1372 assert.True(t, channelMember.SchemeAdmin) 1373 assert.True(t, channelMember.SchemeUser) 1374 assert.Equal(t, "", channelMember.ExplicitRoles) 1375 1376 // Test importing deleted user with a valid team & valid channel name in apply mode. 1377 username = model.NewId() 1378 deleteAt := model.GetMillis() 1379 deletedUserData := &UserImportData{ 1380 Username: &username, 1381 DeleteAt: &deleteAt, 1382 Email: ptrStr(model.NewId() + "@example.com"), 1383 Teams: &[]UserTeamImportData{ 1384 { 1385 Name: &team.Name, 1386 Roles: ptrStr("team_user"), 1387 Channels: &[]UserChannelImportData{ 1388 { 1389 Name: &channel.Name, 1390 Roles: ptrStr("channel_user"), 1391 }, 1392 }, 1393 }, 1394 }, 1395 } 1396 err = th.App.ImportUser(deletedUserData, false) 1397 assert.Nil(t, err) 1398 1399 user, err = th.App.GetUserByUsername(*deletedUserData.Username) 1400 if err != nil { 1401 t.Fatalf("Failed to get user from database.") 1402 } 1403 1404 teamMember, err = th.App.GetTeamMember(team.Id, user.Id) 1405 if err != nil { 1406 t.Fatalf("Failed to get the team member") 1407 } 1408 1409 assert.True(t, teamMember.SchemeUser) 1410 assert.Equal(t, "", teamMember.ExplicitRoles) 1411 1412 channelMember, err = th.App.GetChannelMember(channel.Id, user.Id) 1413 if err != nil { 1414 t.Fatalf("Failed to get the channel member") 1415 } 1416 1417 assert.True(t, channelMember.SchemeUser) 1418 assert.Equal(t, "", channelMember.ExplicitRoles) 1419 1420 } 1421 1422 func TestImportUserDefaultNotifyProps(t *testing.T) { 1423 th := Setup(t) 1424 defer th.TearDown() 1425 1426 // Create a valid new user with some, but not all, notify props populated. 1427 username := model.NewId() 1428 data := UserImportData{ 1429 Username: &username, 1430 Email: ptrStr(model.NewId() + "@example.com"), 1431 NotifyProps: &UserNotifyPropsImportData{ 1432 Email: ptrStr("false"), 1433 }, 1434 } 1435 require.Nil(t, th.App.ImportUser(&data, false)) 1436 1437 user, err := th.App.GetUserByUsername(username) 1438 require.Nil(t, err) 1439 1440 // Check the value of the notify prop we specified explicitly in the import data. 1441 val, ok := user.NotifyProps[model.EMAIL_NOTIFY_PROP] 1442 assert.True(t, ok) 1443 assert.Equal(t, "false", val) 1444 1445 // Check all the other notify props are set to their default values. 1446 comparisonUser := model.User{Username: user.Username} 1447 comparisonUser.SetDefaultNotifications() 1448 1449 for key, expectedValue := range comparisonUser.NotifyProps { 1450 if key == model.EMAIL_NOTIFY_PROP { 1451 continue 1452 } 1453 1454 val, ok := user.NotifyProps[key] 1455 assert.True(t, ok) 1456 assert.Equal(t, expectedValue, val) 1457 } 1458 } 1459 1460 func TestImportImportPost(t *testing.T) { 1461 th := Setup(t) 1462 defer th.TearDown() 1463 1464 // Create a Team. 1465 teamName := model.NewId() 1466 th.App.ImportTeam(&TeamImportData{ 1467 Name: &teamName, 1468 DisplayName: ptrStr("Display Name"), 1469 Type: ptrStr("O"), 1470 }, false) 1471 team, err := th.App.GetTeamByName(teamName) 1472 if err != nil { 1473 t.Fatalf("Failed to get team from database.") 1474 } 1475 1476 // Create a Channel. 1477 channelName := model.NewId() 1478 th.App.ImportChannel(&ChannelImportData{ 1479 Team: &teamName, 1480 Name: &channelName, 1481 DisplayName: ptrStr("Display Name"), 1482 Type: ptrStr("O"), 1483 }, false) 1484 channel, err := th.App.GetChannelByName(channelName, team.Id, false) 1485 if err != nil { 1486 t.Fatalf("Failed to get channel from database.") 1487 } 1488 1489 // Create a user. 1490 username := model.NewId() 1491 th.App.ImportUser(&UserImportData{ 1492 Username: &username, 1493 Email: ptrStr(model.NewId() + "@example.com"), 1494 }, false) 1495 user, err := th.App.GetUserByUsername(username) 1496 if err != nil { 1497 t.Fatalf("Failed to get user from database.") 1498 } 1499 1500 // Count the number of posts in the testing team. 1501 var initialPostCount int64 1502 if result := <-th.App.Srv.Store.Post().AnalyticsPostCount(team.Id, false, false); result.Err != nil { 1503 t.Fatal(result.Err) 1504 } else { 1505 initialPostCount = result.Data.(int64) 1506 } 1507 1508 // Try adding an invalid post in dry run mode. 1509 data := &PostImportData{ 1510 Team: &teamName, 1511 Channel: &channelName, 1512 User: &username, 1513 } 1514 err = th.App.ImportPost(data, true) 1515 assert.NotNil(t, err) 1516 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 1517 1518 // Try adding a valid post in dry run mode. 1519 data = &PostImportData{ 1520 Team: &teamName, 1521 Channel: &channelName, 1522 User: &username, 1523 Message: ptrStr("Hello"), 1524 CreateAt: ptrInt64(model.GetMillis()), 1525 } 1526 err = th.App.ImportPost(data, true) 1527 assert.Nil(t, err) 1528 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 1529 1530 // Try adding an invalid post in apply mode. 1531 data = &PostImportData{ 1532 Team: &teamName, 1533 Channel: &channelName, 1534 User: &username, 1535 CreateAt: ptrInt64(model.GetMillis()), 1536 } 1537 err = th.App.ImportPost(data, false) 1538 assert.NotNil(t, err) 1539 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 1540 1541 // Try adding a valid post with invalid team in apply mode. 1542 data = &PostImportData{ 1543 Team: ptrStr(model.NewId()), 1544 Channel: &channelName, 1545 User: &username, 1546 Message: ptrStr("Message"), 1547 CreateAt: ptrInt64(model.GetMillis()), 1548 } 1549 err = th.App.ImportPost(data, false) 1550 assert.NotNil(t, err) 1551 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 1552 1553 // Try adding a valid post with invalid channel in apply mode. 1554 data = &PostImportData{ 1555 Team: &teamName, 1556 Channel: ptrStr(model.NewId()), 1557 User: &username, 1558 Message: ptrStr("Message"), 1559 CreateAt: ptrInt64(model.GetMillis()), 1560 } 1561 err = th.App.ImportPost(data, false) 1562 assert.NotNil(t, err) 1563 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 1564 1565 // Try adding a valid post with invalid user in apply mode. 1566 data = &PostImportData{ 1567 Team: &teamName, 1568 Channel: &channelName, 1569 User: ptrStr(model.NewId()), 1570 Message: ptrStr("Message"), 1571 CreateAt: ptrInt64(model.GetMillis()), 1572 } 1573 err = th.App.ImportPost(data, false) 1574 assert.NotNil(t, err) 1575 AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id) 1576 1577 // Try adding a valid post in apply mode. 1578 time := model.GetMillis() 1579 data = &PostImportData{ 1580 Team: &teamName, 1581 Channel: &channelName, 1582 User: &username, 1583 Message: ptrStr("Message"), 1584 CreateAt: &time, 1585 } 1586 err = th.App.ImportPost(data, false) 1587 assert.Nil(t, err) 1588 AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id) 1589 1590 // Check the post values. 1591 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, time); result.Err != nil { 1592 t.Fatal(result.Err.Error()) 1593 } else { 1594 posts := result.Data.([]*model.Post) 1595 if len(posts) != 1 { 1596 t.Fatal("Unexpected number of posts found.") 1597 } 1598 post := posts[0] 1599 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 1600 t.Fatal("Post properties not as expected") 1601 } 1602 } 1603 1604 // Update the post. 1605 data = &PostImportData{ 1606 Team: &teamName, 1607 Channel: &channelName, 1608 User: &username, 1609 Message: ptrStr("Message"), 1610 CreateAt: &time, 1611 } 1612 err = th.App.ImportPost(data, false) 1613 assert.Nil(t, err) 1614 AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id) 1615 1616 // Check the post values. 1617 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, time); result.Err != nil { 1618 t.Fatal(result.Err.Error()) 1619 } else { 1620 posts := result.Data.([]*model.Post) 1621 if len(posts) != 1 { 1622 t.Fatal("Unexpected number of posts found.") 1623 } 1624 post := posts[0] 1625 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 1626 t.Fatal("Post properties not as expected") 1627 } 1628 } 1629 1630 // Save the post with a different time. 1631 newTime := time + 1 1632 data = &PostImportData{ 1633 Team: &teamName, 1634 Channel: &channelName, 1635 User: &username, 1636 Message: ptrStr("Message"), 1637 CreateAt: &newTime, 1638 } 1639 err = th.App.ImportPost(data, false) 1640 assert.Nil(t, err) 1641 AssertAllPostsCount(t, th.App, initialPostCount, 2, team.Id) 1642 1643 // Save the post with a different message. 1644 data = &PostImportData{ 1645 Team: &teamName, 1646 Channel: &channelName, 1647 User: &username, 1648 Message: ptrStr("Message 2"), 1649 CreateAt: &time, 1650 } 1651 err = th.App.ImportPost(data, false) 1652 assert.Nil(t, err) 1653 AssertAllPostsCount(t, th.App, initialPostCount, 3, team.Id) 1654 1655 // Test with hashtags 1656 hashtagTime := time + 2 1657 data = &PostImportData{ 1658 Team: &teamName, 1659 Channel: &channelName, 1660 User: &username, 1661 Message: ptrStr("Message 2 #hashtagmashupcity"), 1662 CreateAt: &hashtagTime, 1663 } 1664 err = th.App.ImportPost(data, false) 1665 assert.Nil(t, err) 1666 AssertAllPostsCount(t, th.App, initialPostCount, 4, team.Id) 1667 1668 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, hashtagTime); result.Err != nil { 1669 t.Fatal(result.Err.Error()) 1670 } else { 1671 posts := result.Data.([]*model.Post) 1672 if len(posts) != 1 { 1673 t.Fatal("Unexpected number of posts found.") 1674 } 1675 post := posts[0] 1676 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 1677 t.Fatal("Post properties not as expected") 1678 } 1679 if post.Hashtags != "#hashtagmashupcity" { 1680 t.Fatalf("Hashtags not as expected: %s", post.Hashtags) 1681 } 1682 } 1683 1684 // Post with flags. 1685 username2 := model.NewId() 1686 th.App.ImportUser(&UserImportData{ 1687 Username: &username2, 1688 Email: ptrStr(model.NewId() + "@example.com"), 1689 }, false) 1690 user2, err := th.App.GetUserByUsername(username2) 1691 if err != nil { 1692 t.Fatalf("Failed to get user from database.") 1693 } 1694 1695 flagsTime := hashtagTime + 1 1696 data = &PostImportData{ 1697 Team: &teamName, 1698 Channel: &channelName, 1699 User: &username, 1700 Message: ptrStr("Message with Favorites"), 1701 CreateAt: &flagsTime, 1702 FlaggedBy: &[]string{ 1703 username, 1704 username2, 1705 }, 1706 } 1707 if err := th.App.ImportPost(data, false); err != nil { 1708 t.Fatalf("Expected success.") 1709 } 1710 AssertAllPostsCount(t, th.App, initialPostCount, 5, team.Id) 1711 1712 // Check the post values. 1713 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, flagsTime); result.Err != nil { 1714 t.Fatal(result.Err.Error()) 1715 } else { 1716 posts := result.Data.([]*model.Post) 1717 if len(posts) != 1 { 1718 t.Fatal("Unexpected number of posts found.") 1719 } 1720 post := posts[0] 1721 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 1722 t.Fatal("Post properties not as expected") 1723 } 1724 1725 checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 1726 checkPreference(t, th.App, user2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 1727 } 1728 1729 // Post with reaction. 1730 reactionPostTime := hashtagTime + 2 1731 reactionTime := hashtagTime + 3 1732 data = &PostImportData{ 1733 Team: &teamName, 1734 Channel: &channelName, 1735 User: &username, 1736 Message: ptrStr("Message with reaction"), 1737 CreateAt: &reactionPostTime, 1738 Reactions: &[]ReactionImportData{{ 1739 User: &user2.Username, 1740 EmojiName: ptrStr("+1"), 1741 CreateAt: &reactionTime, 1742 }}, 1743 } 1744 if err := th.App.ImportPost(data, false); err != nil { 1745 t.Fatalf("Expected success.") 1746 } 1747 AssertAllPostsCount(t, th.App, initialPostCount, 6, team.Id) 1748 1749 // Check the post values. 1750 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, reactionPostTime); result.Err != nil { 1751 t.Fatal(result.Err.Error()) 1752 } else { 1753 posts := result.Data.([]*model.Post) 1754 if len(posts) != 1 { 1755 t.Fatal("Unexpected number of posts found.") 1756 } 1757 post := posts[0] 1758 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id || !post.HasReactions { 1759 t.Fatal("Post properties not as expected") 1760 } 1761 1762 if result := <-th.App.Srv.Store.Reaction().GetForPost(post.Id, false); result.Err != nil { 1763 t.Fatal("Can't get reaction") 1764 } else if len(result.Data.([]*model.Reaction)) != 1 { 1765 t.Fatal("Invalid number of reactions") 1766 } 1767 } 1768 1769 // Post with reply. 1770 replyPostTime := hashtagTime + 4 1771 replyTime := hashtagTime + 5 1772 data = &PostImportData{ 1773 Team: &teamName, 1774 Channel: &channelName, 1775 User: &username, 1776 Message: ptrStr("Message with reply"), 1777 CreateAt: &replyPostTime, 1778 Replies: &[]ReplyImportData{{ 1779 User: &user2.Username, 1780 Message: ptrStr("Message reply"), 1781 CreateAt: &replyTime, 1782 }}, 1783 } 1784 if err := th.App.ImportPost(data, false); err != nil { 1785 t.Fatalf("Expected success.") 1786 } 1787 AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id) 1788 1789 // Check the post values. 1790 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyPostTime); result.Err != nil { 1791 t.Fatal(result.Err.Error()) 1792 } else { 1793 posts := result.Data.([]*model.Post) 1794 if len(posts) != 1 { 1795 t.Fatal("Unexpected number of posts found.") 1796 } 1797 post := posts[0] 1798 if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id { 1799 t.Fatal("Post properties not as expected") 1800 } 1801 1802 // Check the reply values. 1803 if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyTime); result.Err != nil { 1804 t.Fatal(result.Err.Error()) 1805 } else { 1806 replies := result.Data.([]*model.Post) 1807 if len(replies) != 1 { 1808 t.Fatal("Unexpected number of posts found.") 1809 } 1810 reply := replies[0] 1811 if reply.Message != *(*data.Replies)[0].Message || reply.CreateAt != *(*data.Replies)[0].CreateAt || reply.UserId != user2.Id { 1812 t.Fatal("Post properties not as expected") 1813 } 1814 1815 if reply.RootId != post.Id { 1816 t.Fatal("Unexpected reply RootId") 1817 } 1818 } 1819 } 1820 1821 // Update post with replies. 1822 data = &PostImportData{ 1823 Team: &teamName, 1824 Channel: &channelName, 1825 User: &user2.Username, 1826 Message: ptrStr("Message with reply"), 1827 CreateAt: &replyPostTime, 1828 Replies: &[]ReplyImportData{{ 1829 User: &username, 1830 Message: ptrStr("Message reply"), 1831 CreateAt: &replyTime, 1832 }}, 1833 } 1834 if err := th.App.ImportPost(data, false); err != nil { 1835 t.Fatalf("Expected success.") 1836 } 1837 AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id) 1838 1839 // Create new post with replies based on the previous one. 1840 data = &PostImportData{ 1841 Team: &teamName, 1842 Channel: &channelName, 1843 User: &user2.Username, 1844 Message: ptrStr("Message with reply 2"), 1845 CreateAt: &replyPostTime, 1846 Replies: &[]ReplyImportData{{ 1847 User: &username, 1848 Message: ptrStr("Message reply"), 1849 CreateAt: &replyTime, 1850 }}, 1851 } 1852 if err := th.App.ImportPost(data, false); err != nil { 1853 t.Fatalf("Expected success.") 1854 } 1855 AssertAllPostsCount(t, th.App, initialPostCount, 10, team.Id) 1856 1857 // Create new reply for existing post with replies. 1858 data = &PostImportData{ 1859 Team: &teamName, 1860 Channel: &channelName, 1861 User: &user2.Username, 1862 Message: ptrStr("Message with reply"), 1863 CreateAt: &replyPostTime, 1864 Replies: &[]ReplyImportData{{ 1865 User: &username, 1866 Message: ptrStr("Message reply 2"), 1867 CreateAt: &replyTime, 1868 }}, 1869 } 1870 if err := th.App.ImportPost(data, false); err != nil { 1871 t.Fatalf("Expected success.") 1872 } 1873 AssertAllPostsCount(t, th.App, initialPostCount, 11, team.Id) 1874 } 1875 1876 func TestImportImportDirectChannel(t *testing.T) { 1877 th := Setup(t).InitBasic() 1878 defer th.TearDown() 1879 1880 // Check how many channels are in the database. 1881 var directChannelCount int64 1882 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_DIRECT); r.Err == nil { 1883 directChannelCount = r.Data.(int64) 1884 } else { 1885 t.Fatalf("Failed to get direct channel count.") 1886 } 1887 1888 var groupChannelCount int64 1889 if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_GROUP); r.Err == nil { 1890 groupChannelCount = r.Data.(int64) 1891 } else { 1892 t.Fatalf("Failed to get group channel count.") 1893 } 1894 1895 // Do an invalid channel in dry-run mode. 1896 data := DirectChannelImportData{ 1897 Members: &[]string{ 1898 model.NewId(), 1899 }, 1900 Header: ptrStr("Channel Header"), 1901 } 1902 err := th.App.ImportDirectChannel(&data, true) 1903 require.NotNil(t, err) 1904 1905 // Check that no more channels are in the DB. 1906 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 1907 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1908 1909 // Do a valid DIRECT channel with a nonexistent member in dry-run mode. 1910 data.Members = &[]string{ 1911 model.NewId(), 1912 model.NewId(), 1913 } 1914 err = th.App.ImportDirectChannel(&data, true) 1915 require.Nil(t, err) 1916 1917 // Check that no more channels are in the DB. 1918 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 1919 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1920 1921 // Do a valid GROUP channel with a nonexistent member in dry-run mode. 1922 data.Members = &[]string{ 1923 model.NewId(), 1924 model.NewId(), 1925 model.NewId(), 1926 } 1927 err = th.App.ImportDirectChannel(&data, true) 1928 require.Nil(t, err) 1929 1930 // Check that no more channels are in the DB. 1931 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 1932 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1933 1934 // Do an invalid channel in apply mode. 1935 data.Members = &[]string{ 1936 model.NewId(), 1937 } 1938 err = th.App.ImportDirectChannel(&data, false) 1939 require.NotNil(t, err) 1940 1941 // Check that no more channels are in the DB. 1942 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount) 1943 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1944 1945 // Do a valid DIRECT channel. 1946 data.Members = &[]string{ 1947 th.BasicUser.Username, 1948 th.BasicUser2.Username, 1949 } 1950 err = th.App.ImportDirectChannel(&data, false) 1951 require.Nil(t, err) 1952 1953 // Check that one more DIRECT channel is in the DB. 1954 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 1955 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1956 1957 // Do the same DIRECT channel again. 1958 err = th.App.ImportDirectChannel(&data, false) 1959 require.Nil(t, err) 1960 1961 // Check that no more channels are in the DB. 1962 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 1963 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1964 1965 // Update the channel's HEADER 1966 data.Header = ptrStr("New Channel Header 2") 1967 err = th.App.ImportDirectChannel(&data, false) 1968 require.Nil(t, err) 1969 1970 // Check that no more channels are in the DB. 1971 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 1972 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1973 1974 // Get the channel to check that the header was updated. 1975 channel, err := th.App.GetOrCreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id) 1976 require.Nil(t, err) 1977 require.Equal(t, channel.Header, *data.Header) 1978 1979 // Do a GROUP channel with an extra invalid member. 1980 user3 := th.CreateUser() 1981 data.Members = &[]string{ 1982 th.BasicUser.Username, 1983 th.BasicUser2.Username, 1984 user3.Username, 1985 model.NewId(), 1986 } 1987 err = th.App.ImportDirectChannel(&data, false) 1988 require.NotNil(t, err) 1989 1990 // Check that no more channels are in the DB. 1991 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 1992 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount) 1993 1994 // Do a valid GROUP channel. 1995 data.Members = &[]string{ 1996 th.BasicUser.Username, 1997 th.BasicUser2.Username, 1998 user3.Username, 1999 } 2000 err = th.App.ImportDirectChannel(&data, false) 2001 require.Nil(t, err) 2002 2003 // Check that one more GROUP channel is in the DB. 2004 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2005 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1) 2006 2007 // Do the same DIRECT channel again. 2008 err = th.App.ImportDirectChannel(&data, false) 2009 require.Nil(t, err) 2010 2011 // Check that no more channels are in the DB. 2012 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2013 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1) 2014 2015 // Update the channel's HEADER 2016 data.Header = ptrStr("New Channel Header 3") 2017 err = th.App.ImportDirectChannel(&data, false) 2018 require.Nil(t, err) 2019 2020 // Check that no more channels are in the DB. 2021 AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1) 2022 AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1) 2023 2024 // Get the channel to check that the header was updated. 2025 userIds := []string{ 2026 th.BasicUser.Id, 2027 th.BasicUser2.Id, 2028 user3.Id, 2029 } 2030 channel, err = th.App.createGroupChannel(userIds, th.BasicUser.Id) 2031 require.Equal(t, err.Id, store.CHANNEL_EXISTS_ERROR) 2032 require.Equal(t, channel.Header, *data.Header) 2033 2034 // Import a channel with some favorites. 2035 data.Members = &[]string{ 2036 th.BasicUser.Username, 2037 th.BasicUser2.Username, 2038 } 2039 data.FavoritedBy = &[]string{ 2040 th.BasicUser.Username, 2041 th.BasicUser2.Username, 2042 } 2043 err = th.App.ImportDirectChannel(&data, false) 2044 require.Nil(t, err) 2045 2046 channel, err = th.App.GetOrCreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id) 2047 require.Nil(t, err) 2048 checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true") 2049 checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true") 2050 } 2051 2052 func TestImportImportDirectPost(t *testing.T) { 2053 th := Setup(t).InitBasic() 2054 defer th.TearDown() 2055 2056 // Create the DIRECT channel. 2057 channelData := DirectChannelImportData{ 2058 Members: &[]string{ 2059 th.BasicUser.Username, 2060 th.BasicUser2.Username, 2061 }, 2062 } 2063 err := th.App.ImportDirectChannel(&channelData, false) 2064 require.Nil(t, err) 2065 2066 // Get the channel. 2067 var directChannel *model.Channel 2068 channel, err := th.App.GetOrCreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id) 2069 require.Nil(t, err) 2070 require.NotEmpty(t, channel) 2071 directChannel = channel 2072 2073 // Get the number of posts in the system. 2074 result := <-th.App.Srv.Store.Post().AnalyticsPostCount("", false, false) 2075 require.Nil(t, result.Err) 2076 initialPostCount := result.Data.(int64) 2077 2078 // Try adding an invalid post in dry run mode. 2079 data := &DirectPostImportData{ 2080 ChannelMembers: &[]string{ 2081 th.BasicUser.Username, 2082 th.BasicUser2.Username, 2083 }, 2084 User: ptrStr(th.BasicUser.Username), 2085 CreateAt: ptrInt64(model.GetMillis()), 2086 } 2087 err = th.App.ImportDirectPost(data, true) 2088 require.NotNil(t, err) 2089 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2090 2091 // Try adding a valid post in dry run mode. 2092 data = &DirectPostImportData{ 2093 ChannelMembers: &[]string{ 2094 th.BasicUser.Username, 2095 th.BasicUser2.Username, 2096 }, 2097 User: ptrStr(th.BasicUser.Username), 2098 Message: ptrStr("Message"), 2099 CreateAt: ptrInt64(model.GetMillis()), 2100 } 2101 err = th.App.ImportDirectPost(data, true) 2102 require.Nil(t, err) 2103 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2104 2105 // Try adding an invalid post in apply mode. 2106 data = &DirectPostImportData{ 2107 ChannelMembers: &[]string{ 2108 th.BasicUser.Username, 2109 model.NewId(), 2110 }, 2111 User: ptrStr(th.BasicUser.Username), 2112 Message: ptrStr("Message"), 2113 CreateAt: ptrInt64(model.GetMillis()), 2114 } 2115 err = th.App.ImportDirectPost(data, false) 2116 require.NotNil(t, err) 2117 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2118 2119 // Try adding a valid post in apply mode. 2120 data = &DirectPostImportData{ 2121 ChannelMembers: &[]string{ 2122 th.BasicUser.Username, 2123 th.BasicUser2.Username, 2124 }, 2125 User: ptrStr(th.BasicUser.Username), 2126 Message: ptrStr("Message"), 2127 CreateAt: ptrInt64(model.GetMillis()), 2128 } 2129 err = th.App.ImportDirectPost(data, false) 2130 require.Nil(t, err) 2131 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2132 2133 // Check the post values. 2134 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt) 2135 require.Nil(t, result.Err) 2136 2137 posts := result.Data.([]*model.Post) 2138 require.Equal(t, len(posts), 1) 2139 2140 post := posts[0] 2141 require.Equal(t, post.Message, *data.Message) 2142 require.Equal(t, post.CreateAt, *data.CreateAt) 2143 require.Equal(t, post.UserId, th.BasicUser.Id) 2144 2145 // Import the post again. 2146 err = th.App.ImportDirectPost(data, false) 2147 require.Nil(t, err) 2148 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2149 2150 // Check the post values. 2151 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt) 2152 require.Nil(t, result.Err) 2153 2154 posts = result.Data.([]*model.Post) 2155 require.Equal(t, len(posts), 1) 2156 2157 post = posts[0] 2158 require.Equal(t, post.Message, *data.Message) 2159 require.Equal(t, post.CreateAt, *data.CreateAt) 2160 require.Equal(t, post.UserId, th.BasicUser.Id) 2161 2162 // Save the post with a different time. 2163 data.CreateAt = ptrInt64(*data.CreateAt + 1) 2164 err = th.App.ImportDirectPost(data, false) 2165 require.Nil(t, err) 2166 AssertAllPostsCount(t, th.App, initialPostCount, 2, "") 2167 2168 // Save the post with a different message. 2169 data.Message = ptrStr("Message 2") 2170 err = th.App.ImportDirectPost(data, false) 2171 require.Nil(t, err) 2172 AssertAllPostsCount(t, th.App, initialPostCount, 3, "") 2173 2174 // Test with hashtags 2175 data.Message = ptrStr("Message 2 #hashtagmashupcity") 2176 data.CreateAt = ptrInt64(*data.CreateAt + 1) 2177 err = th.App.ImportDirectPost(data, false) 2178 require.Nil(t, err) 2179 AssertAllPostsCount(t, th.App, initialPostCount, 4, "") 2180 2181 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt) 2182 require.Nil(t, result.Err) 2183 2184 posts = result.Data.([]*model.Post) 2185 require.Equal(t, len(posts), 1) 2186 2187 post = posts[0] 2188 require.Equal(t, post.Message, *data.Message) 2189 require.Equal(t, post.CreateAt, *data.CreateAt) 2190 require.Equal(t, post.UserId, th.BasicUser.Id) 2191 require.Equal(t, post.Hashtags, "#hashtagmashupcity") 2192 2193 // Test with some flags. 2194 data = &DirectPostImportData{ 2195 ChannelMembers: &[]string{ 2196 th.BasicUser.Username, 2197 th.BasicUser2.Username, 2198 }, 2199 FlaggedBy: &[]string{ 2200 th.BasicUser.Username, 2201 th.BasicUser2.Username, 2202 }, 2203 User: ptrStr(th.BasicUser.Username), 2204 Message: ptrStr("Message"), 2205 CreateAt: ptrInt64(model.GetMillis()), 2206 } 2207 2208 err = th.App.ImportDirectPost(data, false) 2209 require.Nil(t, err) 2210 2211 // Check the post values. 2212 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt) 2213 require.Nil(t, result.Err) 2214 2215 posts = result.Data.([]*model.Post) 2216 require.Equal(t, len(posts), 1) 2217 2218 post = posts[0] 2219 checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2220 checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2221 2222 // ------------------ Group Channel ------------------------- 2223 2224 // Create the GROUP channel. 2225 user3 := th.CreateUser() 2226 channelData = DirectChannelImportData{ 2227 Members: &[]string{ 2228 th.BasicUser.Username, 2229 th.BasicUser2.Username, 2230 user3.Username, 2231 }, 2232 } 2233 err = th.App.ImportDirectChannel(&channelData, false) 2234 require.Nil(t, err) 2235 2236 // Get the channel. 2237 var groupChannel *model.Channel 2238 userIds := []string{ 2239 th.BasicUser.Id, 2240 th.BasicUser2.Id, 2241 user3.Id, 2242 } 2243 channel, err = th.App.createGroupChannel(userIds, th.BasicUser.Id) 2244 require.Equal(t, err.Id, store.CHANNEL_EXISTS_ERROR) 2245 groupChannel = channel 2246 2247 // Get the number of posts in the system. 2248 result = <-th.App.Srv.Store.Post().AnalyticsPostCount("", false, false) 2249 require.Nil(t, result.Err) 2250 initialPostCount = result.Data.(int64) 2251 2252 // Try adding an invalid post in dry run mode. 2253 data = &DirectPostImportData{ 2254 ChannelMembers: &[]string{ 2255 th.BasicUser.Username, 2256 th.BasicUser2.Username, 2257 user3.Username, 2258 }, 2259 User: ptrStr(th.BasicUser.Username), 2260 CreateAt: ptrInt64(model.GetMillis()), 2261 } 2262 err = th.App.ImportDirectPost(data, true) 2263 require.NotNil(t, err) 2264 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2265 2266 // Try adding a valid post in dry run mode. 2267 data = &DirectPostImportData{ 2268 ChannelMembers: &[]string{ 2269 th.BasicUser.Username, 2270 th.BasicUser2.Username, 2271 user3.Username, 2272 }, 2273 User: ptrStr(th.BasicUser.Username), 2274 Message: ptrStr("Message"), 2275 CreateAt: ptrInt64(model.GetMillis()), 2276 } 2277 err = th.App.ImportDirectPost(data, true) 2278 require.Nil(t, err) 2279 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2280 2281 // Try adding an invalid post in apply mode. 2282 data = &DirectPostImportData{ 2283 ChannelMembers: &[]string{ 2284 th.BasicUser.Username, 2285 th.BasicUser2.Username, 2286 user3.Username, 2287 model.NewId(), 2288 }, 2289 User: ptrStr(th.BasicUser.Username), 2290 Message: ptrStr("Message"), 2291 CreateAt: ptrInt64(model.GetMillis()), 2292 } 2293 err = th.App.ImportDirectPost(data, false) 2294 require.NotNil(t, err) 2295 AssertAllPostsCount(t, th.App, initialPostCount, 0, "") 2296 2297 // Try adding a valid post in apply mode. 2298 data = &DirectPostImportData{ 2299 ChannelMembers: &[]string{ 2300 th.BasicUser.Username, 2301 th.BasicUser2.Username, 2302 user3.Username, 2303 }, 2304 User: ptrStr(th.BasicUser.Username), 2305 Message: ptrStr("Message"), 2306 CreateAt: ptrInt64(model.GetMillis()), 2307 } 2308 err = th.App.ImportDirectPost(data, false) 2309 require.Nil(t, err) 2310 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2311 2312 // Check the post values. 2313 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt) 2314 require.Nil(t, result.Err) 2315 2316 posts = result.Data.([]*model.Post) 2317 require.Equal(t, len(posts), 1) 2318 2319 post = posts[0] 2320 require.Equal(t, post.Message, *data.Message) 2321 require.Equal(t, post.CreateAt, *data.CreateAt) 2322 require.Equal(t, post.UserId, th.BasicUser.Id) 2323 2324 // Import the post again. 2325 err = th.App.ImportDirectPost(data, false) 2326 require.Nil(t, err) 2327 AssertAllPostsCount(t, th.App, initialPostCount, 1, "") 2328 2329 // Check the post values. 2330 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt) 2331 require.Nil(t, result.Err) 2332 2333 posts = result.Data.([]*model.Post) 2334 require.Equal(t, len(posts), 1) 2335 2336 post = posts[0] 2337 require.Equal(t, post.Message, *data.Message) 2338 require.Equal(t, post.CreateAt, *data.CreateAt) 2339 require.Equal(t, post.UserId, th.BasicUser.Id) 2340 2341 // Save the post with a different time. 2342 data.CreateAt = ptrInt64(*data.CreateAt + 1) 2343 err = th.App.ImportDirectPost(data, false) 2344 require.Nil(t, err) 2345 AssertAllPostsCount(t, th.App, initialPostCount, 2, "") 2346 2347 // Save the post with a different message. 2348 data.Message = ptrStr("Message 2") 2349 err = th.App.ImportDirectPost(data, false) 2350 require.Nil(t, err) 2351 AssertAllPostsCount(t, th.App, initialPostCount, 3, "") 2352 2353 // Test with hashtags 2354 data.Message = ptrStr("Message 2 #hashtagmashupcity") 2355 data.CreateAt = ptrInt64(*data.CreateAt + 1) 2356 err = th.App.ImportDirectPost(data, false) 2357 require.Nil(t, err) 2358 AssertAllPostsCount(t, th.App, initialPostCount, 4, "") 2359 2360 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt) 2361 require.Nil(t, result.Err) 2362 2363 posts = result.Data.([]*model.Post) 2364 require.Equal(t, len(posts), 1) 2365 2366 post = posts[0] 2367 require.Equal(t, post.Message, *data.Message) 2368 require.Equal(t, post.CreateAt, *data.CreateAt) 2369 require.Equal(t, post.UserId, th.BasicUser.Id) 2370 require.Equal(t, post.Hashtags, "#hashtagmashupcity") 2371 2372 // Test with some flags. 2373 data = &DirectPostImportData{ 2374 ChannelMembers: &[]string{ 2375 th.BasicUser.Username, 2376 th.BasicUser2.Username, 2377 user3.Username, 2378 }, 2379 FlaggedBy: &[]string{ 2380 th.BasicUser.Username, 2381 th.BasicUser2.Username, 2382 }, 2383 User: ptrStr(th.BasicUser.Username), 2384 Message: ptrStr("Message"), 2385 CreateAt: ptrInt64(model.GetMillis()), 2386 } 2387 2388 err = th.App.ImportDirectPost(data, false) 2389 require.Nil(t, err) 2390 2391 // Check the post values. 2392 result = <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt) 2393 require.Nil(t, result.Err) 2394 2395 posts = result.Data.([]*model.Post) 2396 require.Equal(t, len(posts), 1) 2397 2398 post = posts[0] 2399 checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2400 checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true") 2401 2402 } 2403 2404 func TestImportImportEmoji(t *testing.T) { 2405 th := Setup(t) 2406 defer th.TearDown() 2407 2408 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCustomEmoji = true }) 2409 2410 testsDir, _ := fileutils.FindDir("tests") 2411 testImage := filepath.Join(testsDir, "test.png") 2412 2413 data := EmojiImportData{Name: ptrStr(model.NewId())} 2414 err := th.App.ImportEmoji(&data, true) 2415 assert.NotNil(t, err, "Invalid emoji should have failed dry run") 2416 2417 result := <-th.App.Srv.Store.Emoji().GetByName(*data.Name) 2418 assert.Nil(t, result.Data, "Emoji should not have been imported") 2419 2420 data.Image = ptrStr(testImage) 2421 err = th.App.ImportEmoji(&data, true) 2422 assert.Nil(t, err, "Valid emoji should have passed dry run") 2423 2424 data = EmojiImportData{Name: ptrStr(model.NewId())} 2425 err = th.App.ImportEmoji(&data, false) 2426 assert.NotNil(t, err, "Invalid emoji should have failed apply mode") 2427 2428 data.Image = ptrStr("non-existent-file") 2429 err = th.App.ImportEmoji(&data, false) 2430 assert.NotNil(t, err, "Emoji with bad image file should have failed apply mode") 2431 2432 data.Image = ptrStr(testImage) 2433 err = th.App.ImportEmoji(&data, false) 2434 assert.Nil(t, err, "Valid emoji should have succeeded apply mode") 2435 2436 result = <-th.App.Srv.Store.Emoji().GetByName(*data.Name) 2437 assert.NotNil(t, result.Data, "Emoji should have been imported") 2438 2439 err = th.App.ImportEmoji(&data, false) 2440 assert.Nil(t, err, "Second run should have succeeded apply mode") 2441 } 2442 2443 func TestImportAttachment(t *testing.T) { 2444 th := Setup(t) 2445 defer th.TearDown() 2446 2447 testsDir, _ := fileutils.FindDir("tests") 2448 testImage := filepath.Join(testsDir, "test.png") 2449 invalidPath := "some-invalid-path" 2450 2451 userId := model.NewId() 2452 data := AttachmentImportData{Path: &testImage} 2453 _, err := th.App.ImportAttachment(&data, &model.Post{UserId: userId, ChannelId: "some-channel"}, "some-team", true) 2454 assert.Nil(t, err, "sample run without errors") 2455 2456 attachments := GetAttachments(userId, th, t) 2457 assert.Equal(t, len(attachments), 1) 2458 2459 data = AttachmentImportData{Path: &invalidPath} 2460 _, err = th.App.ImportAttachment(&data, &model.Post{UserId: model.NewId(), ChannelId: "some-channel"}, "some-team", true) 2461 assert.NotNil(t, err, "should have failed when opening the file") 2462 assert.Equal(t, err.Id, "app.import.attachment.bad_file.error") 2463 } 2464 2465 func TestImportPostAndRepliesWithAttachments(t *testing.T) { 2466 2467 th := Setup(t) 2468 defer th.TearDown() 2469 2470 // Create a Team. 2471 teamName := model.NewId() 2472 th.App.ImportTeam(&TeamImportData{ 2473 Name: &teamName, 2474 DisplayName: ptrStr("Display Name"), 2475 Type: ptrStr("O"), 2476 }, false) 2477 team, err := th.App.GetTeamByName(teamName) 2478 if err != nil { 2479 t.Fatalf("Failed to get team from database.") 2480 } 2481 2482 // Create a Channel. 2483 channelName := model.NewId() 2484 th.App.ImportChannel(&ChannelImportData{ 2485 Team: &teamName, 2486 Name: &channelName, 2487 DisplayName: ptrStr("Display Name"), 2488 Type: ptrStr("O"), 2489 }, false) 2490 _, err = th.App.GetChannelByName(channelName, team.Id, false) 2491 if err != nil { 2492 t.Fatalf("Failed to get channel from database.") 2493 } 2494 2495 // Create a user3. 2496 username := model.NewId() 2497 th.App.ImportUser(&UserImportData{ 2498 Username: &username, 2499 Email: ptrStr(model.NewId() + "@example.com"), 2500 }, false) 2501 user3, err := th.App.GetUserByUsername(username) 2502 if err != nil { 2503 t.Fatalf("Failed to get user3 from database.") 2504 } 2505 2506 username2 := model.NewId() 2507 th.App.ImportUser(&UserImportData{ 2508 Username: &username2, 2509 Email: ptrStr(model.NewId() + "@example.com"), 2510 }, false) 2511 user4, err := th.App.GetUserByUsername(username2) 2512 if err != nil { 2513 t.Fatalf("Failed to get user3 from database.") 2514 } 2515 2516 // Post with attachments. 2517 time := model.GetMillis() 2518 attachmentsPostTime := time 2519 attachmentsReplyTime := time + 1 2520 testsDir, _ := fileutils.FindDir("tests") 2521 testImage := filepath.Join(testsDir, "test.png") 2522 testMarkDown := filepath.Join(testsDir, "test-attachments.md") 2523 data := &PostImportData{ 2524 Team: &teamName, 2525 Channel: &channelName, 2526 User: &username, 2527 Message: ptrStr("Message with reply"), 2528 CreateAt: &attachmentsPostTime, 2529 Attachments: &[]AttachmentImportData{{Path: &testImage}, {Path: &testMarkDown}}, 2530 Replies: &[]ReplyImportData{{ 2531 User: &user4.Username, 2532 Message: ptrStr("Message reply"), 2533 CreateAt: &attachmentsReplyTime, 2534 Attachments: &[]AttachmentImportData{{Path: &testImage}}, 2535 }}, 2536 } 2537 2538 err = th.App.ImportPost(data, false) 2539 assert.Nil(t, err) 2540 2541 attachments := GetAttachments(user3.Id, th, t) 2542 assert.Equal(t, len(attachments), 2) 2543 assert.Contains(t, attachments[0].Path, team.Id) 2544 assert.Contains(t, attachments[1].Path, team.Id) 2545 AssertFileIdsInPost(attachments, th, t) 2546 2547 attachments = GetAttachments(user4.Id, th, t) 2548 assert.Equal(t, len(attachments), 1) 2549 assert.Contains(t, attachments[0].Path, team.Id) 2550 AssertFileIdsInPost(attachments, th, t) 2551 2552 // Reply with Attachments in Direct Post 2553 2554 // Create direct post users. 2555 2556 username3 := model.NewId() 2557 th.App.ImportUser(&UserImportData{ 2558 Username: &username3, 2559 Email: ptrStr(model.NewId() + "@example.com"), 2560 }, false) 2561 user3, err = th.App.GetUserByUsername(username3) 2562 if err != nil { 2563 t.Fatalf("Failed to get user3 from database.") 2564 } 2565 2566 username4 := model.NewId() 2567 th.App.ImportUser(&UserImportData{ 2568 Username: &username4, 2569 Email: ptrStr(model.NewId() + "@example.com"), 2570 }, false) 2571 2572 user4, err = th.App.GetUserByUsername(username4) 2573 if err != nil { 2574 t.Fatalf("Failed to get user3 from database.") 2575 } 2576 2577 directImportData := &DirectPostImportData{ 2578 ChannelMembers: &[]string{ 2579 user3.Username, 2580 user4.Username, 2581 }, 2582 User: &user3.Username, 2583 Message: ptrStr("Message with Replies"), 2584 CreateAt: ptrInt64(model.GetMillis()), 2585 Replies: &[]ReplyImportData{{ 2586 User: &user4.Username, 2587 Message: ptrStr("Message reply with attachment"), 2588 CreateAt: ptrInt64(model.GetMillis()), 2589 Attachments: &[]AttachmentImportData{{Path: &testImage}}, 2590 }}, 2591 } 2592 2593 if err := th.App.ImportDirectPost(directImportData, false); err != nil { 2594 t.Fatalf("Expected success.") 2595 } 2596 2597 attachments = GetAttachments(user4.Id, th, t) 2598 assert.Equal(t, len(attachments), 1) 2599 assert.Contains(t, attachments[0].Path, "noteam") 2600 AssertFileIdsInPost(attachments, th, t) 2601 2602 } 2603 2604 func TestImportDirectPostWithAttachments(t *testing.T) { 2605 2606 th := Setup(t) 2607 defer th.TearDown() 2608 2609 testsDir, _ := fileutils.FindDir("tests") 2610 testImage := filepath.Join(testsDir, "test.png") 2611 2612 // Create a user. 2613 username := model.NewId() 2614 th.App.ImportUser(&UserImportData{ 2615 Username: &username, 2616 Email: ptrStr(model.NewId() + "@example.com"), 2617 }, false) 2618 user1, err := th.App.GetUserByUsername(username) 2619 if err != nil { 2620 t.Fatalf("Failed to get user1 from database.") 2621 } 2622 2623 username2 := model.NewId() 2624 th.App.ImportUser(&UserImportData{ 2625 Username: &username2, 2626 Email: ptrStr(model.NewId() + "@example.com"), 2627 }, false) 2628 2629 user2, err := th.App.GetUserByUsername(username2) 2630 if err != nil { 2631 t.Fatalf("Failed to get user2 from database.") 2632 } 2633 2634 directImportData := &DirectPostImportData{ 2635 ChannelMembers: &[]string{ 2636 user1.Username, 2637 user2.Username, 2638 }, 2639 User: &user1.Username, 2640 Message: ptrStr("Direct message"), 2641 CreateAt: ptrInt64(model.GetMillis()), 2642 Attachments: &[]AttachmentImportData{{Path: &testImage}}, 2643 } 2644 2645 if err := th.App.ImportDirectPost(directImportData, false); err != nil { 2646 t.Fatalf("Expected success.") 2647 } 2648 2649 attachments := GetAttachments(user1.Id, th, t) 2650 assert.Equal(t, len(attachments), 1) 2651 assert.Contains(t, attachments[0].Path, "noteam") 2652 AssertFileIdsInPost(attachments, th, t) 2653 }