summaryrefslogtreecommitdiffstats
path: root/app/import_functions_test.go
diff options
context:
space:
mode:
authorJesús Espino <jespinog@gmail.com>2018-08-01 15:45:26 +0200
committerGitHub <noreply@github.com>2018-08-01 15:45:26 +0200
commit1f168263a2ff73ddee1193cccdeea533f6d501fe (patch)
tree61a59be015b121cee5df9b4c6cf809980814ff63 /app/import_functions_test.go
parentf4fdd7835b8eeb04106a9ff6a4f85b8593d9074b (diff)
downloadchat-1f168263a2ff73ddee1193cccdeea533f6d501fe.tar.gz
chat-1f168263a2ff73ddee1193cccdeea533f6d501fe.tar.bz2
chat-1f168263a2ff73ddee1193cccdeea533f6d501fe.zip
Split app/import.go in multiple files (#9179)
Diffstat (limited to 'app/import_functions_test.go')
-rw-r--r--app/import_functions_test.go2501
1 files changed, 2501 insertions, 0 deletions
diff --git a/app/import_functions_test.go b/app/import_functions_test.go
new file mode 100644
index 000000000..e0859af45
--- /dev/null
+++ b/app/import_functions_test.go
@@ -0,0 +1,2501 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package app
+
+import (
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/mattermost/mattermost-server/model"
+ "github.com/mattermost/mattermost-server/store"
+ "github.com/mattermost/mattermost-server/utils"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestImportImportScheme(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ // Try importing an invalid scheme in dryRun mode.
+ data := SchemeImportData{
+ Name: ptrStr(model.NewId()),
+ Scope: ptrStr("team"),
+ DefaultTeamUserRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultTeamAdminRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultChannelUserRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultChannelAdminRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ Description: ptrStr("description"),
+ }
+
+ if err := th.App.ImportScheme(&data, true); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil {
+ t.Fatalf("Scheme should not have imported.")
+ }
+
+ // Try importing a valid scheme in dryRun mode.
+ data.DisplayName = ptrStr("display name")
+
+ if err := th.App.ImportScheme(&data, true); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil {
+ t.Fatalf("Scheme should not have imported.")
+ }
+
+ // Try importing an invalid scheme.
+ data.DisplayName = nil
+
+ if err := th.App.ImportScheme(&data, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil {
+ t.Fatalf("Scheme should not have imported.")
+ }
+
+ // Try importing a valid scheme with all params set.
+ data.DisplayName = ptrStr("display name")
+
+ if err := th.App.ImportScheme(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ scheme := res.Data.(*model.Scheme)
+ assert.Equal(t, *data.Name, scheme.Name)
+ assert.Equal(t, *data.DisplayName, scheme.DisplayName)
+ assert.Equal(t, *data.Description, scheme.Description)
+ assert.Equal(t, *data.Scope, scheme.Scope)
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+ }
+
+ // Try modifying all the fields and re-importing.
+ data.DisplayName = ptrStr("new display name")
+ data.Description = ptrStr("new description")
+
+ if err := th.App.ImportScheme(&data, false); err != nil {
+ t.Fatalf("Should have succeeded: %v", err)
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ scheme := res.Data.(*model.Scheme)
+ assert.Equal(t, *data.Name, scheme.Name)
+ assert.Equal(t, *data.DisplayName, scheme.DisplayName)
+ assert.Equal(t, *data.Description, scheme.Description)
+ assert.Equal(t, *data.Scope, scheme.Scope)
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+ }
+
+ // Try changing the scope of the scheme and reimporting.
+ data.Scope = ptrStr("channel")
+
+ if err := th.App.ImportScheme(&data, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ scheme := res.Data.(*model.Scheme)
+ assert.Equal(t, *data.Name, scheme.Name)
+ assert.Equal(t, *data.DisplayName, scheme.DisplayName)
+ assert.Equal(t, *data.Description, scheme.Description)
+ assert.Equal(t, "team", scheme.Scope)
+ }
+}
+
+func TestImportImportRole(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Try importing an invalid role in dryRun mode.
+ rid1 := model.NewId()
+ data := RoleImportData{
+ Name: &rid1,
+ }
+
+ if err := th.App.ImportRole(&data, true, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil {
+ t.Fatalf("Role should not have imported.")
+ }
+
+ // Try importing the valid role in dryRun mode.
+ data.DisplayName = ptrStr("display name")
+
+ if err := th.App.ImportRole(&data, true, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil {
+ t.Fatalf("Role should not have imported as we are in dry run mode.")
+ }
+
+ // Try importing an invalid role.
+ data.DisplayName = nil
+
+ if err := th.App.ImportRole(&data, false, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil {
+ t.Fatalf("Role should not have imported.")
+ }
+
+ // Try importing a valid role with all params set.
+ data.DisplayName = ptrStr("display name")
+ data.Description = ptrStr("description")
+ data.Permissions = &[]string{"invite_user", "add_user_to_team"}
+
+ if err := th.App.ImportRole(&data, false, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.Name, role.Name)
+ assert.Equal(t, *data.DisplayName, role.DisplayName)
+ assert.Equal(t, *data.Description, role.Description)
+ assert.Equal(t, *data.Permissions, role.Permissions)
+ assert.False(t, role.BuiltIn)
+ assert.False(t, role.SchemeManaged)
+ }
+
+ // Try changing all the params and reimporting.
+ data.DisplayName = ptrStr("new display name")
+ data.Description = ptrStr("description")
+ data.Permissions = &[]string{"use_slash_commands"}
+
+ if err := th.App.ImportRole(&data, false, true); err != nil {
+ t.Fatalf("Should have succeeded. %v", err)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.Name, role.Name)
+ assert.Equal(t, *data.DisplayName, role.DisplayName)
+ assert.Equal(t, *data.Description, role.Description)
+ assert.Equal(t, *data.Permissions, role.Permissions)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ // Check that re-importing with only required fields doesn't update the others.
+ data2 := RoleImportData{
+ Name: &rid1,
+ DisplayName: ptrStr("new display name again"),
+ }
+
+ if err := th.App.ImportRole(&data2, false, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data2.Name, role.Name)
+ assert.Equal(t, *data2.DisplayName, role.DisplayName)
+ assert.Equal(t, *data.Description, role.Description)
+ assert.Equal(t, *data.Permissions, role.Permissions)
+ assert.False(t, role.BuiltIn)
+ assert.False(t, role.SchemeManaged)
+ }
+}
+
+func TestImportImportTeam(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ scheme1 := th.SetupTeamScheme()
+ scheme2 := th.SetupTeamScheme()
+
+ // Check how many teams are in the database.
+ var teamsCount int64
+ if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
+ teamsCount = r.Data.(int64)
+ } else {
+ t.Fatalf("Failed to get team count.")
+ }
+
+ data := TeamImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("XYZ"),
+ Description: ptrStr("The team description."),
+ AllowOpenInvite: ptrBool(true),
+ Scheme: &scheme1.Name,
+ }
+
+ // Try importing an invalid team in dryRun mode.
+ if err := th.App.ImportTeam(&data, true); err == nil {
+ t.Fatalf("Should have received an error importing an invalid team.")
+ }
+
+ // Do a valid team in dry-run mode.
+ data.Type = ptrStr("O")
+ if err := th.App.ImportTeam(&data, true); err != nil {
+ t.Fatalf("Received an error validating valid team.")
+ }
+
+ // Check that no more teams are in the DB.
+ th.CheckTeamCount(t, teamsCount)
+
+ // Do an invalid team in apply mode, check db changes.
+ data.Type = ptrStr("XYZ")
+ if err := th.App.ImportTeam(&data, false); err == nil {
+ t.Fatalf("Import should have failed on invalid team.")
+ }
+
+ // Check that no more teams are in the DB.
+ th.CheckTeamCount(t, teamsCount)
+
+ // Do a valid team in apply mode, check db changes.
+ data.Type = ptrStr("O")
+ if err := th.App.ImportTeam(&data, false); err != nil {
+ t.Fatalf("Received an error importing valid team: %v", err)
+ }
+
+ // Check that one more team is in the DB.
+ th.CheckTeamCount(t, teamsCount+1)
+
+ // Get the team and check that all the fields are correct.
+ if team, err := th.App.GetTeamByName(*data.Name); err != nil {
+ t.Fatalf("Failed to get team from database.")
+ } else {
+ assert.Equal(t, *data.DisplayName, team.DisplayName)
+ assert.Equal(t, *data.Type, team.Type)
+ assert.Equal(t, *data.Description, team.Description)
+ assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite)
+ assert.Equal(t, scheme1.Id, *team.SchemeId)
+ }
+
+ // Alter all the fields of that team (apart from unique identifier) and import again.
+ data.DisplayName = ptrStr("Display Name 2")
+ data.Type = ptrStr("P")
+ data.Description = ptrStr("The new description")
+ data.AllowOpenInvite = ptrBool(false)
+ data.Scheme = &scheme2.Name
+
+ // Check that the original number of teams are again in the DB (because this query doesn't include deleted).
+ data.Type = ptrStr("O")
+ if err := th.App.ImportTeam(&data, false); err != nil {
+ t.Fatalf("Received an error importing updated valid team.")
+ }
+
+ th.CheckTeamCount(t, teamsCount+1)
+
+ // Get the team and check that all fields are correct.
+ if team, err := th.App.GetTeamByName(*data.Name); err != nil {
+ t.Fatalf("Failed to get team from database.")
+ } else {
+ assert.Equal(t, *data.DisplayName, team.DisplayName)
+ assert.Equal(t, *data.Type, team.Type)
+ assert.Equal(t, *data.Description, team.Description)
+ assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite)
+ assert.Equal(t, scheme2.Id, *team.SchemeId)
+ }
+}
+
+func TestImportImportChannel(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ scheme1 := th.SetupChannelScheme()
+ scheme2 := th.SetupChannelScheme()
+
+ // Import a Team.
+ teamName := model.NewId()
+ th.App.ImportTeam(&TeamImportData{
+ Name: &teamName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ team, err := th.App.GetTeamByName(teamName)
+ if err != nil {
+ t.Fatalf("Failed to get team from database.")
+ }
+
+ // Check how many channels are in the database.
+ var channelCount int64
+ if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
+ channelCount = r.Data.(int64)
+ } else {
+ t.Fatalf("Failed to get team count.")
+ }
+
+ // Do an invalid channel in dry-run mode.
+ data := ChannelImportData{
+ Team: &teamName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ Header: ptrStr("Channe Header"),
+ Purpose: ptrStr("Channel Purpose"),
+ Scheme: &scheme1.Name,
+ }
+ if err := th.App.ImportChannel(&data, true); err == nil {
+ t.Fatalf("Expected error due to invalid name.")
+ }
+
+ // Check that no more channels are in the DB.
+ th.CheckChannelsCount(t, channelCount)
+
+ // Do a valid channel with a nonexistent team in dry-run mode.
+ data.Name = ptrStr("channelname")
+ data.Team = ptrStr(model.NewId())
+ if err := th.App.ImportChannel(&data, true); err != nil {
+ t.Fatalf("Expected success as cannot validate channel name in dry run mode.")
+ }
+
+ // Check that no more channels are in the DB.
+ th.CheckChannelsCount(t, channelCount)
+
+ // Do a valid channel in dry-run mode.
+ data.Team = &teamName
+ if err := th.App.ImportChannel(&data, true); err != nil {
+ t.Fatalf("Expected success as valid team.")
+ }
+
+ // Check that no more channels are in the DB.
+ th.CheckChannelsCount(t, channelCount)
+
+ // Do an invalid channel in apply mode.
+ data.Name = nil
+ if err := th.App.ImportChannel(&data, false); err == nil {
+ t.Fatalf("Expected error due to invalid name (apply mode).")
+ }
+
+ // Check that no more channels are in the DB.
+ th.CheckChannelsCount(t, channelCount)
+
+ // Do a valid channel in apply mode with a non-existent team.
+ data.Name = ptrStr("channelname")
+ data.Team = ptrStr(model.NewId())
+ if err := th.App.ImportChannel(&data, false); err == nil {
+ t.Fatalf("Expected error due to non-existent team (apply mode).")
+ }
+
+ // Check that no more channels are in the DB.
+ th.CheckChannelsCount(t, channelCount)
+
+ // Do a valid channel in apply mode.
+ data.Team = &teamName
+ if err := th.App.ImportChannel(&data, false); err != nil {
+ t.Fatalf("Expected success in apply mode: %v", err.Error())
+ }
+
+ // Check that 1 more channel is in the DB.
+ th.CheckChannelsCount(t, channelCount+1)
+
+ // Get the Channel and check all the fields are correct.
+ if channel, err := th.App.GetChannelByName(*data.Name, team.Id, false); err != nil {
+ t.Fatalf("Failed to get channel from database.")
+ } else {
+ assert.Equal(t, *data.Name, channel.Name)
+ assert.Equal(t, *data.DisplayName, channel.DisplayName)
+ assert.Equal(t, *data.Type, channel.Type)
+ assert.Equal(t, *data.Header, channel.Header)
+ assert.Equal(t, *data.Purpose, channel.Purpose)
+ assert.Equal(t, scheme1.Id, *channel.SchemeId)
+ }
+
+ // Alter all the fields of that channel.
+ data.DisplayName = ptrStr("Chaned Disp Name")
+ data.Type = ptrStr(model.CHANNEL_PRIVATE)
+ data.Header = ptrStr("New Header")
+ data.Purpose = ptrStr("New Purpose")
+ data.Scheme = &scheme2.Name
+ if err := th.App.ImportChannel(&data, false); err != nil {
+ t.Fatalf("Expected success in apply mode: %v", err.Error())
+ }
+
+ // Check channel count the same.
+ th.CheckChannelsCount(t, channelCount)
+
+ // Get the Channel and check all the fields are correct.
+ if channel, err := th.App.GetChannelByName(*data.Name, team.Id, false); err != nil {
+ t.Fatalf("Failed to get channel from database.")
+ } else {
+ assert.Equal(t, *data.Name, channel.Name)
+ assert.Equal(t, *data.DisplayName, channel.DisplayName)
+ assert.Equal(t, *data.Type, channel.Type)
+ assert.Equal(t, *data.Header, channel.Header)
+ assert.Equal(t, *data.Purpose, channel.Purpose)
+ assert.Equal(t, scheme2.Id, *channel.SchemeId)
+ }
+
+}
+
+func TestImportImportUser(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Check how many users are in the database.
+ var userCount int64
+ if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil {
+ userCount = r.Data.(int64)
+ } else {
+ t.Fatalf("Failed to get user count.")
+ }
+
+ // Do an invalid user in dry-run mode.
+ data := UserImportData{
+ Username: ptrStr(model.NewId()),
+ }
+ if err := th.App.ImportUser(&data, true); err == nil {
+ t.Fatalf("Should have failed to import invalid user.")
+ }
+
+ // Check that no more users are in the DB.
+ if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil {
+ if r.Data.(int64) != userCount {
+ t.Fatalf("Unexpected number of users")
+ }
+ } else {
+ t.Fatalf("Failed to get user count.")
+ }
+
+ // Do a valid user in dry-run mode.
+ data = UserImportData{
+ Username: ptrStr(model.NewId()),
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }
+ if err := th.App.ImportUser(&data, true); err != nil {
+ t.Fatalf("Should have succeeded to import valid user.")
+ }
+
+ // Check that no more users are in the DB.
+ if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil {
+ if r.Data.(int64) != userCount {
+ t.Fatalf("Unexpected number of users")
+ }
+ } else {
+ t.Fatalf("Failed to get user count.")
+ }
+
+ // Do an invalid user in apply mode.
+ data = UserImportData{
+ Username: ptrStr(model.NewId()),
+ }
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed to import invalid user.")
+ }
+
+ // Check that no more users are in the DB.
+ if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil {
+ if r.Data.(int64) != userCount {
+ t.Fatalf("Unexpected number of users")
+ }
+ } else {
+ t.Fatalf("Failed to get user count.")
+ }
+
+ // Do a valid user in apply mode.
+ username := model.NewId()
+ testsDir, _ := utils.FindDir("tests")
+ data = UserImportData{
+ ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")),
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ Nickname: ptrStr(model.NewId()),
+ FirstName: ptrStr(model.NewId()),
+ LastName: ptrStr(model.NewId()),
+ Position: ptrStr(model.NewId()),
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded to import valid user.")
+ }
+
+ // Check that one more user is in the DB.
+ if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil {
+ if r.Data.(int64) != userCount+1 {
+ t.Fatalf("Unexpected number of users")
+ }
+ } else {
+ t.Fatalf("Failed to get user count.")
+ }
+
+ // Get the user and check all the fields are correct.
+ if user, err := th.App.GetUserByUsername(username); err != nil {
+ t.Fatalf("Failed to get user from database.")
+ } else {
+ if user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position {
+ t.Fatalf("User properties do not match Import Data.")
+ }
+ // Check calculated properties.
+ if user.AuthService != "" {
+ t.Fatalf("Expected Auth Service to be empty.")
+ }
+
+ if !(user.AuthData == nil || *user.AuthData == "") {
+ t.Fatalf("Expected AuthData to be empty.")
+ }
+
+ if len(user.Password) == 0 {
+ t.Fatalf("Expected password to be set.")
+ }
+
+ if !user.EmailVerified {
+ t.Fatalf("Expected EmailVerified to be true.")
+ }
+
+ if user.Locale != *th.App.Config().LocalizationSettings.DefaultClientLocale {
+ t.Fatalf("Expected Locale to be the default.")
+ }
+
+ if user.Roles != "system_user" {
+ t.Fatalf("Expected roles to be system_user")
+ }
+ }
+
+ // Alter all the fields of that user.
+ data.Email = ptrStr(model.NewId() + "@example.com")
+ data.ProfileImage = ptrStr(filepath.Join(testsDir, "testgif.gif"))
+ data.AuthService = ptrStr("ldap")
+ data.AuthData = &username
+ data.Nickname = ptrStr(model.NewId())
+ data.FirstName = ptrStr(model.NewId())
+ data.LastName = ptrStr(model.NewId())
+ data.Position = ptrStr(model.NewId())
+ data.Roles = ptrStr("system_admin system_user")
+ data.Locale = ptrStr("zh_CN")
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded to update valid user %v", err)
+ }
+
+ // Check user count the same.
+ if r := <-th.App.Srv.Store.User().GetTotalUsersCount(); r.Err == nil {
+ if r.Data.(int64) != userCount+1 {
+ t.Fatalf("Unexpected number of users")
+ }
+ } else {
+ t.Fatalf("Failed to get user count.")
+ }
+
+ // Get the user and check all the fields are correct.
+ if user, err := th.App.GetUserByUsername(username); err != nil {
+ t.Fatalf("Failed to get user from database.")
+ } else {
+ if user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position {
+ t.Fatalf("Updated User properties do not match Import Data.")
+ }
+ // Check calculated properties.
+ if user.AuthService != "ldap" {
+ t.Fatalf("Expected Auth Service to be ldap \"%v\"", user.AuthService)
+ }
+
+ if !(user.AuthData == data.AuthData || *user.AuthData == *data.AuthData) {
+ t.Fatalf("Expected AuthData to be set.")
+ }
+
+ if len(user.Password) != 0 {
+ t.Fatalf("Expected password to be empty.")
+ }
+
+ if !user.EmailVerified {
+ t.Fatalf("Expected EmailVerified to be true.")
+ }
+
+ if user.Locale != *data.Locale {
+ t.Fatalf("Expected Locale to be the set.")
+ }
+
+ if user.Roles != *data.Roles {
+ t.Fatalf("Expected roles to be set: %v", user.Roles)
+ }
+ }
+
+ // Check Password and AuthData together.
+ data.Password = ptrStr("PasswordTest")
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed to import invalid user.")
+ }
+
+ data.AuthData = nil
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded to update valid user %v", err)
+ }
+
+ data.Password = ptrStr("")
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed to import invalid user.")
+ }
+
+ data.Password = ptrStr(strings.Repeat("0123456789", 10))
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed to import invalid user.")
+ }
+
+ data.Password = ptrStr("TestPassword")
+
+ // Test team and channel memberships
+ teamName := model.NewId()
+ th.App.ImportTeam(&TeamImportData{
+ Name: &teamName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ team, err := th.App.GetTeamByName(teamName)
+ if err != nil {
+ t.Fatalf("Failed to get team from database.")
+ }
+
+ channelName := model.NewId()
+ th.App.ImportChannel(&ChannelImportData{
+ Team: &teamName,
+ Name: &channelName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ channel, err := th.App.GetChannelByName(channelName, team.Id, false)
+ if err != nil {
+ t.Fatalf("Failed to get channel from database.")
+ }
+
+ username = model.NewId()
+ data = UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ Nickname: ptrStr(model.NewId()),
+ FirstName: ptrStr(model.NewId()),
+ LastName: ptrStr(model.NewId()),
+ Position: ptrStr(model.NewId()),
+ }
+
+ teamMembers, err := th.App.GetTeamMembers(team.Id, 0, 1000)
+ if err != nil {
+ t.Fatalf("Failed to get team member count")
+ }
+ teamMemberCount := len(teamMembers)
+
+ channelMemberCount, err := th.App.GetChannelMemberCount(channel.Id)
+ if err != nil {
+ t.Fatalf("Failed to get channel member count")
+ }
+
+ // Test with an invalid team & channel membership in dry-run mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Roles: ptrStr("invalid"),
+ Channels: &[]UserChannelImportData{
+ {
+ Roles: ptrStr("invalid"),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, true); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Test with an unknown team name & invalid channel membership in dry-run mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: ptrStr(model.NewId()),
+ Channels: &[]UserChannelImportData{
+ {
+ Roles: ptrStr("invalid"),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, true); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Test with a valid team & invalid channel membership in dry-run mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Channels: &[]UserChannelImportData{
+ {
+ Roles: ptrStr("invalid"),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, true); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Test with a valid team & unknown channel name in dry-run mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Channels: &[]UserChannelImportData{
+ {
+ Name: ptrStr(model.NewId()),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, true); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ // Test with a valid team & valid channel name in dry-run mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Channels: &[]UserChannelImportData{
+ {
+ Name: &channelName,
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, true); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ // Check no new member objects were created because dry run mode.
+ if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil {
+ t.Fatalf("Failed to get Team Member Count")
+ } else if len(tmc) != teamMemberCount {
+ t.Fatalf("Number of team members not as expected")
+ }
+
+ if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil {
+ t.Fatalf("Failed to get Channel Member Count")
+ } else if cmc != channelMemberCount {
+ t.Fatalf("Number of channel members not as expected")
+ }
+
+ // Test with an invalid team & channel membership in apply mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Roles: ptrStr("invalid"),
+ Channels: &[]UserChannelImportData{
+ {
+ Roles: ptrStr("invalid"),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Test with an unknown team name & invalid channel membership in apply mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: ptrStr(model.NewId()),
+ Channels: &[]UserChannelImportData{
+ {
+ Roles: ptrStr("invalid"),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Test with a valid team & invalid channel membership in apply mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Channels: &[]UserChannelImportData{
+ {
+ Roles: ptrStr("invalid"),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Check no new member objects were created because all tests should have failed so far.
+ if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil {
+ t.Fatalf("Failed to get Team Member Count")
+ } else if len(tmc) != teamMemberCount {
+ t.Fatalf("Number of team members not as expected")
+ }
+
+ if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil {
+ t.Fatalf("Failed to get Channel Member Count")
+ } else if cmc != channelMemberCount {
+ t.Fatalf("Number of channel members not as expected")
+ }
+
+ // Test with a valid team & unknown channel name in apply mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Channels: &[]UserChannelImportData{
+ {
+ Name: ptrStr(model.NewId()),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, false); err == nil {
+ t.Fatalf("Should have failed.")
+ }
+
+ // Check only new team member object created because dry run mode.
+ if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil {
+ t.Fatalf("Failed to get Team Member Count")
+ } else if len(tmc) != teamMemberCount+1 {
+ t.Fatalf("Number of team members not as expected")
+ }
+
+ if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil {
+ t.Fatalf("Failed to get Channel Member Count")
+ } else if cmc != channelMemberCount {
+ t.Fatalf("Number of channel members not as expected")
+ }
+
+ // Check team member properties.
+ user, err := th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+ if teamMember, err := th.App.GetTeamMember(team.Id, user.Id); err != nil {
+ t.Fatalf("Failed to get team member from database.")
+ } else if teamMember.Roles != "team_user" {
+ t.Fatalf("Team member properties not as expected")
+ }
+
+ // Test with a valid team & valid channel name in apply mode.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Channels: &[]UserChannelImportData{
+ {
+ Name: &channelName,
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ // Check only new channel member object created because dry run mode.
+ if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil {
+ t.Fatalf("Failed to get Team Member Count")
+ } else if len(tmc) != teamMemberCount+1 {
+ t.Fatalf("Number of team members not as expected")
+ }
+
+ if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil {
+ t.Fatalf("Failed to get Channel Member Count")
+ } else if cmc != channelMemberCount+1 {
+ t.Fatalf("Number of channel members not as expected")
+ }
+
+ // Check channel member properties.
+ if channelMember, err := th.App.GetChannelMember(channel.Id, user.Id); err != nil {
+ t.Fatalf("Failed to get channel member from database.")
+ } else if channelMember.Roles != "channel_user" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.PUSH_NOTIFY_PROP] != "default" || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != "all" {
+ t.Fatalf("Channel member properties not as expected")
+ }
+
+ // Test with the properties of the team and channel membership changed.
+ data.Teams = &[]UserTeamImportData{
+ {
+ Name: &teamName,
+ Roles: ptrStr("team_user team_admin"),
+ Channels: &[]UserChannelImportData{
+ {
+ Name: &channelName,
+ Roles: ptrStr("channel_user channel_admin"),
+ NotifyProps: &UserChannelNotifyPropsImportData{
+ Desktop: ptrStr(model.USER_NOTIFY_MENTION),
+ Mobile: ptrStr(model.USER_NOTIFY_MENTION),
+ MarkUnread: ptrStr(model.USER_NOTIFY_MENTION),
+ },
+ Favorite: ptrBool(true),
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ // Check both member properties.
+ if teamMember, err := th.App.GetTeamMember(team.Id, user.Id); err != nil {
+ t.Fatalf("Failed to get team member from database.")
+ } else if teamMember.Roles != "team_user team_admin" {
+ t.Fatalf("Team member properties not as expected: %v", teamMember.Roles)
+ }
+
+ if channelMember, err := th.App.GetChannelMember(channel.Id, user.Id); err != nil {
+ t.Fatalf("Failed to get channel member Desktop from database.")
+ } else if channelMember.Roles != "channel_user channel_admin" || channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP] != model.USER_NOTIFY_MENTION || channelMember.NotifyProps[model.PUSH_NOTIFY_PROP] != model.USER_NOTIFY_MENTION || channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.USER_NOTIFY_MENTION {
+ t.Fatalf("Channel member properties not as expected")
+ }
+
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true")
+
+ // No more new member objects.
+ if tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000); err != nil {
+ t.Fatalf("Failed to get Team Member Count")
+ } else if len(tmc) != teamMemberCount+1 {
+ t.Fatalf("Number of team members not as expected")
+ }
+
+ if cmc, err := th.App.GetChannelMemberCount(channel.Id); err != nil {
+ t.Fatalf("Failed to get Channel Member Count")
+ } else if cmc != channelMemberCount+1 {
+ t.Fatalf("Number of channel members not as expected")
+ }
+
+ // Add a user with some preferences.
+ username = model.NewId()
+ data = UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ 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"}`),
+ UseMilitaryTime: ptrStr("true"),
+ CollapsePreviews: ptrStr("true"),
+ MessageDisplay: ptrStr("compact"),
+ ChannelDisplayMode: ptrStr("centered"),
+ TutorialStep: ptrStr("3"),
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ // Check their values.
+ user, err = th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "use_military_time", *data.UseMilitaryTime)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "collapse_previews", *data.CollapsePreviews)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "message_display", *data.MessageDisplay)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "channel_display_mode", *data.ChannelDisplayMode)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep)
+
+ // Change those preferences.
+ data = UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ 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"}`),
+ UseMilitaryTime: ptrStr("false"),
+ CollapsePreviews: ptrStr("false"),
+ MessageDisplay: ptrStr("clean"),
+ ChannelDisplayMode: ptrStr("full"),
+ TutorialStep: ptrStr("2"),
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ // Check their values again.
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "use_military_time", *data.UseMilitaryTime)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "collapse_previews", *data.CollapsePreviews)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "message_display", *data.MessageDisplay)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "channel_display_mode", *data.ChannelDisplayMode)
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep)
+
+ // Set Notify Props
+ data.NotifyProps = &UserNotifyPropsImportData{
+ Desktop: ptrStr(model.USER_NOTIFY_ALL),
+ DesktopSound: ptrStr("true"),
+ Email: ptrStr("true"),
+ Mobile: ptrStr(model.USER_NOTIFY_ALL),
+ MobilePushStatus: ptrStr(model.STATUS_ONLINE),
+ ChannelTrigger: ptrStr("true"),
+ CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ROOT),
+ MentionKeys: ptrStr("valid,misc"),
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ user, err = th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL)
+ checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true")
+ checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true")
+ checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL)
+ checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE)
+ checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true")
+ checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT)
+ checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "valid,misc")
+
+ // Change Notify Props
+ data.NotifyProps = &UserNotifyPropsImportData{
+ Desktop: ptrStr(model.USER_NOTIFY_MENTION),
+ DesktopSound: ptrStr("false"),
+ Email: ptrStr("false"),
+ Mobile: ptrStr(model.USER_NOTIFY_NONE),
+ MobilePushStatus: ptrStr(model.STATUS_AWAY),
+ ChannelTrigger: ptrStr("false"),
+ CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY),
+ MentionKeys: ptrStr("misc"),
+ }
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ user, err = th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION)
+ checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false")
+ checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false")
+ checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE)
+ checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY)
+ checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false")
+ checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY)
+ checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc")
+
+ // Check Notify Props get set on *create* user.
+ username = model.NewId()
+ data = UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }
+ data.NotifyProps = &UserNotifyPropsImportData{
+ Desktop: ptrStr(model.USER_NOTIFY_MENTION),
+ DesktopSound: ptrStr("false"),
+ Email: ptrStr("false"),
+ Mobile: ptrStr(model.USER_NOTIFY_NONE),
+ MobilePushStatus: ptrStr(model.STATUS_AWAY),
+ ChannelTrigger: ptrStr("false"),
+ CommentsTrigger: ptrStr(model.COMMENTS_NOTIFY_ANY),
+ MentionKeys: ptrStr("misc"),
+ }
+
+ if err := th.App.ImportUser(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ user, err = th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION)
+ checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false")
+ checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false")
+ checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE)
+ checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY)
+ checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false")
+ checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY)
+ checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc")
+
+ // Test importing a user with roles set to a team and a channel which are affected by an override scheme.
+ // The import subsystem should translate `channel_admin/channel_user/team_admin/team_user`
+ // to the appropriate scheme-managed-role booleans.
+
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ teamSchemeData := &SchemeImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ Scope: ptrStr("team"),
+ DefaultTeamUserRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultTeamAdminRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultChannelUserRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultChannelAdminRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ Description: ptrStr("description"),
+ }
+
+ if err := th.App.ImportScheme(teamSchemeData, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ var teamScheme *model.Scheme
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*teamSchemeData.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ teamScheme = res.Data.(*model.Scheme)
+ }
+
+ teamData := &TeamImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ Description: ptrStr("The team description."),
+ AllowOpenInvite: ptrBool(true),
+ Scheme: &teamScheme.Name,
+ }
+ if err := th.App.ImportTeam(teamData, false); err != nil {
+ t.Fatalf("Import should have succeeded: %v", err.Error())
+ }
+ team, err = th.App.GetTeamByName(teamName)
+ if err != nil {
+ t.Fatalf("Failed to get team from database.")
+ }
+
+ channelData := &ChannelImportData{
+ Team: &teamName,
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ Header: ptrStr("Channe Header"),
+ Purpose: ptrStr("Channel Purpose"),
+ }
+ if err := th.App.ImportChannel(channelData, false); err != nil {
+ t.Fatalf("Import should have succeeded.")
+ }
+ channel, err = th.App.GetChannelByName(*channelData.Name, team.Id, false)
+ if err != nil {
+ t.Fatalf("Failed to get channel from database: %v", err.Error())
+ }
+
+ // Test with a valid team & valid channel name in apply mode.
+ userData := &UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ Teams: &[]UserTeamImportData{
+ {
+ Name: &team.Name,
+ Roles: ptrStr("team_user team_admin"),
+ Channels: &[]UserChannelImportData{
+ {
+ Name: &channel.Name,
+ Roles: ptrStr("channel_admin channel_user"),
+ },
+ },
+ },
+ },
+ }
+ if err := th.App.ImportUser(userData, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ user, err = th.App.GetUserByUsername(*userData.Username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ teamMember, err := th.App.GetTeamMember(team.Id, user.Id)
+ if err != nil {
+ t.Fatalf("Failed to get the team member")
+ }
+ assert.True(t, teamMember.SchemeAdmin)
+ assert.True(t, teamMember.SchemeUser)
+ assert.Equal(t, "", teamMember.ExplicitRoles)
+
+ channelMember, err := th.App.GetChannelMember(channel.Id, user.Id)
+ if err != nil {
+ t.Fatalf("Failed to get the channel member")
+ }
+ assert.True(t, channelMember.SchemeAdmin)
+ assert.True(t, channelMember.SchemeUser)
+ assert.Equal(t, "", channelMember.ExplicitRoles)
+
+}
+
+func TestImportImportPost(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Create a Team.
+ teamName := model.NewId()
+ th.App.ImportTeam(&TeamImportData{
+ Name: &teamName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ team, err := th.App.GetTeamByName(teamName)
+ if err != nil {
+ t.Fatalf("Failed to get team from database.")
+ }
+
+ // Create a Channel.
+ channelName := model.NewId()
+ th.App.ImportChannel(&ChannelImportData{
+ Team: &teamName,
+ Name: &channelName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ channel, err := th.App.GetChannelByName(channelName, team.Id, false)
+ if err != nil {
+ t.Fatalf("Failed to get channel from database.")
+ }
+
+ // Create a user.
+ username := model.NewId()
+ th.App.ImportUser(&UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }, false)
+ user, err := th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ // Count the number of posts in the testing team.
+ var initialPostCount int64
+ if result := <-th.App.Srv.Store.Post().AnalyticsPostCount(team.Id, false, false); result.Err != nil {
+ t.Fatal(result.Err)
+ } else {
+ initialPostCount = result.Data.(int64)
+ }
+
+ // Try adding an invalid post in dry run mode.
+ data := &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ }
+ if err := th.App.ImportPost(data, true); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
+
+ // Try adding a valid post in dry run mode.
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Hello"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportPost(data, true); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
+
+ // Try adding an invalid post in apply mode.
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportPost(data, false); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
+
+ // Try adding a valid post with invalid team in apply mode.
+ data = &PostImportData{
+ Team: ptrStr(model.NewId()),
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportPost(data, false); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
+
+ // Try adding a valid post with invalid channel in apply mode.
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: ptrStr(model.NewId()),
+ User: &username,
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportPost(data, false); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
+
+ // Try adding a valid post with invalid user in apply mode.
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: ptrStr(model.NewId()),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportPost(data, false); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
+
+ // Try adding a valid post in apply mode.
+ time := model.GetMillis()
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message"),
+ CreateAt: &time,
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id)
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, time); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ }
+
+ // Update the post.
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message"),
+ CreateAt: &time,
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id)
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, time); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ }
+
+ // Save the post with a different time.
+ newTime := time + 1
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message"),
+ CreateAt: &newTime,
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 2, team.Id)
+
+ // Save the post with a different message.
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message 2"),
+ CreateAt: &time,
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 3, team.Id)
+
+ // Test with hashtags
+ hashtagTime := time + 2
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message 2 #hashtagmashupcity"),
+ CreateAt: &hashtagTime,
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 4, team.Id)
+
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, hashtagTime); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ if post.Hashtags != "#hashtagmashupcity" {
+ t.Fatalf("Hashtags not as expected: %s", post.Hashtags)
+ }
+ }
+
+ // Post with flags.
+ username2 := model.NewId()
+ th.App.ImportUser(&UserImportData{
+ Username: &username2,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }, false)
+ user2, err := th.App.GetUserByUsername(username2)
+ if err != nil {
+ t.Fatalf("Failed to get user from database.")
+ }
+
+ flagsTime := hashtagTime + 1
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message with Favorites"),
+ CreateAt: &flagsTime,
+ FlaggedBy: &[]string{
+ username,
+ username2,
+ },
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 5, team.Id)
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, flagsTime); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id {
+ t.Fatal("Post properties not as expected")
+ }
+
+ checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
+ checkPreference(t, th.App, user2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
+ }
+
+ // Post with reaction.
+ reactionPostTime := hashtagTime + 2
+ reactionTime := hashtagTime + 3
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message with reaction"),
+ CreateAt: &reactionPostTime,
+ Reactions: &[]ReactionImportData{{
+ User: &user2.Username,
+ EmojiName: ptrStr("+1"),
+ CreateAt: &reactionTime,
+ }},
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 6, team.Id)
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, reactionPostTime); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id || !post.HasReactions {
+ t.Fatal("Post properties not as expected")
+ }
+
+ if result := <-th.App.Srv.Store.Reaction().GetForPost(post.Id, false); result.Err != nil {
+ t.Fatal("Can't get reaction")
+ } else if len(result.Data.([]*model.Reaction)) != 1 {
+ t.Fatal("Invalid number of reactions")
+ }
+ }
+
+ // Post with reply.
+ replyPostTime := hashtagTime + 4
+ replyTime := hashtagTime + 5
+ data = &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message with reply"),
+ CreateAt: &replyPostTime,
+ Replies: &[]ReplyImportData{{
+ User: &user2.Username,
+ Message: ptrStr("Message reply"),
+ CreateAt: &replyTime,
+ }},
+ }
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id)
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyPostTime); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id {
+ t.Fatal("Post properties not as expected")
+ }
+
+ // Check the reply values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyTime); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ replies := result.Data.([]*model.Post)
+ if len(replies) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ reply := replies[0]
+ if reply.Message != *(*data.Replies)[0].Message || reply.CreateAt != *(*data.Replies)[0].CreateAt || reply.UserId != user2.Id {
+ t.Fatal("Post properties not as expected")
+ }
+
+ if reply.RootId != post.Id {
+ t.Fatal("Unexpected reply RootId")
+ }
+ }
+ }
+}
+
+func TestImportImportDirectChannel(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ // Check how many channels are in the database.
+ var directChannelCount int64
+ if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_DIRECT); r.Err == nil {
+ directChannelCount = r.Data.(int64)
+ } else {
+ t.Fatalf("Failed to get direct channel count.")
+ }
+
+ var groupChannelCount int64
+ if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_GROUP); r.Err == nil {
+ groupChannelCount = r.Data.(int64)
+ } else {
+ t.Fatalf("Failed to get group channel count.")
+ }
+
+ // Do an invalid channel in dry-run mode.
+ data := DirectChannelImportData{
+ Members: &[]string{
+ model.NewId(),
+ },
+ Header: ptrStr("Channel Header"),
+ }
+ if err := th.App.ImportDirectChannel(&data, true); err == nil {
+ t.Fatalf("Expected error due to invalid name.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Do a valid DIRECT channel with a nonexistent member in dry-run mode.
+ data.Members = &[]string{
+ model.NewId(),
+ model.NewId(),
+ }
+ if err := th.App.ImportDirectChannel(&data, true); err != nil {
+ t.Fatalf("Expected success as cannot validate existence of channel members in dry run mode.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Do a valid GROUP channel with a nonexistent member in dry-run mode.
+ data.Members = &[]string{
+ model.NewId(),
+ model.NewId(),
+ model.NewId(),
+ }
+ if err := th.App.ImportDirectChannel(&data, true); err != nil {
+ t.Fatalf("Expected success as cannot validate existence of channel members in dry run mode.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Do an invalid channel in apply mode.
+ data.Members = &[]string{
+ model.NewId(),
+ }
+ if err := th.App.ImportDirectChannel(&data, false); err == nil {
+ t.Fatalf("Expected error due to invalid member (apply mode).")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Do a valid DIRECT channel.
+ data.Members = &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ }
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+
+ // Check that one more DIRECT channel is in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Do the same DIRECT channel again.
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Update the channel's HEADER
+ data.Header = ptrStr("New Channel Header 2")
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Get the channel to check that the header was updated.
+ if channel, err := th.App.createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err == nil || err.Id != store.CHANNEL_EXISTS_ERROR {
+ t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
+ } else {
+ if channel.Header != *data.Header {
+ t.Fatal("Channel header has not been updated successfully.")
+ }
+ }
+
+ // Do a GROUP channel with an extra invalid member.
+ user3 := th.CreateUser()
+ data.Members = &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ model.NewId(),
+ }
+ if err := th.App.ImportDirectChannel(&data, false); err == nil {
+ t.Fatalf("Should have failed due to invalid member in list.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
+
+ // Do a valid GROUP channel.
+ data.Members = &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ }
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ // Check that one more GROUP channel is in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1)
+
+ // Do the same DIRECT channel again.
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1)
+
+ // Update the channel's HEADER
+ data.Header = ptrStr("New Channel Header 3")
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ // Check that no more channels are in the DB.
+ AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
+ AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1)
+
+ // Get the channel to check that the header was updated.
+ userIds := []string{
+ th.BasicUser.Id,
+ th.BasicUser2.Id,
+ user3.Id,
+ }
+ if channel, err := th.App.createGroupChannel(userIds, th.BasicUser.Id); err.Id != store.CHANNEL_EXISTS_ERROR {
+ t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
+ } else {
+ if channel.Header != *data.Header {
+ t.Fatal("Channel header has not been updated successfully.")
+ }
+ }
+
+ // Import a channel with some favorites.
+ data.Members = &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ }
+ data.FavoritedBy = &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ }
+ if err := th.App.ImportDirectChannel(&data, false); err != nil {
+ t.Fatal(err)
+ }
+
+ if channel, err := th.App.createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err == nil || err.Id != store.CHANNEL_EXISTS_ERROR {
+ t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
+ } else {
+ checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true")
+ checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true")
+ }
+}
+
+func TestImportImportDirectPost(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ // Create the DIRECT channel.
+ channelData := DirectChannelImportData{
+ Members: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ }
+ if err := th.App.ImportDirectChannel(&channelData, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+
+ // Get the channel.
+ var directChannel *model.Channel
+ if channel, err := th.App.createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err.Id != store.CHANNEL_EXISTS_ERROR {
+ t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
+ } else {
+ directChannel = channel
+ }
+
+ // Get the number of posts in the system.
+ var initialPostCount int64
+ if result := <-th.App.Srv.Store.Post().AnalyticsPostCount("", false, false); result.Err != nil {
+ t.Fatal(result.Err)
+ } else {
+ initialPostCount = result.Data.(int64)
+ }
+
+ // Try adding an invalid post in dry run mode.
+ data := &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, true); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
+
+ // Try adding a valid post in dry run mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, true); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
+
+ // Try adding an invalid post in apply mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ model.NewId(),
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, false); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
+
+ // Try adding a valid post in apply mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ }
+
+ // Import the post again.
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ }
+
+ // Save the post with a different time.
+ data.CreateAt = ptrInt64(*data.CreateAt + 1)
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 2, "")
+
+ // Save the post with a different message.
+ data.Message = ptrStr("Message 2")
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 3, "")
+
+ // Test with hashtags
+ data.Message = ptrStr("Message 2 #hashtagmashupcity")
+ data.CreateAt = ptrInt64(*data.CreateAt + 1)
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 4, "")
+
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ if post.Hashtags != "#hashtagmashupcity" {
+ t.Fatalf("Hashtags not as expected: %s", post.Hashtags)
+ }
+ }
+
+ // Test with some flags.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ FlaggedBy: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
+ checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
+ }
+
+ // ------------------ Group Channel -------------------------
+
+ // Create the GROUP channel.
+ user3 := th.CreateUser()
+ channelData = DirectChannelImportData{
+ Members: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ },
+ }
+ if err := th.App.ImportDirectChannel(&channelData, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+
+ // Get the channel.
+ var groupChannel *model.Channel
+ userIds := []string{
+ th.BasicUser.Id,
+ th.BasicUser2.Id,
+ user3.Id,
+ }
+ if channel, err := th.App.createGroupChannel(userIds, th.BasicUser.Id); err.Id != store.CHANNEL_EXISTS_ERROR {
+ t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
+ } else {
+ groupChannel = channel
+ }
+
+ // Get the number of posts in the system.
+ if result := <-th.App.Srv.Store.Post().AnalyticsPostCount("", false, false); result.Err != nil {
+ t.Fatal(result.Err)
+ } else {
+ initialPostCount = result.Data.(int64)
+ }
+
+ // Try adding an invalid post in dry run mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, true); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
+
+ // Try adding a valid post in dry run mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, true); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
+
+ // Try adding an invalid post in apply mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ model.NewId(),
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, false); err == nil {
+ t.Fatalf("Expected error.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
+
+ // Try adding a valid post in apply mode.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ }
+
+ // Import the post again.
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ }
+
+ // Save the post with a different time.
+ data.CreateAt = ptrInt64(*data.CreateAt + 1)
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 2, "")
+
+ // Save the post with a different message.
+ data.Message = ptrStr("Message 2")
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 3, "")
+
+ // Test with hashtags
+ data.Message = ptrStr("Message 2 #hashtagmashupcity")
+ data.CreateAt = ptrInt64(*data.CreateAt + 1)
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+ AssertAllPostsCount(t, th.App, initialPostCount, 4, "")
+
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
+ t.Fatal("Post properties not as expected")
+ }
+ if post.Hashtags != "#hashtagmashupcity" {
+ t.Fatalf("Hashtags not as expected: %s", post.Hashtags)
+ }
+ }
+
+ // Test with some flags.
+ data = &DirectPostImportData{
+ ChannelMembers: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ user3.Username,
+ },
+ FlaggedBy: &[]string{
+ th.BasicUser.Username,
+ th.BasicUser2.Username,
+ },
+ User: ptrStr(th.BasicUser.Username),
+ Message: ptrStr("Message"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ }
+
+ if err := th.App.ImportDirectPost(data, false); err != nil {
+ t.Fatalf("Expected success: %v", err.Error())
+ }
+
+ // Check the post values.
+ if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
+ t.Fatal(result.Err.Error())
+ } else {
+ posts := result.Data.([]*model.Post)
+ if len(posts) != 1 {
+ t.Fatal("Unexpected number of posts found.")
+ }
+ post := posts[0]
+ checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
+ checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
+ }
+}
+
+func TestImportImportEmoji(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCustomEmoji = true })
+
+ testsDir, _ := utils.FindDir("tests")
+ testImage := filepath.Join(testsDir, "test.png")
+
+ data := EmojiImportData{Name: ptrStr(model.NewId())}
+ err := th.App.ImportEmoji(&data, true)
+ assert.NotNil(t, err, "Invalid emoji should have failed dry run")
+
+ result := <-th.App.Srv.Store.Emoji().GetByName(*data.Name)
+ assert.Nil(t, result.Data, "Emoji should not have been imported")
+
+ data.Image = ptrStr(testImage)
+ err = th.App.ImportEmoji(&data, true)
+ assert.Nil(t, err, "Valid emoji should have passed dry run")
+
+ data = EmojiImportData{Name: ptrStr(model.NewId())}
+ err = th.App.ImportEmoji(&data, false)
+ assert.NotNil(t, err, "Invalid emoji should have failed apply mode")
+
+ data.Image = ptrStr("non-existent-file")
+ err = th.App.ImportEmoji(&data, false)
+ assert.NotNil(t, err, "Emoji with bad image file should have failed apply mode")
+
+ data.Image = ptrStr(testImage)
+ err = th.App.ImportEmoji(&data, false)
+ assert.Nil(t, err, "Valid emoji should have succeeded apply mode")
+
+ result = <-th.App.Srv.Store.Emoji().GetByName(*data.Name)
+ assert.NotNil(t, result.Data, "Emoji should have been imported")
+
+ err = th.App.ImportEmoji(&data, false)
+ assert.Nil(t, err, "Second run should have succeeded apply mode")
+}
+
+func TestImportAttachment(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ testsDir, _ := utils.FindDir("tests")
+ testImage := filepath.Join(testsDir, "test.png")
+ invalidPath := "some-invalid-path"
+
+ userId := model.NewId()
+ data := AttachmentImportData{Path: &testImage}
+ _, err := th.App.ImportAttachment(&data, &model.Post{UserId: userId, ChannelId: "some-channel"}, "some-team", true)
+ assert.Nil(t, err, "sample run without errors")
+
+ attachments := GetAttachments(userId, th, t)
+ assert.Equal(t, len(attachments), 1)
+
+ data = AttachmentImportData{Path: &invalidPath}
+ _, err = th.App.ImportAttachment(&data, &model.Post{UserId: model.NewId(), ChannelId: "some-channel"}, "some-team", true)
+ assert.NotNil(t, err, "should have failed when opening the file")
+ assert.Equal(t, err.Id, "app.import.attachment.bad_file.error")
+}
+
+func TestImportPostAndRepliesWithAttachments(t *testing.T) {
+
+ th := Setup()
+ defer th.TearDown()
+
+ // Create a Team.
+ teamName := model.NewId()
+ th.App.ImportTeam(&TeamImportData{
+ Name: &teamName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ team, err := th.App.GetTeamByName(teamName)
+ if err != nil {
+ t.Fatalf("Failed to get team from database.")
+ }
+
+ // Create a Channel.
+ channelName := model.NewId()
+ th.App.ImportChannel(&ChannelImportData{
+ Team: &teamName,
+ Name: &channelName,
+ DisplayName: ptrStr("Display Name"),
+ Type: ptrStr("O"),
+ }, false)
+ _, err = th.App.GetChannelByName(channelName, team.Id, false)
+ if err != nil {
+ t.Fatalf("Failed to get channel from database.")
+ }
+
+ // Create a user3.
+ username := model.NewId()
+ th.App.ImportUser(&UserImportData{
+ Username: &username,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }, false)
+ user3, err := th.App.GetUserByUsername(username)
+ if err != nil {
+ t.Fatalf("Failed to get user3 from database.")
+ }
+
+ username2 := model.NewId()
+ th.App.ImportUser(&UserImportData{
+ Username: &username2,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }, false)
+ user4, err := th.App.GetUserByUsername(username2)
+ if err != nil {
+ t.Fatalf("Failed to get user3 from database.")
+ }
+
+ // Post with attachments.
+ time := model.GetMillis()
+ attachmentsPostTime := time
+ attachmentsReplyTime := time + 1
+ testsDir, _ := utils.FindDir("tests")
+ testImage := filepath.Join(testsDir, "test.png")
+ testMarkDown := filepath.Join(testsDir, "test-attachments.md")
+ data := &PostImportData{
+ Team: &teamName,
+ Channel: &channelName,
+ User: &username,
+ Message: ptrStr("Message with reply"),
+ CreateAt: &attachmentsPostTime,
+ Attachments: &[]AttachmentImportData{{Path: &testImage}, {Path: &testMarkDown}},
+ Replies: &[]ReplyImportData{{
+ User: &user4.Username,
+ Message: ptrStr("Message reply"),
+ CreateAt: &attachmentsReplyTime,
+ Attachments: &[]AttachmentImportData{{Path: &testImage}},
+ }},
+ }
+
+ if err := th.App.ImportPost(data, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ attachments := GetAttachments(user3.Id, th, t)
+ assert.Equal(t, len(attachments), 2)
+ assert.Contains(t, attachments[0].Path, team.Id)
+ assert.Contains(t, attachments[1].Path, team.Id)
+ AssertFileIdsInPost(attachments, th, t)
+
+ attachments = GetAttachments(user4.Id, th, t)
+ assert.Equal(t, len(attachments), 1)
+ assert.Contains(t, attachments[0].Path, team.Id)
+ AssertFileIdsInPost(attachments, th, t)
+
+ // Reply with Attachments in Direct Post
+
+ // Create direct post users.
+
+ username3 := model.NewId()
+ th.App.ImportUser(&UserImportData{
+ Username: &username3,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }, false)
+ user3, err = th.App.GetUserByUsername(username3)
+ if err != nil {
+ t.Fatalf("Failed to get user3 from database.")
+ }
+
+ username4 := model.NewId()
+ th.App.ImportUser(&UserImportData{
+ Username: &username4,
+ Email: ptrStr(model.NewId() + "@example.com"),
+ }, false)
+
+ user4, err = th.App.GetUserByUsername(username4)
+ if err != nil {
+ t.Fatalf("Failed to get user3 from database.")
+ }
+
+ directImportData := &DirectPostImportData{
+ ChannelMembers: &[]string{
+ user3.Username,
+ user4.Username,
+ },
+ User: &user3.Username,
+ Message: ptrStr("Message with Replies"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ Replies: &[]ReplyImportData{{
+ User: &user4.Username,
+ Message: ptrStr("Message reply with attachment"),
+ CreateAt: ptrInt64(model.GetMillis()),
+ Attachments: &[]AttachmentImportData{{Path: &testImage}},
+ }},
+ }
+
+ if err := th.App.ImportDirectPost(directImportData, false); err != nil {
+ t.Fatalf("Expected success.")
+ }
+
+ attachments = GetAttachments(user4.Id, th, t)
+ assert.Equal(t, len(attachments), 1)
+ assert.Contains(t, attachments[0].Path, "noteam")
+ AssertFileIdsInPost(attachments, th, t)
+
+}