github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/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  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/mattermost/mattermost-server/v5/model"
    17  	"github.com/mattermost/mattermost-server/v5/store"
    18  	"github.com/mattermost/mattermost-server/v5/utils/fileutils"
    19  )
    20  
    21  func TestImportImportScheme(t *testing.T) {
    22  	th := Setup(t)
    23  	defer th.TearDown()
    24  
    25  	// Mark the phase 2 permissions migration as completed.
    26  	th.App.Srv().Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
    27  
    28  	defer func() {
    29  		th.App.Srv().Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
    30  	}()
    31  
    32  	// Try importing an invalid scheme in dryRun mode.
    33  	data := SchemeImportData{
    34  		Name:  ptrStr(model.NewId()),
    35  		Scope: ptrStr("team"),
    36  		DefaultTeamGuestRole: &RoleImportData{
    37  			Name:        ptrStr(model.NewId()),
    38  			DisplayName: ptrStr(model.NewId()),
    39  		},
    40  		DefaultTeamUserRole: &RoleImportData{
    41  			Name:        ptrStr(model.NewId()),
    42  			DisplayName: ptrStr(model.NewId()),
    43  		},
    44  		DefaultTeamAdminRole: &RoleImportData{
    45  			Name:        ptrStr(model.NewId()),
    46  			DisplayName: ptrStr(model.NewId()),
    47  		},
    48  		DefaultChannelGuestRole: &RoleImportData{
    49  			Name:        ptrStr(model.NewId()),
    50  			DisplayName: ptrStr(model.NewId()),
    51  		},
    52  		DefaultChannelUserRole: &RoleImportData{
    53  			Name:        ptrStr(model.NewId()),
    54  			DisplayName: ptrStr(model.NewId()),
    55  		},
    56  		DefaultChannelAdminRole: &RoleImportData{
    57  			Name:        ptrStr(model.NewId()),
    58  			DisplayName: ptrStr(model.NewId()),
    59  		},
    60  		Description: ptrStr("description"),
    61  	}
    62  
    63  	err := th.App.importScheme(&data, true)
    64  	require.NotNil(t, err, "Should have failed to import.")
    65  
    66  	_, nErr := th.App.Srv().Store.Scheme().GetByName(*data.Name)
    67  	require.NotNil(t, nErr, "Scheme should not have imported.")
    68  
    69  	// Try importing a valid scheme in dryRun mode.
    70  	data.DisplayName = ptrStr("display name")
    71  
    72  	err = th.App.importScheme(&data, true)
    73  	require.Nil(t, err, "Should have succeeded.")
    74  
    75  	_, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
    76  	require.NotNil(t, nErr, "Scheme should not have imported.")
    77  
    78  	// Try importing an invalid scheme.
    79  	data.DisplayName = nil
    80  
    81  	err = th.App.importScheme(&data, false)
    82  	require.NotNil(t, err, "Should have failed to import.")
    83  
    84  	_, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
    85  	require.NotNil(t, nErr, "Scheme should not have imported.")
    86  
    87  	// Try importing a valid scheme with all params set.
    88  	data.DisplayName = ptrStr("display name")
    89  
    90  	err = th.App.importScheme(&data, false)
    91  	require.Nil(t, err, "Should have succeeded.")
    92  
    93  	scheme, nErr := th.App.Srv().Store.Scheme().GetByName(*data.Name)
    94  	require.Nil(t, nErr, "Failed to import scheme: %v", err)
    95  
    96  	assert.Equal(t, *data.Name, scheme.Name)
    97  	assert.Equal(t, *data.DisplayName, scheme.DisplayName)
    98  	assert.Equal(t, *data.Description, scheme.Description)
    99  	assert.Equal(t, *data.Scope, scheme.Scope)
   100  
   101  	role, nErr := th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamAdminRole)
   102  	require.Nil(t, nErr, "Should have found the imported role.")
   103  
   104  	assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
   105  	assert.False(t, role.BuiltIn)
   106  	assert.True(t, role.SchemeManaged)
   107  
   108  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamUserRole)
   109  	require.Nil(t, nErr, "Should have found the imported role.")
   110  
   111  	assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
   112  	assert.False(t, role.BuiltIn)
   113  	assert.True(t, role.SchemeManaged)
   114  
   115  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamGuestRole)
   116  	require.Nil(t, nErr, "Should have found the imported role.")
   117  
   118  	assert.Equal(t, *data.DefaultTeamGuestRole.DisplayName, role.DisplayName)
   119  	assert.False(t, role.BuiltIn)
   120  	assert.True(t, role.SchemeManaged)
   121  
   122  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelAdminRole)
   123  	require.Nil(t, nErr, "Should have found the imported role.")
   124  
   125  	assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
   126  	assert.False(t, role.BuiltIn)
   127  	assert.True(t, role.SchemeManaged)
   128  
   129  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelUserRole)
   130  	require.Nil(t, nErr, "Should have found the imported role.")
   131  
   132  	assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
   133  	assert.False(t, role.BuiltIn)
   134  	assert.True(t, role.SchemeManaged)
   135  
   136  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelGuestRole)
   137  	require.Nil(t, nErr, "Should have found the imported role.")
   138  
   139  	assert.Equal(t, *data.DefaultChannelGuestRole.DisplayName, role.DisplayName)
   140  	assert.False(t, role.BuiltIn)
   141  	assert.True(t, role.SchemeManaged)
   142  
   143  	// Try modifying all the fields and re-importing.
   144  	data.DisplayName = ptrStr("new display name")
   145  	data.Description = ptrStr("new description")
   146  
   147  	err = th.App.importScheme(&data, false)
   148  	require.Nil(t, err, "Should have succeeded: %v", err)
   149  
   150  	scheme, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
   151  	require.Nil(t, nErr, "Failed to import scheme: %v", err)
   152  
   153  	assert.Equal(t, *data.Name, scheme.Name)
   154  	assert.Equal(t, *data.DisplayName, scheme.DisplayName)
   155  	assert.Equal(t, *data.Description, scheme.Description)
   156  	assert.Equal(t, *data.Scope, scheme.Scope)
   157  
   158  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamAdminRole)
   159  	require.Nil(t, nErr, "Should have found the imported role.")
   160  
   161  	assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
   162  	assert.False(t, role.BuiltIn)
   163  	assert.True(t, role.SchemeManaged)
   164  
   165  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamUserRole)
   166  	require.Nil(t, nErr, "Should have found the imported role.")
   167  
   168  	assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
   169  	assert.False(t, role.BuiltIn)
   170  	assert.True(t, role.SchemeManaged)
   171  
   172  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamGuestRole)
   173  	require.Nil(t, nErr, "Should have found the imported role.")
   174  
   175  	assert.Equal(t, *data.DefaultTeamGuestRole.DisplayName, role.DisplayName)
   176  	assert.False(t, role.BuiltIn)
   177  	assert.True(t, role.SchemeManaged)
   178  
   179  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelAdminRole)
   180  	require.Nil(t, nErr, "Should have found the imported role.")
   181  
   182  	assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
   183  	assert.False(t, role.BuiltIn)
   184  	assert.True(t, role.SchemeManaged)
   185  
   186  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelUserRole)
   187  	require.Nil(t, nErr, "Should have found the imported role.")
   188  
   189  	assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
   190  	assert.False(t, role.BuiltIn)
   191  	assert.True(t, role.SchemeManaged)
   192  
   193  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelGuestRole)
   194  	require.Nil(t, nErr, "Should have found the imported role.")
   195  
   196  	assert.Equal(t, *data.DefaultChannelGuestRole.DisplayName, role.DisplayName)
   197  	assert.False(t, role.BuiltIn)
   198  	assert.True(t, role.SchemeManaged)
   199  
   200  	// Try changing the scope of the scheme and reimporting.
   201  	data.Scope = ptrStr("channel")
   202  
   203  	err = th.App.importScheme(&data, false)
   204  	require.NotNil(t, err, "Should have failed to import.")
   205  
   206  	scheme, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
   207  	require.Nil(t, nErr, "Failed to import scheme: %v", err)
   208  
   209  	assert.Equal(t, *data.Name, scheme.Name)
   210  	assert.Equal(t, *data.DisplayName, scheme.DisplayName)
   211  	assert.Equal(t, *data.Description, scheme.Description)
   212  	assert.Equal(t, "team", scheme.Scope)
   213  
   214  }
   215  
   216  func TestImportImportSchemeWithoutGuestRoles(t *testing.T) {
   217  	th := Setup(t)
   218  	defer th.TearDown()
   219  
   220  	// Mark the phase 2 permissions migration as completed.
   221  	th.App.Srv().Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
   222  
   223  	defer func() {
   224  		th.App.Srv().Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
   225  	}()
   226  
   227  	// Try importing an invalid scheme in dryRun mode.
   228  	data := SchemeImportData{
   229  		Name:  ptrStr(model.NewId()),
   230  		Scope: ptrStr("team"),
   231  		DefaultTeamUserRole: &RoleImportData{
   232  			Name:        ptrStr(model.NewId()),
   233  			DisplayName: ptrStr(model.NewId()),
   234  		},
   235  		DefaultTeamAdminRole: &RoleImportData{
   236  			Name:        ptrStr(model.NewId()),
   237  			DisplayName: ptrStr(model.NewId()),
   238  		},
   239  		DefaultChannelUserRole: &RoleImportData{
   240  			Name:        ptrStr(model.NewId()),
   241  			DisplayName: ptrStr(model.NewId()),
   242  		},
   243  		DefaultChannelAdminRole: &RoleImportData{
   244  			Name:        ptrStr(model.NewId()),
   245  			DisplayName: ptrStr(model.NewId()),
   246  		},
   247  		Description: ptrStr("description"),
   248  	}
   249  
   250  	err := th.App.importScheme(&data, true)
   251  	require.NotNil(t, err, "Should have failed to import.")
   252  
   253  	_, nErr := th.App.Srv().Store.Scheme().GetByName(*data.Name)
   254  	require.NotNil(t, nErr, "Scheme should not have imported.")
   255  
   256  	// Try importing a valid scheme in dryRun mode.
   257  	data.DisplayName = ptrStr("display name")
   258  
   259  	err = th.App.importScheme(&data, true)
   260  	require.Nil(t, err, "Should have succeeded.")
   261  
   262  	_, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
   263  	require.NotNil(t, nErr, "Scheme should not have imported.")
   264  
   265  	// Try importing an invalid scheme.
   266  	data.DisplayName = nil
   267  
   268  	err = th.App.importScheme(&data, false)
   269  	require.NotNil(t, err, "Should have failed to import.")
   270  
   271  	_, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
   272  	require.NotNil(t, nErr, "Scheme should not have imported.")
   273  
   274  	// Try importing a valid scheme with all params set.
   275  	data.DisplayName = ptrStr("display name")
   276  
   277  	err = th.App.importScheme(&data, false)
   278  	require.Nil(t, err, "Should have succeeded.")
   279  
   280  	scheme, nErr := th.App.Srv().Store.Scheme().GetByName(*data.Name)
   281  	require.Nil(t, nErr, "Failed to import scheme: %v", err)
   282  
   283  	assert.Equal(t, *data.Name, scheme.Name)
   284  	assert.Equal(t, *data.DisplayName, scheme.DisplayName)
   285  	assert.Equal(t, *data.Description, scheme.Description)
   286  	assert.Equal(t, *data.Scope, scheme.Scope)
   287  
   288  	role, nErr := th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamAdminRole)
   289  	require.Nil(t, nErr, "Should have found the imported role.")
   290  
   291  	assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
   292  	assert.False(t, role.BuiltIn)
   293  	assert.True(t, role.SchemeManaged)
   294  
   295  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamUserRole)
   296  	require.Nil(t, nErr, "Should have found the imported role.")
   297  
   298  	assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
   299  	assert.False(t, role.BuiltIn)
   300  	assert.True(t, role.SchemeManaged)
   301  
   302  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamGuestRole)
   303  	require.Nil(t, nErr, "Should have found the imported role.")
   304  
   305  	assert.Equal(t, *data.DefaultTeamGuestRole.DisplayName, role.DisplayName)
   306  	assert.False(t, role.BuiltIn)
   307  	assert.True(t, role.SchemeManaged)
   308  
   309  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelAdminRole)
   310  	require.Nil(t, nErr, "Should have found the imported role.")
   311  
   312  	assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
   313  	assert.False(t, role.BuiltIn)
   314  	assert.True(t, role.SchemeManaged)
   315  
   316  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelUserRole)
   317  	require.Nil(t, nErr, "Should have found the imported role.")
   318  
   319  	assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
   320  	assert.False(t, role.BuiltIn)
   321  	assert.True(t, role.SchemeManaged)
   322  
   323  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelGuestRole)
   324  	require.Nil(t, nErr, "Should have found the imported role.")
   325  
   326  	assert.Equal(t, *data.DefaultChannelGuestRole.DisplayName, role.DisplayName)
   327  	assert.False(t, role.BuiltIn)
   328  	assert.True(t, role.SchemeManaged)
   329  
   330  	// Try modifying all the fields and re-importing.
   331  	data.DisplayName = ptrStr("new display name")
   332  	data.Description = ptrStr("new description")
   333  
   334  	err = th.App.importScheme(&data, false)
   335  	require.Nil(t, err, "Should have succeeded: %v", err)
   336  
   337  	scheme, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
   338  	require.Nil(t, nErr, "Failed to import scheme: %v", err)
   339  
   340  	assert.Equal(t, *data.Name, scheme.Name)
   341  	assert.Equal(t, *data.DisplayName, scheme.DisplayName)
   342  	assert.Equal(t, *data.Description, scheme.Description)
   343  	assert.Equal(t, *data.Scope, scheme.Scope)
   344  
   345  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamAdminRole)
   346  	require.Nil(t, nErr, "Should have found the imported role.")
   347  
   348  	assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
   349  	assert.False(t, role.BuiltIn)
   350  	assert.True(t, role.SchemeManaged)
   351  
   352  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamUserRole)
   353  	require.Nil(t, nErr, "Should have found the imported role.")
   354  
   355  	assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
   356  	assert.False(t, role.BuiltIn)
   357  	assert.True(t, role.SchemeManaged)
   358  
   359  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultTeamGuestRole)
   360  	require.Nil(t, nErr, "Should have found the imported role.")
   361  
   362  	assert.Equal(t, *data.DefaultTeamGuestRole.DisplayName, role.DisplayName)
   363  	assert.False(t, role.BuiltIn)
   364  	assert.True(t, role.SchemeManaged)
   365  
   366  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelAdminRole)
   367  	require.Nil(t, nErr, "Should have found the imported role.")
   368  
   369  	assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
   370  	assert.False(t, role.BuiltIn)
   371  	assert.True(t, role.SchemeManaged)
   372  
   373  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelUserRole)
   374  	require.Nil(t, nErr, "Should have found the imported role.")
   375  
   376  	assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
   377  	assert.False(t, role.BuiltIn)
   378  	assert.True(t, role.SchemeManaged)
   379  
   380  	role, nErr = th.App.Srv().Store.Role().GetByName(scheme.DefaultChannelGuestRole)
   381  	require.Nil(t, nErr, "Should have found the imported role.")
   382  
   383  	assert.Equal(t, *data.DefaultChannelGuestRole.DisplayName, role.DisplayName)
   384  	assert.False(t, role.BuiltIn)
   385  	assert.True(t, role.SchemeManaged)
   386  
   387  	// Try changing the scope of the scheme and reimporting.
   388  	data.Scope = ptrStr("channel")
   389  
   390  	err = th.App.importScheme(&data, false)
   391  	require.NotNil(t, err, "Should have failed to import.")
   392  
   393  	scheme, nErr = th.App.Srv().Store.Scheme().GetByName(*data.Name)
   394  	require.Nil(t, nErr, "Failed to import scheme: %v", err)
   395  
   396  	assert.Equal(t, *data.Name, scheme.Name)
   397  	assert.Equal(t, *data.DisplayName, scheme.DisplayName)
   398  	assert.Equal(t, *data.Description, scheme.Description)
   399  	assert.Equal(t, "team", scheme.Scope)
   400  }
   401  
   402  func TestImportImportRole(t *testing.T) {
   403  	th := Setup(t)
   404  	defer th.TearDown()
   405  
   406  	// Try importing an invalid role in dryRun mode.
   407  	rid1 := model.NewId()
   408  	data := RoleImportData{
   409  		Name: &rid1,
   410  	}
   411  
   412  	err := th.App.importRole(&data, true, false)
   413  	require.NotNil(t, err, "Should have failed to import.")
   414  
   415  	_, nErr := th.App.Srv().Store.Role().GetByName(rid1)
   416  	require.NotNil(t, nErr, "Should have failed to import.")
   417  
   418  	// Try importing the valid role in dryRun mode.
   419  	data.DisplayName = ptrStr("display name")
   420  
   421  	err = th.App.importRole(&data, true, false)
   422  	require.Nil(t, err, "Should have succeeded.")
   423  
   424  	_, nErr = th.App.Srv().Store.Role().GetByName(rid1)
   425  	require.NotNil(t, nErr, "Role should not have imported as we are in dry run mode.")
   426  
   427  	// Try importing an invalid role.
   428  	data.DisplayName = nil
   429  
   430  	err = th.App.importRole(&data, false, false)
   431  	require.NotNil(t, err, "Should have failed to import.")
   432  
   433  	_, nErr = th.App.Srv().Store.Role().GetByName(rid1)
   434  	require.NotNil(t, nErr, "Role should not have imported.")
   435  
   436  	// Try importing a valid role with all params set.
   437  	data.DisplayName = ptrStr("display name")
   438  	data.Description = ptrStr("description")
   439  	data.Permissions = &[]string{"invite_user", "add_user_to_team"}
   440  
   441  	err = th.App.importRole(&data, false, false)
   442  	require.Nil(t, err, "Should have succeeded.")
   443  
   444  	role, nErr := th.App.Srv().Store.Role().GetByName(rid1)
   445  	require.Nil(t, nErr, "Should have found the imported role.")
   446  
   447  	assert.Equal(t, *data.Name, role.Name)
   448  	assert.Equal(t, *data.DisplayName, role.DisplayName)
   449  	assert.Equal(t, *data.Description, role.Description)
   450  	assert.Equal(t, *data.Permissions, role.Permissions)
   451  	assert.False(t, role.BuiltIn)
   452  	assert.False(t, role.SchemeManaged)
   453  
   454  	// Try changing all the params and reimporting.
   455  	data.DisplayName = ptrStr("new display name")
   456  	data.Description = ptrStr("description")
   457  	data.Permissions = &[]string{"use_slash_commands"}
   458  
   459  	err = th.App.importRole(&data, false, true)
   460  	require.Nil(t, err, "Should have succeeded. %v", err)
   461  
   462  	role, nErr = th.App.Srv().Store.Role().GetByName(rid1)
   463  	require.Nil(t, nErr, "Should have found the imported role.")
   464  
   465  	assert.Equal(t, *data.Name, role.Name)
   466  	assert.Equal(t, *data.DisplayName, role.DisplayName)
   467  	assert.Equal(t, *data.Description, role.Description)
   468  	assert.Equal(t, *data.Permissions, role.Permissions)
   469  	assert.False(t, role.BuiltIn)
   470  	assert.True(t, role.SchemeManaged)
   471  
   472  	// Check that re-importing with only required fields doesn't update the others.
   473  	data2 := RoleImportData{
   474  		Name:        &rid1,
   475  		DisplayName: ptrStr("new display name again"),
   476  	}
   477  
   478  	err = th.App.importRole(&data2, false, false)
   479  	require.Nil(t, err, "Should have succeeded.")
   480  
   481  	role, nErr = th.App.Srv().Store.Role().GetByName(rid1)
   482  	require.Nil(t, nErr, "Should have found the imported role.")
   483  
   484  	assert.Equal(t, *data2.Name, role.Name)
   485  	assert.Equal(t, *data2.DisplayName, role.DisplayName)
   486  	assert.Equal(t, *data.Description, role.Description)
   487  	assert.Equal(t, *data.Permissions, role.Permissions)
   488  	assert.False(t, role.BuiltIn)
   489  	assert.False(t, role.SchemeManaged)
   490  }
   491  
   492  func TestImportImportTeam(t *testing.T) {
   493  	th := Setup(t)
   494  	defer th.TearDown()
   495  
   496  	// Mark the phase 2 permissions migration as completed.
   497  	th.App.Srv().Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
   498  
   499  	defer func() {
   500  		th.App.Srv().Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
   501  	}()
   502  
   503  	scheme1 := th.SetupTeamScheme()
   504  	scheme2 := th.SetupTeamScheme()
   505  
   506  	// Check how many teams are in the database.
   507  	teamsCount, err := th.App.Srv().Store.Team().AnalyticsTeamCount(false)
   508  	require.Nil(t, err, "Failed to get team count.")
   509  
   510  	data := TeamImportData{
   511  		Name:            ptrStr(model.NewId()),
   512  		DisplayName:     ptrStr("Display Name"),
   513  		Type:            ptrStr("XYZ"),
   514  		Description:     ptrStr("The team description."),
   515  		AllowOpenInvite: ptrBool(true),
   516  		Scheme:          &scheme1.Name,
   517  	}
   518  
   519  	// Try importing an invalid team in dryRun mode.
   520  	err = th.App.importTeam(&data, true)
   521  	require.NotNil(t, err, "Should have received an error importing an invalid team.")
   522  
   523  	// Do a valid team in dry-run mode.
   524  	data.Type = ptrStr("O")
   525  	err = th.App.importTeam(&data, true)
   526  	require.Nil(t, err, "Received an error validating valid team.")
   527  
   528  	// Check that no more teams are in the DB.
   529  	th.CheckTeamCount(t, teamsCount)
   530  
   531  	// Do an invalid team in apply mode, check db changes.
   532  	data.Type = ptrStr("XYZ")
   533  	err = th.App.importTeam(&data, false)
   534  	require.NotNil(t, err, "Import should have failed on invalid team.")
   535  
   536  	// Check that no more teams are in the DB.
   537  	th.CheckTeamCount(t, teamsCount)
   538  
   539  	// Do a valid team in apply mode, check db changes.
   540  	data.Type = ptrStr("O")
   541  	err = th.App.importTeam(&data, false)
   542  	require.Nil(t, err, "Received an error importing valid team: %v", err)
   543  
   544  	// Check that one more team is in the DB.
   545  	th.CheckTeamCount(t, teamsCount+1)
   546  
   547  	// Get the team and check that all the fields are correct.
   548  	team, err := th.App.GetTeamByName(*data.Name)
   549  	require.Nil(t, err, "Failed to get team from database.")
   550  
   551  	assert.Equal(t, *data.DisplayName, team.DisplayName)
   552  	assert.Equal(t, *data.Type, team.Type)
   553  	assert.Equal(t, *data.Description, team.Description)
   554  	assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite)
   555  	assert.Equal(t, scheme1.Id, *team.SchemeId)
   556  
   557  	// Alter all the fields of that team (apart from unique identifier) and import again.
   558  	data.DisplayName = ptrStr("Display Name 2")
   559  	data.Type = ptrStr("P")
   560  	data.Description = ptrStr("The new description")
   561  	data.AllowOpenInvite = ptrBool(false)
   562  	data.Scheme = &scheme2.Name
   563  
   564  	// Check that the original number of teams are again in the DB (because this query doesn't include deleted).
   565  	data.Type = ptrStr("O")
   566  	err = th.App.importTeam(&data, false)
   567  	require.Nil(t, err, "Received an error importing updated valid team.")
   568  
   569  	th.CheckTeamCount(t, teamsCount+1)
   570  
   571  	// Get the team and check that all fields are correct.
   572  	team, err = th.App.GetTeamByName(*data.Name)
   573  	require.Nil(t, err, "Failed to get team from database.")
   574  
   575  	assert.Equal(t, *data.DisplayName, team.DisplayName)
   576  	assert.Equal(t, *data.Type, team.Type)
   577  	assert.Equal(t, *data.Description, team.Description)
   578  	assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite)
   579  	assert.Equal(t, scheme2.Id, *team.SchemeId)
   580  }
   581  
   582  func TestImportImportChannel(t *testing.T) {
   583  	th := Setup(t)
   584  	defer th.TearDown()
   585  
   586  	// Mark the phase 2 permissions migration as completed.
   587  	th.App.Srv().Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
   588  
   589  	defer func() {
   590  		th.App.Srv().Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
   591  	}()
   592  
   593  	scheme1 := th.SetupChannelScheme()
   594  	scheme2 := th.SetupChannelScheme()
   595  
   596  	// Import a Team.
   597  	teamName := model.NewRandomTeamName()
   598  	th.App.importTeam(&TeamImportData{
   599  		Name:        &teamName,
   600  		DisplayName: ptrStr("Display Name"),
   601  		Type:        ptrStr("O"),
   602  	}, false)
   603  	team, err := th.App.GetTeamByName(teamName)
   604  	require.Nil(t, err, "Failed to get team from database.")
   605  
   606  	// Check how many channels are in the database.
   607  	channelCount, err := th.App.Srv().Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN)
   608  	require.Nil(t, err, "Failed to get team count.")
   609  
   610  	// Do an invalid channel in dry-run mode.
   611  	data := ChannelImportData{
   612  		Team:        &teamName,
   613  		DisplayName: ptrStr("Display Name"),
   614  		Type:        ptrStr("O"),
   615  		Header:      ptrStr("Channe Header"),
   616  		Purpose:     ptrStr("Channel Purpose"),
   617  		Scheme:      &scheme1.Name,
   618  	}
   619  	err = th.App.importChannel(&data, true)
   620  	require.NotNil(t, err, "Expected error due to invalid name.")
   621  
   622  	// Check that no more channels are in the DB.
   623  	th.CheckChannelsCount(t, channelCount)
   624  
   625  	// Do a valid channel with a nonexistent team in dry-run mode.
   626  	data.Name = ptrStr("channelname")
   627  	data.Team = ptrStr(model.NewId())
   628  	err = th.App.importChannel(&data, true)
   629  	require.Nil(t, err, "Expected success as cannot validate channel name in dry run mode.")
   630  
   631  	// Check that no more channels are in the DB.
   632  	th.CheckChannelsCount(t, channelCount)
   633  
   634  	// Do a valid channel in dry-run mode.
   635  	data.Team = &teamName
   636  	err = th.App.importChannel(&data, true)
   637  	require.Nil(t, err, "Expected success as valid team.")
   638  
   639  	// Check that no more channels are in the DB.
   640  	th.CheckChannelsCount(t, channelCount)
   641  
   642  	// Do an invalid channel in apply mode.
   643  	data.Name = nil
   644  	err = th.App.importChannel(&data, false)
   645  	require.NotNil(t, err, "Expected error due to invalid name (apply mode).")
   646  
   647  	// Check that no more channels are in the DB.
   648  	th.CheckChannelsCount(t, channelCount)
   649  
   650  	// Do a valid channel in apply mode with a non-existent team.
   651  	data.Name = ptrStr("channelname")
   652  	data.Team = ptrStr(model.NewId())
   653  	err = th.App.importChannel(&data, false)
   654  	require.NotNil(t, err, "Expected error due to non-existent team (apply mode).")
   655  
   656  	// Check that no more channels are in the DB.
   657  	th.CheckChannelsCount(t, channelCount)
   658  
   659  	// Do a valid channel in apply mode.
   660  	data.Team = &teamName
   661  	err = th.App.importChannel(&data, false)
   662  	require.Nil(t, err, "Expected success in apply mode")
   663  
   664  	// Check that 1 more channel is in the DB.
   665  	th.CheckChannelsCount(t, channelCount+1)
   666  
   667  	// Get the Channel and check all the fields are correct.
   668  	channel, err := th.App.GetChannelByName(*data.Name, team.Id, false)
   669  	require.Nil(t, err, "Failed to get channel from database.")
   670  
   671  	assert.Equal(t, *data.Name, channel.Name)
   672  	assert.Equal(t, *data.DisplayName, channel.DisplayName)
   673  	assert.Equal(t, *data.Type, channel.Type)
   674  	assert.Equal(t, *data.Header, channel.Header)
   675  	assert.Equal(t, *data.Purpose, channel.Purpose)
   676  	assert.Equal(t, scheme1.Id, *channel.SchemeId)
   677  
   678  	// Alter all the fields of that channel.
   679  	data.DisplayName = ptrStr("Chaned Disp Name")
   680  	data.Type = ptrStr(model.CHANNEL_PRIVATE)
   681  	data.Header = ptrStr("New Header")
   682  	data.Purpose = ptrStr("New Purpose")
   683  	data.Scheme = &scheme2.Name
   684  	err = th.App.importChannel(&data, false)
   685  	require.Nil(t, err, "Expected success in apply mode")
   686  
   687  	// Check channel count the same.
   688  	th.CheckChannelsCount(t, channelCount)
   689  
   690  	// Get the Channel and check all the fields are correct.
   691  	channel, err = th.App.GetChannelByName(*data.Name, team.Id, false)
   692  	require.Nil(t, err, "Failed to get channel from database.")
   693  
   694  	assert.Equal(t, *data.Name, channel.Name)
   695  	assert.Equal(t, *data.DisplayName, channel.DisplayName)
   696  	assert.Equal(t, *data.Type, channel.Type)
   697  	assert.Equal(t, *data.Header, channel.Header)
   698  	assert.Equal(t, *data.Purpose, channel.Purpose)
   699  	assert.Equal(t, scheme2.Id, *channel.SchemeId)
   700  }
   701  
   702  func TestImportImportUser(t *testing.T) {
   703  	th := Setup(t)
   704  	defer th.TearDown()
   705  
   706  	// Check how many users are in the database.
   707  	userCount, err := th.App.Srv().Store.User().Count(model.UserCountOptions{
   708  		IncludeDeleted:     true,
   709  		IncludeBotAccounts: false,
   710  	})
   711  	require.Nil(t, err, "Failed to get user count.")
   712  
   713  	// Do an invalid user in dry-run mode.
   714  	data := UserImportData{
   715  		Username: ptrStr(model.NewId()),
   716  	}
   717  	err = th.App.importUser(&data, true)
   718  	require.NotNil(t, err, "Should have failed to import invalid user.")
   719  
   720  	// Check that no more users are in the DB.
   721  	userCount2, err := th.App.Srv().Store.User().Count(model.UserCountOptions{
   722  		IncludeDeleted:     true,
   723  		IncludeBotAccounts: false,
   724  	})
   725  	require.Nil(t, err, "Failed to get user count.")
   726  	assert.Equal(t, userCount, userCount2, "Unexpected number of users")
   727  
   728  	// Do a valid user in dry-run mode.
   729  	data = UserImportData{
   730  		Username: ptrStr(model.NewId()),
   731  		Email:    ptrStr(model.NewId() + "@example.com"),
   732  	}
   733  	err = th.App.importUser(&data, true)
   734  	require.Nil(t, err, "Should have succeeded to import valid user.")
   735  
   736  	// Check that no more users are in the DB.
   737  	userCount3, err := th.App.Srv().Store.User().Count(model.UserCountOptions{
   738  		IncludeDeleted:     true,
   739  		IncludeBotAccounts: false,
   740  	})
   741  	require.Nil(t, err, "Failed to get user count.")
   742  	assert.Equal(t, userCount, userCount3, "Unexpected number of users")
   743  
   744  	// Do an invalid user in apply mode.
   745  	data = UserImportData{
   746  		Username: ptrStr(model.NewId()),
   747  	}
   748  	err = th.App.importUser(&data, false)
   749  	require.NotNil(t, err, "Should have failed to import invalid user.")
   750  
   751  	// Check that no more users are in the DB.
   752  	userCount4, err := th.App.Srv().Store.User().Count(model.UserCountOptions{
   753  		IncludeDeleted:     true,
   754  		IncludeBotAccounts: false,
   755  	})
   756  	require.Nil(t, err, "Failed to get user count.")
   757  	assert.Equal(t, userCount, userCount4, "Unexpected number of users")
   758  
   759  	// Do a valid user in apply mode.
   760  	username := model.NewId()
   761  	testsDir, _ := fileutils.FindDir("tests")
   762  	data = UserImportData{
   763  		ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")),
   764  		Username:     &username,
   765  		Email:        ptrStr(model.NewId() + "@example.com"),
   766  		Nickname:     ptrStr(model.NewId()),
   767  		FirstName:    ptrStr(model.NewId()),
   768  		LastName:     ptrStr(model.NewId()),
   769  		Position:     ptrStr(model.NewId()),
   770  	}
   771  	err = th.App.importUser(&data, false)
   772  	require.Nil(t, err, "Should have succeeded to import valid user.")
   773  
   774  	// Check that one more user is in the DB.
   775  	userCount5, err := th.App.Srv().Store.User().Count(model.UserCountOptions{
   776  		IncludeDeleted:     true,
   777  		IncludeBotAccounts: false,
   778  	})
   779  	require.Nil(t, err, "Failed to get user count.")
   780  	assert.Equal(t, userCount+1, userCount5, "Unexpected number of users")
   781  
   782  	// Get the user and check all the fields are correct.
   783  	user, err2 := th.App.GetUserByUsername(username)
   784  	require.Nil(t, err2, "Failed to get user from database.")
   785  
   786  	userBool := user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position
   787  	require.False(t, userBool, "User properties do not match Import Data.")
   788  
   789  	// Check calculated properties.
   790  	require.Empty(t, user.AuthService, "Expected Auth Service to be empty.")
   791  
   792  	require.Empty(t, user.AuthData, "Expected AuthData to be empty.")
   793  
   794  	require.NotEmpty(t, user.Password, "Expected password to be set.")
   795  
   796  	require.True(t, user.EmailVerified, "Expected EmailVerified to be true.")
   797  
   798  	require.Equal(t, user.Locale, *th.App.Config().LocalizationSettings.DefaultClientLocale, "Expected Locale to be the default.")
   799  
   800  	require.Equal(t, user.Roles, "system_user", "Expected roles to be system_user")
   801  
   802  	// Alter all the fields of that user.
   803  	data.Email = ptrStr(model.NewId() + "@example.com")
   804  	data.ProfileImage = ptrStr(filepath.Join(testsDir, "testgif.gif"))
   805  	data.AuthService = ptrStr("ldap")
   806  	data.AuthData = &username
   807  	data.Nickname = ptrStr(model.NewId())
   808  	data.FirstName = ptrStr(model.NewId())
   809  	data.LastName = ptrStr(model.NewId())
   810  	data.Position = ptrStr(model.NewId())
   811  	data.Roles = ptrStr("system_admin system_user")
   812  	data.Locale = ptrStr("zh_CN")
   813  
   814  	err = th.App.importUser(&data, false)
   815  	require.Nil(t, err, "Should have succeeded to update valid user %v", err)
   816  
   817  	// Check user count the same.
   818  	userCount6, err := th.App.Srv().Store.User().Count(model.UserCountOptions{
   819  		IncludeDeleted:     true,
   820  		IncludeBotAccounts: false,
   821  	})
   822  	require.Nil(t, err, "Failed to get user count.")
   823  	assert.Equal(t, userCount+1, userCount6, "Unexpected number of users")
   824  
   825  	// Get the user and check all the fields are correct.
   826  	user, err2 = th.App.GetUserByUsername(username)
   827  	require.Nil(t, err2, "Failed to get user from database.")
   828  
   829  	userBool = user.Email != *data.Email || user.Nickname != *data.Nickname || user.FirstName != *data.FirstName || user.LastName != *data.LastName || user.Position != *data.Position
   830  	require.False(t, userBool, "Updated User properties do not match Import Data.")
   831  
   832  	require.Equal(t, "ldap", user.AuthService, "Expected Auth Service to be ldap \"%v\"", user.AuthService)
   833  
   834  	require.Equal(t, user.AuthData, data.AuthData, "Expected AuthData to be set.")
   835  
   836  	require.Empty(t, user.Password, "Expected password to be empty.")
   837  
   838  	require.True(t, user.EmailVerified, "Expected EmailVerified to be true.")
   839  
   840  	require.Equal(t, *data.Locale, user.Locale, "Expected Locale to be the set.")
   841  
   842  	require.Equal(t, *data.Roles, user.Roles, "Expected roles to be set: %v", user.Roles)
   843  
   844  	// Check Password and AuthData together.
   845  	data.Password = ptrStr("PasswordTest")
   846  	err = th.App.importUser(&data, false)
   847  	require.NotNil(t, err, "Should have failed to import invalid user.")
   848  
   849  	data.AuthData = nil
   850  	data.AuthService = nil
   851  	err = th.App.importUser(&data, false)
   852  	require.Nil(t, err, "Should have succeeded to update valid user %v", err)
   853  
   854  	data.Password = ptrStr("")
   855  	err = th.App.importUser(&data, false)
   856  	require.NotNil(t, err, "Should have failed to import invalid user.")
   857  
   858  	data.Password = ptrStr(strings.Repeat("0123456789", 10))
   859  	err = th.App.importUser(&data, false)
   860  	require.NotNil(t, err, "Should have failed to import invalid user.")
   861  
   862  	data.Password = ptrStr("TestPassword")
   863  
   864  	// Test team and channel memberships
   865  	teamName := model.NewRandomTeamName()
   866  	th.App.importTeam(&TeamImportData{
   867  		Name:        &teamName,
   868  		DisplayName: ptrStr("Display Name"),
   869  		Type:        ptrStr("O"),
   870  	}, false)
   871  	team, err := th.App.GetTeamByName(teamName)
   872  	require.Nil(t, err, "Failed to get team from database.")
   873  
   874  	channelName := model.NewId()
   875  	th.App.importChannel(&ChannelImportData{
   876  		Team:        &teamName,
   877  		Name:        &channelName,
   878  		DisplayName: ptrStr("Display Name"),
   879  		Type:        ptrStr("O"),
   880  	}, false)
   881  	channel, err := th.App.GetChannelByName(channelName, team.Id, false)
   882  	require.Nil(t, err, "Failed to get channel from database.")
   883  
   884  	username = model.NewId()
   885  	data = UserImportData{
   886  		Username:  &username,
   887  		Email:     ptrStr(model.NewId() + "@example.com"),
   888  		Nickname:  ptrStr(model.NewId()),
   889  		FirstName: ptrStr(model.NewId()),
   890  		LastName:  ptrStr(model.NewId()),
   891  		Position:  ptrStr(model.NewId()),
   892  	}
   893  
   894  	teamMembers, err := th.App.GetTeamMembers(team.Id, 0, 1000, nil)
   895  	require.Nil(t, err, "Failed to get team member count")
   896  	teamMemberCount := len(teamMembers)
   897  
   898  	channelMemberCount, err := th.App.GetChannelMemberCount(channel.Id)
   899  	require.Nil(t, err, "Failed to get channel member count")
   900  
   901  	// Test with an invalid team & channel membership in dry-run mode.
   902  	data.Teams = &[]UserTeamImportData{
   903  		{
   904  			Roles: ptrStr("invalid"),
   905  			Channels: &[]UserChannelImportData{
   906  				{
   907  					Roles: ptrStr("invalid"),
   908  				},
   909  			},
   910  		},
   911  	}
   912  	err = th.App.importUser(&data, true)
   913  	assert.NotNil(t, err)
   914  
   915  	// Test with an unknown team name & invalid channel membership in dry-run mode.
   916  	data.Teams = &[]UserTeamImportData{
   917  		{
   918  			Name: ptrStr(model.NewId()),
   919  			Channels: &[]UserChannelImportData{
   920  				{
   921  					Roles: ptrStr("invalid"),
   922  				},
   923  			},
   924  		},
   925  	}
   926  	err = th.App.importUser(&data, true)
   927  	assert.NotNil(t, err)
   928  
   929  	// Test with a valid team & invalid channel membership in dry-run mode.
   930  	data.Teams = &[]UserTeamImportData{
   931  		{
   932  			Name: &teamName,
   933  			Channels: &[]UserChannelImportData{
   934  				{
   935  					Roles: ptrStr("invalid"),
   936  				},
   937  			},
   938  		},
   939  	}
   940  	err = th.App.importUser(&data, true)
   941  	assert.NotNil(t, err)
   942  
   943  	// Test with a valid team & unknown channel name in dry-run mode.
   944  	data.Teams = &[]UserTeamImportData{
   945  		{
   946  			Name: &teamName,
   947  			Channels: &[]UserChannelImportData{
   948  				{
   949  					Name: ptrStr(model.NewId()),
   950  				},
   951  			},
   952  		},
   953  	}
   954  	err = th.App.importUser(&data, true)
   955  	assert.Nil(t, err)
   956  
   957  	// Test with a valid team & valid channel name in dry-run mode.
   958  	data.Teams = &[]UserTeamImportData{
   959  		{
   960  			Name: &teamName,
   961  			Channels: &[]UserChannelImportData{
   962  				{
   963  					Name: &channelName,
   964  				},
   965  			},
   966  		},
   967  	}
   968  	err = th.App.importUser(&data, true)
   969  	assert.Nil(t, err)
   970  
   971  	// Check no new member objects were created because dry run mode.
   972  	tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000, nil)
   973  	require.Nil(t, err, "Failed to get Team Member Count")
   974  	require.Len(t, tmc, teamMemberCount, "Number of team members not as expected")
   975  
   976  	cmc, err := th.App.GetChannelMemberCount(channel.Id)
   977  	require.Nil(t, err, "Failed to get Channel Member Count")
   978  	require.Equal(t, channelMemberCount, cmc, "Number of channel members not as expected")
   979  
   980  	// Test with an invalid team & channel membership in apply mode.
   981  	data.Teams = &[]UserTeamImportData{
   982  		{
   983  			Roles: ptrStr("invalid"),
   984  			Channels: &[]UserChannelImportData{
   985  				{
   986  					Roles: ptrStr("invalid"),
   987  				},
   988  			},
   989  		},
   990  	}
   991  	err = th.App.importUser(&data, false)
   992  	assert.NotNil(t, err)
   993  
   994  	// Test with an unknown team name & invalid channel membership in apply mode.
   995  	data.Teams = &[]UserTeamImportData{
   996  		{
   997  			Name: ptrStr(model.NewId()),
   998  			Channels: &[]UserChannelImportData{
   999  				{
  1000  					Roles: ptrStr("invalid"),
  1001  				},
  1002  			},
  1003  		},
  1004  	}
  1005  	err = th.App.importUser(&data, false)
  1006  	assert.NotNil(t, err)
  1007  
  1008  	// Test with a valid team & invalid channel membership in apply mode.
  1009  	data.Teams = &[]UserTeamImportData{
  1010  		{
  1011  			Name: &teamName,
  1012  			Channels: &[]UserChannelImportData{
  1013  				{
  1014  					Roles: ptrStr("invalid"),
  1015  				},
  1016  			},
  1017  		},
  1018  	}
  1019  	err = th.App.importUser(&data, false)
  1020  	assert.NotNil(t, err)
  1021  
  1022  	// Check no new member objects were created because all tests should have failed so far.
  1023  	tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
  1024  	require.Nil(t, err, "Failed to get Team Member Count")
  1025  	require.Len(t, tmc, teamMemberCount)
  1026  
  1027  	cmc, err = th.App.GetChannelMemberCount(channel.Id)
  1028  	require.Nil(t, err, "Failed to get Channel Member Count")
  1029  	require.Equal(t, channelMemberCount, cmc)
  1030  
  1031  	// Test with a valid team & unknown channel name in apply mode.
  1032  	data.Teams = &[]UserTeamImportData{
  1033  		{
  1034  			Name: &teamName,
  1035  			Channels: &[]UserChannelImportData{
  1036  				{
  1037  					Name: ptrStr(model.NewId()),
  1038  				},
  1039  			},
  1040  		},
  1041  	}
  1042  	err = th.App.importUser(&data, false)
  1043  	assert.NotNil(t, err)
  1044  
  1045  	// Check only new team member object created because dry run mode.
  1046  	tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
  1047  	require.Nil(t, err, "Failed to get Team Member Count")
  1048  	require.Len(t, tmc, teamMemberCount+1)
  1049  
  1050  	cmc, err = th.App.GetChannelMemberCount(channel.Id)
  1051  	require.Nil(t, err, "Failed to get Channel Member Count")
  1052  	require.Equal(t, channelMemberCount, cmc)
  1053  
  1054  	// Check team member properties.
  1055  	user, err = th.App.GetUserByUsername(username)
  1056  	require.Nil(t, err, "Failed to get user from database.")
  1057  
  1058  	teamMember, err := th.App.GetTeamMember(team.Id, user.Id)
  1059  	require.Nil(t, err, "Failed to get team member from database.")
  1060  	require.Equal(t, "team_user", teamMember.Roles)
  1061  
  1062  	// Test with a valid team & valid channel name in apply mode.
  1063  	data.Teams = &[]UserTeamImportData{
  1064  		{
  1065  			Name: &teamName,
  1066  			Channels: &[]UserChannelImportData{
  1067  				{
  1068  					Name: &channelName,
  1069  				},
  1070  			},
  1071  		},
  1072  	}
  1073  	err = th.App.importUser(&data, false)
  1074  	assert.Nil(t, err)
  1075  
  1076  	// Check only new channel member object created because dry run mode.
  1077  	tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
  1078  	require.Nil(t, err, "Failed to get Team Member Count")
  1079  	require.Len(t, tmc, teamMemberCount+1, "Number of team members not as expected")
  1080  
  1081  	cmc, err = th.App.GetChannelMemberCount(channel.Id)
  1082  	require.Nil(t, err, "Failed to get Channel Member Count")
  1083  	require.Equal(t, channelMemberCount+1, cmc, "Number of channel members not as expected")
  1084  
  1085  	// Check channel member properties.
  1086  	channelMember, err := th.App.GetChannelMember(channel.Id, user.Id)
  1087  	require.Nil(t, err, "Failed to get channel member from database.")
  1088  	assert.Equal(t, "channel_user", channelMember.Roles)
  1089  	assert.Equal(t, "default", channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP])
  1090  	assert.Equal(t, "default", channelMember.NotifyProps[model.PUSH_NOTIFY_PROP])
  1091  	assert.Equal(t, "all", channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP])
  1092  
  1093  	// Test with the properties of the team and channel membership changed.
  1094  	data.Teams = &[]UserTeamImportData{
  1095  		{
  1096  			Name:  &teamName,
  1097  			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"}`),
  1098  			Roles: ptrStr("team_user team_admin"),
  1099  			Channels: &[]UserChannelImportData{
  1100  				{
  1101  					Name:  &channelName,
  1102  					Roles: ptrStr("channel_user channel_admin"),
  1103  					NotifyProps: &UserChannelNotifyPropsImportData{
  1104  						Desktop:    ptrStr(model.USER_NOTIFY_MENTION),
  1105  						Mobile:     ptrStr(model.USER_NOTIFY_MENTION),
  1106  						MarkUnread: ptrStr(model.USER_NOTIFY_MENTION),
  1107  					},
  1108  					Favorite: ptrBool(true),
  1109  				},
  1110  			},
  1111  		},
  1112  	}
  1113  	err = th.App.importUser(&data, false)
  1114  	assert.Nil(t, err)
  1115  
  1116  	// Check both member properties.
  1117  	teamMember, err = th.App.GetTeamMember(team.Id, user.Id)
  1118  	require.Nil(t, err, "Failed to get team member from database.")
  1119  	require.Equal(t, "team_user team_admin", teamMember.Roles)
  1120  
  1121  	channelMember, err = th.App.GetChannelMember(channel.Id, user.Id)
  1122  	require.Nil(t, err, "Failed to get channel member Desktop from database.")
  1123  	assert.Equal(t, "channel_user channel_admin", channelMember.Roles)
  1124  	assert.Equal(t, model.USER_NOTIFY_MENTION, channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP])
  1125  	assert.Equal(t, model.USER_NOTIFY_MENTION, channelMember.NotifyProps[model.PUSH_NOTIFY_PROP])
  1126  	assert.Equal(t, model.USER_NOTIFY_MENTION, channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP])
  1127  
  1128  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true")
  1129  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, team.Id, *(*data.Teams)[0].Theme)
  1130  
  1131  	// No more new member objects.
  1132  	tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
  1133  	require.Nil(t, err, "Failed to get Team Member Count")
  1134  	require.Len(t, tmc, teamMemberCount+1, "Number of team members not as expected")
  1135  
  1136  	cmc, err = th.App.GetChannelMemberCount(channel.Id)
  1137  	require.Nil(t, err, "Failed to get Channel Member Count")
  1138  	require.Equal(t, channelMemberCount+1, cmc, "Number of channel members not as expected")
  1139  
  1140  	// Add a user with some preferences.
  1141  	username = model.NewId()
  1142  	data = UserImportData{
  1143  		Username:           &username,
  1144  		Email:              ptrStr(model.NewId() + "@example.com"),
  1145  		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"}`),
  1146  		UseMilitaryTime:    ptrStr("true"),
  1147  		CollapsePreviews:   ptrStr("true"),
  1148  		MessageDisplay:     ptrStr("compact"),
  1149  		ChannelDisplayMode: ptrStr("centered"),
  1150  		TutorialStep:       ptrStr("3"),
  1151  		UseMarkdownPreview: ptrStr("true"),
  1152  		UseFormatting:      ptrStr("true"),
  1153  		ShowUnreadSection:  ptrStr("true"),
  1154  		EmailInterval:      ptrStr("immediately"),
  1155  	}
  1156  	err = th.App.importUser(&data, false)
  1157  	assert.Nil(t, err)
  1158  
  1159  	// Check their values.
  1160  	user, err = th.App.GetUserByUsername(username)
  1161  	require.Nil(t, err, "Failed to get user from database.")
  1162  
  1163  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme)
  1164  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_USE_MILITARY_TIME, *data.UseMilitaryTime)
  1165  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSE_SETTING, *data.CollapsePreviews)
  1166  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_MESSAGE_DISPLAY, *data.MessageDisplay)
  1167  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_CHANNEL_DISPLAY_MODE, *data.ChannelDisplayMode)
  1168  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep)
  1169  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_ADVANCED_SETTINGS, "feature_enabled_markdown_preview", *data.UseMarkdownPreview)
  1170  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_ADVANCED_SETTINGS, "formatting", *data.UseFormatting)
  1171  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_SIDEBAR_SETTINGS, "show_unread_section", *data.ShowUnreadSection)
  1172  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL, "30")
  1173  
  1174  	// Change those preferences.
  1175  	data = UserImportData{
  1176  		Username:           &username,
  1177  		Email:              ptrStr(model.NewId() + "@example.com"),
  1178  		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"}`),
  1179  		UseMilitaryTime:    ptrStr("false"),
  1180  		CollapsePreviews:   ptrStr("false"),
  1181  		MessageDisplay:     ptrStr("clean"),
  1182  		ChannelDisplayMode: ptrStr("full"),
  1183  		TutorialStep:       ptrStr("2"),
  1184  		EmailInterval:      ptrStr("hour"),
  1185  	}
  1186  	err = th.App.importUser(&data, false)
  1187  	assert.Nil(t, err)
  1188  
  1189  	// Check their values again.
  1190  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, "", *data.Theme)
  1191  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_USE_MILITARY_TIME, *data.UseMilitaryTime)
  1192  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSE_SETTING, *data.CollapsePreviews)
  1193  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_MESSAGE_DISPLAY, *data.MessageDisplay)
  1194  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_CHANNEL_DISPLAY_MODE, *data.ChannelDisplayMode)
  1195  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, user.Id, *data.TutorialStep)
  1196  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL, "3600")
  1197  
  1198  	// Set Notify Without mention keys
  1199  	data.NotifyProps = &UserNotifyPropsImportData{
  1200  		Desktop:          ptrStr(model.USER_NOTIFY_ALL),
  1201  		DesktopSound:     ptrStr("true"),
  1202  		Email:            ptrStr("true"),
  1203  		Mobile:           ptrStr(model.USER_NOTIFY_ALL),
  1204  		MobilePushStatus: ptrStr(model.STATUS_ONLINE),
  1205  		ChannelTrigger:   ptrStr("true"),
  1206  		CommentsTrigger:  ptrStr(model.COMMENTS_NOTIFY_ROOT),
  1207  	}
  1208  	err = th.App.importUser(&data, false)
  1209  	assert.Nil(t, err)
  1210  
  1211  	user, err = th.App.GetUserByUsername(username)
  1212  	require.Nil(t, err, "Failed to get user from database.")
  1213  
  1214  	checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL)
  1215  	checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true")
  1216  	checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true")
  1217  	checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL)
  1218  	checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE)
  1219  	checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true")
  1220  	checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT)
  1221  	checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "")
  1222  
  1223  	// Set Notify Props with Mention keys
  1224  	data.NotifyProps = &UserNotifyPropsImportData{
  1225  		Desktop:          ptrStr(model.USER_NOTIFY_ALL),
  1226  		DesktopSound:     ptrStr("true"),
  1227  		Email:            ptrStr("true"),
  1228  		Mobile:           ptrStr(model.USER_NOTIFY_ALL),
  1229  		MobilePushStatus: ptrStr(model.STATUS_ONLINE),
  1230  		ChannelTrigger:   ptrStr("true"),
  1231  		CommentsTrigger:  ptrStr(model.COMMENTS_NOTIFY_ROOT),
  1232  		MentionKeys:      ptrStr("valid,misc"),
  1233  	}
  1234  	err = th.App.importUser(&data, false)
  1235  	assert.Nil(t, err)
  1236  
  1237  	user, err = th.App.GetUserByUsername(username)
  1238  	require.Nil(t, err, "Failed to get user from database.")
  1239  
  1240  	checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_ALL)
  1241  	checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "true")
  1242  	checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "true")
  1243  	checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_ALL)
  1244  	checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_ONLINE)
  1245  	checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "true")
  1246  	checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ROOT)
  1247  	checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "valid,misc")
  1248  
  1249  	// Change Notify Props with mention keys
  1250  	data.NotifyProps = &UserNotifyPropsImportData{
  1251  		Desktop:          ptrStr(model.USER_NOTIFY_MENTION),
  1252  		DesktopSound:     ptrStr("false"),
  1253  		Email:            ptrStr("false"),
  1254  		Mobile:           ptrStr(model.USER_NOTIFY_NONE),
  1255  		MobilePushStatus: ptrStr(model.STATUS_AWAY),
  1256  		ChannelTrigger:   ptrStr("false"),
  1257  		CommentsTrigger:  ptrStr(model.COMMENTS_NOTIFY_ANY),
  1258  		MentionKeys:      ptrStr("misc"),
  1259  	}
  1260  	err = th.App.importUser(&data, false)
  1261  	assert.Nil(t, err)
  1262  
  1263  	user, err = th.App.GetUserByUsername(username)
  1264  	require.Nil(t, err, "Failed to get user from database.")
  1265  
  1266  	checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION)
  1267  	checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false")
  1268  	checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false")
  1269  	checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE)
  1270  	checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY)
  1271  	checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false")
  1272  	checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY)
  1273  	checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc")
  1274  
  1275  	// Change Notify Props without mention keys
  1276  	data.NotifyProps = &UserNotifyPropsImportData{
  1277  		Desktop:          ptrStr(model.USER_NOTIFY_MENTION),
  1278  		DesktopSound:     ptrStr("false"),
  1279  		Email:            ptrStr("false"),
  1280  		Mobile:           ptrStr(model.USER_NOTIFY_NONE),
  1281  		MobilePushStatus: ptrStr(model.STATUS_AWAY),
  1282  		ChannelTrigger:   ptrStr("false"),
  1283  		CommentsTrigger:  ptrStr(model.COMMENTS_NOTIFY_ANY),
  1284  	}
  1285  	err = th.App.importUser(&data, false)
  1286  	assert.Nil(t, err)
  1287  
  1288  	user, err = th.App.GetUserByUsername(username)
  1289  	require.Nil(t, err, "Failed to get user from database.")
  1290  
  1291  	checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION)
  1292  	checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false")
  1293  	checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false")
  1294  	checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE)
  1295  	checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY)
  1296  	checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false")
  1297  	checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY)
  1298  	checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc")
  1299  
  1300  	// Check Notify Props get set on *create* user.
  1301  	username = model.NewId()
  1302  	data = UserImportData{
  1303  		Username: &username,
  1304  		Email:    ptrStr(model.NewId() + "@example.com"),
  1305  	}
  1306  	data.NotifyProps = &UserNotifyPropsImportData{
  1307  		Desktop:          ptrStr(model.USER_NOTIFY_MENTION),
  1308  		DesktopSound:     ptrStr("false"),
  1309  		Email:            ptrStr("false"),
  1310  		Mobile:           ptrStr(model.USER_NOTIFY_NONE),
  1311  		MobilePushStatus: ptrStr(model.STATUS_AWAY),
  1312  		ChannelTrigger:   ptrStr("false"),
  1313  		CommentsTrigger:  ptrStr(model.COMMENTS_NOTIFY_ANY),
  1314  		MentionKeys:      ptrStr("misc"),
  1315  	}
  1316  
  1317  	err = th.App.importUser(&data, false)
  1318  	assert.Nil(t, err)
  1319  
  1320  	user, err = th.App.GetUserByUsername(username)
  1321  	require.Nil(t, err, "Failed to get user from database.")
  1322  
  1323  	checkNotifyProp(t, user, model.DESKTOP_NOTIFY_PROP, model.USER_NOTIFY_MENTION)
  1324  	checkNotifyProp(t, user, model.DESKTOP_SOUND_NOTIFY_PROP, "false")
  1325  	checkNotifyProp(t, user, model.EMAIL_NOTIFY_PROP, "false")
  1326  	checkNotifyProp(t, user, model.PUSH_NOTIFY_PROP, model.USER_NOTIFY_NONE)
  1327  	checkNotifyProp(t, user, model.PUSH_STATUS_NOTIFY_PROP, model.STATUS_AWAY)
  1328  	checkNotifyProp(t, user, model.CHANNEL_MENTIONS_NOTIFY_PROP, "false")
  1329  	checkNotifyProp(t, user, model.COMMENTS_NOTIFY_PROP, model.COMMENTS_NOTIFY_ANY)
  1330  	checkNotifyProp(t, user, model.MENTION_KEYS_NOTIFY_PROP, "misc")
  1331  
  1332  	// Test importing a user with roles set to a team and a channel which are affected by an override scheme.
  1333  	// The import subsystem should translate `channel_admin/channel_user/team_admin/team_user`
  1334  	// to the appropriate scheme-managed-role booleans.
  1335  
  1336  	// Mark the phase 2 permissions migration as completed.
  1337  	th.App.Srv().Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
  1338  
  1339  	defer func() {
  1340  		th.App.Srv().Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
  1341  	}()
  1342  
  1343  	teamSchemeData := &SchemeImportData{
  1344  		Name:        ptrStr(model.NewId()),
  1345  		DisplayName: ptrStr(model.NewId()),
  1346  		Scope:       ptrStr("team"),
  1347  		DefaultTeamGuestRole: &RoleImportData{
  1348  			Name:        ptrStr(model.NewId()),
  1349  			DisplayName: ptrStr(model.NewId()),
  1350  		},
  1351  		DefaultTeamUserRole: &RoleImportData{
  1352  			Name:        ptrStr(model.NewId()),
  1353  			DisplayName: ptrStr(model.NewId()),
  1354  		},
  1355  		DefaultTeamAdminRole: &RoleImportData{
  1356  			Name:        ptrStr(model.NewId()),
  1357  			DisplayName: ptrStr(model.NewId()),
  1358  		},
  1359  		DefaultChannelGuestRole: &RoleImportData{
  1360  			Name:        ptrStr(model.NewId()),
  1361  			DisplayName: ptrStr(model.NewId()),
  1362  		},
  1363  		DefaultChannelUserRole: &RoleImportData{
  1364  			Name:        ptrStr(model.NewId()),
  1365  			DisplayName: ptrStr(model.NewId()),
  1366  		},
  1367  		DefaultChannelAdminRole: &RoleImportData{
  1368  			Name:        ptrStr(model.NewId()),
  1369  			DisplayName: ptrStr(model.NewId()),
  1370  		},
  1371  		Description: ptrStr("description"),
  1372  	}
  1373  
  1374  	err = th.App.importScheme(teamSchemeData, false)
  1375  	assert.Nil(t, err)
  1376  
  1377  	teamScheme, nErr := th.App.Srv().Store.Scheme().GetByName(*teamSchemeData.Name)
  1378  	require.Nil(t, nErr, "Failed to import scheme")
  1379  
  1380  	teamData := &TeamImportData{
  1381  		Name:            ptrStr(model.NewId()),
  1382  		DisplayName:     ptrStr("Display Name"),
  1383  		Type:            ptrStr("O"),
  1384  		Description:     ptrStr("The team description."),
  1385  		AllowOpenInvite: ptrBool(true),
  1386  		Scheme:          &teamScheme.Name,
  1387  	}
  1388  	err = th.App.importTeam(teamData, false)
  1389  	assert.Nil(t, err)
  1390  	team, err = th.App.GetTeamByName(teamName)
  1391  	require.Nil(t, err, "Failed to get team from database.")
  1392  
  1393  	channelData := &ChannelImportData{
  1394  		Team:        &teamName,
  1395  		Name:        ptrStr(model.NewId()),
  1396  		DisplayName: ptrStr("Display Name"),
  1397  		Type:        ptrStr("O"),
  1398  		Header:      ptrStr("Channe Header"),
  1399  		Purpose:     ptrStr("Channel Purpose"),
  1400  	}
  1401  	err = th.App.importChannel(channelData, false)
  1402  	assert.Nil(t, err)
  1403  	channel, err = th.App.GetChannelByName(*channelData.Name, team.Id, false)
  1404  	require.Nil(t, err, "Failed to get channel from database")
  1405  
  1406  	// Test with a valid team & valid channel name in apply mode.
  1407  	userData := &UserImportData{
  1408  		Username: &username,
  1409  		Email:    ptrStr(model.NewId() + "@example.com"),
  1410  		Teams: &[]UserTeamImportData{
  1411  			{
  1412  				Name:  &team.Name,
  1413  				Roles: ptrStr("team_user team_admin"),
  1414  				Channels: &[]UserChannelImportData{
  1415  					{
  1416  						Name:  &channel.Name,
  1417  						Roles: ptrStr("channel_admin channel_user"),
  1418  					},
  1419  				},
  1420  			},
  1421  		},
  1422  	}
  1423  	err = th.App.importUser(userData, false)
  1424  	assert.Nil(t, err)
  1425  
  1426  	user, err = th.App.GetUserByUsername(*userData.Username)
  1427  	require.Nil(t, err, "Failed to get user from database.")
  1428  
  1429  	teamMember, err = th.App.GetTeamMember(team.Id, user.Id)
  1430  	require.Nil(t, err, "Failed to get the team member")
  1431  
  1432  	assert.True(t, teamMember.SchemeAdmin)
  1433  	assert.True(t, teamMember.SchemeUser)
  1434  	assert.False(t, teamMember.SchemeGuest)
  1435  	assert.Equal(t, "", teamMember.ExplicitRoles)
  1436  
  1437  	channelMember, err = th.App.GetChannelMember(channel.Id, user.Id)
  1438  	require.Nil(t, err, "Failed to get the channel member")
  1439  
  1440  	assert.True(t, channelMember.SchemeAdmin)
  1441  	assert.True(t, channelMember.SchemeUser)
  1442  	assert.False(t, channelMember.SchemeGuest)
  1443  	assert.Equal(t, "", channelMember.ExplicitRoles)
  1444  
  1445  	// Test importing deleted user with a valid team & valid channel name in apply mode.
  1446  	username = model.NewId()
  1447  	deleteAt := model.GetMillis()
  1448  	deletedUserData := &UserImportData{
  1449  		Username: &username,
  1450  		DeleteAt: &deleteAt,
  1451  		Email:    ptrStr(model.NewId() + "@example.com"),
  1452  		Teams: &[]UserTeamImportData{
  1453  			{
  1454  				Name:  &team.Name,
  1455  				Roles: ptrStr("team_user"),
  1456  				Channels: &[]UserChannelImportData{
  1457  					{
  1458  						Name:  &channel.Name,
  1459  						Roles: ptrStr("channel_user"),
  1460  					},
  1461  				},
  1462  			},
  1463  		},
  1464  	}
  1465  	err = th.App.importUser(deletedUserData, false)
  1466  	assert.Nil(t, err)
  1467  
  1468  	user, err = th.App.GetUserByUsername(*deletedUserData.Username)
  1469  	require.Nil(t, err, "Failed to get user from database.")
  1470  
  1471  	teamMember, err = th.App.GetTeamMember(team.Id, user.Id)
  1472  	require.Nil(t, err, "Failed to get the team member")
  1473  
  1474  	assert.False(t, teamMember.SchemeAdmin)
  1475  	assert.True(t, teamMember.SchemeUser)
  1476  	assert.False(t, teamMember.SchemeGuest)
  1477  	assert.Equal(t, "", teamMember.ExplicitRoles)
  1478  
  1479  	channelMember, err = th.App.GetChannelMember(channel.Id, user.Id)
  1480  	require.Nil(t, err, "Failed to get the channel member")
  1481  
  1482  	assert.False(t, teamMember.SchemeAdmin)
  1483  	assert.True(t, channelMember.SchemeUser)
  1484  	assert.False(t, teamMember.SchemeGuest)
  1485  	assert.Equal(t, "", channelMember.ExplicitRoles)
  1486  
  1487  	// Test importing deleted guest with a valid team & valid channel name in apply mode.
  1488  	username = model.NewId()
  1489  	deleteAt = model.GetMillis()
  1490  	deletedGuestData := &UserImportData{
  1491  		Username: &username,
  1492  		DeleteAt: &deleteAt,
  1493  		Email:    ptrStr(model.NewId() + "@example.com"),
  1494  		Teams: &[]UserTeamImportData{
  1495  			{
  1496  				Name:  &team.Name,
  1497  				Roles: ptrStr("team_guest"),
  1498  				Channels: &[]UserChannelImportData{
  1499  					{
  1500  						Name:  &channel.Name,
  1501  						Roles: ptrStr("channel_guest"),
  1502  					},
  1503  				},
  1504  			},
  1505  		},
  1506  	}
  1507  	err = th.App.importUser(deletedGuestData, false)
  1508  	assert.Nil(t, err)
  1509  
  1510  	user, err = th.App.GetUserByUsername(*deletedGuestData.Username)
  1511  	require.Nil(t, err, "Failed to get user from database.")
  1512  
  1513  	teamMember, err = th.App.GetTeamMember(team.Id, user.Id)
  1514  	require.Nil(t, err, "Failed to get the team member")
  1515  
  1516  	assert.False(t, teamMember.SchemeAdmin)
  1517  	assert.False(t, teamMember.SchemeUser)
  1518  	assert.True(t, teamMember.SchemeGuest)
  1519  	assert.Equal(t, "", teamMember.ExplicitRoles)
  1520  
  1521  	channelMember, err = th.App.GetChannelMember(channel.Id, user.Id)
  1522  	require.Nil(t, err, "Failed to get the channel member")
  1523  
  1524  	assert.False(t, teamMember.SchemeAdmin)
  1525  	assert.False(t, channelMember.SchemeUser)
  1526  	assert.True(t, teamMember.SchemeGuest)
  1527  	assert.Equal(t, "", channelMember.ExplicitRoles)
  1528  }
  1529  
  1530  func TestImportUserTeams(t *testing.T) {
  1531  	th := Setup(t).InitBasic()
  1532  	defer th.TearDown()
  1533  	team2 := th.CreateTeam()
  1534  	channel2 := th.CreateChannel(th.BasicTeam)
  1535  	channel3 := th.CreateChannel(team2)
  1536  	customRole := th.CreateRole("test_custom_role")
  1537  	sampleTheme := "{\"test\":\"#abcdef\"}"
  1538  
  1539  	tt := []struct {
  1540  		name                  string
  1541  		data                  *[]UserTeamImportData
  1542  		expectedError         bool
  1543  		expectedUserTeams     int
  1544  		expectedUserChannels  int
  1545  		expectedExplicitRoles string
  1546  		expectedRoles         string
  1547  		expectedTheme         string
  1548  	}{
  1549  		{
  1550  			name: "Not existing team should fail",
  1551  			data: &[]UserTeamImportData{
  1552  				{
  1553  					Name: model.NewString("not-existing-team-name"),
  1554  				},
  1555  			},
  1556  			expectedError: true,
  1557  		},
  1558  		{
  1559  			name:                 "nil data shouldn't do anything",
  1560  			expectedError:        false,
  1561  			expectedUserTeams:    0,
  1562  			expectedUserChannels: 0,
  1563  		},
  1564  		{
  1565  			name: "Should fail if one of the roles doesn't exists",
  1566  			data: &[]UserTeamImportData{
  1567  				{
  1568  					Name:  &th.BasicTeam.Name,
  1569  					Roles: model.NewString("not-existing-role"),
  1570  				},
  1571  			},
  1572  			expectedError:         true,
  1573  			expectedUserTeams:     1,
  1574  			expectedUserChannels:  0,
  1575  			expectedExplicitRoles: "",
  1576  			expectedRoles:         "team_user",
  1577  		},
  1578  		{
  1579  			name: "Should success to import explicit role",
  1580  			data: &[]UserTeamImportData{
  1581  				{
  1582  					Name:  &th.BasicTeam.Name,
  1583  					Roles: &customRole.Name,
  1584  				},
  1585  			},
  1586  			expectedError:         false,
  1587  			expectedUserTeams:     1,
  1588  			expectedUserChannels:  1,
  1589  			expectedExplicitRoles: customRole.Name,
  1590  			expectedRoles:         customRole.Name + " team_user",
  1591  		},
  1592  		{
  1593  			name: "Should success to import admin role",
  1594  			data: &[]UserTeamImportData{
  1595  				{
  1596  					Name:  &th.BasicTeam.Name,
  1597  					Roles: model.NewString(model.TEAM_ADMIN_ROLE_ID),
  1598  				},
  1599  			},
  1600  			expectedError:         false,
  1601  			expectedUserTeams:     1,
  1602  			expectedUserChannels:  1,
  1603  			expectedExplicitRoles: "",
  1604  			expectedRoles:         "team_user team_admin",
  1605  		},
  1606  		{
  1607  			name: "Should success to import with theme",
  1608  			data: &[]UserTeamImportData{
  1609  				{
  1610  					Name:  &th.BasicTeam.Name,
  1611  					Theme: &sampleTheme,
  1612  				},
  1613  			},
  1614  			expectedError:         false,
  1615  			expectedUserTeams:     1,
  1616  			expectedUserChannels:  1,
  1617  			expectedExplicitRoles: "",
  1618  			expectedRoles:         "team_user",
  1619  			expectedTheme:         sampleTheme,
  1620  		},
  1621  		{
  1622  			name: "Team without channels must add the default channel",
  1623  			data: &[]UserTeamImportData{
  1624  				{
  1625  					Name: &th.BasicTeam.Name,
  1626  				},
  1627  			},
  1628  			expectedError:         false,
  1629  			expectedUserTeams:     1,
  1630  			expectedUserChannels:  1,
  1631  			expectedExplicitRoles: "",
  1632  			expectedRoles:         "team_user",
  1633  		},
  1634  		{
  1635  			name: "Team with default channel must add only the default channel",
  1636  			data: &[]UserTeamImportData{
  1637  				{
  1638  					Name: &th.BasicTeam.Name,
  1639  					Channels: &[]UserChannelImportData{
  1640  						{
  1641  							Name: ptrStr(model.DEFAULT_CHANNEL),
  1642  						},
  1643  					},
  1644  				},
  1645  			},
  1646  			expectedError:         false,
  1647  			expectedUserTeams:     1,
  1648  			expectedUserChannels:  1,
  1649  			expectedExplicitRoles: "",
  1650  			expectedRoles:         "team_user",
  1651  		},
  1652  		{
  1653  			name: "Team with non default channel must add default channel and the other channel",
  1654  			data: &[]UserTeamImportData{
  1655  				{
  1656  					Name: &th.BasicTeam.Name,
  1657  					Channels: &[]UserChannelImportData{
  1658  						{
  1659  							Name: &th.BasicChannel.Name,
  1660  						},
  1661  					},
  1662  				},
  1663  			},
  1664  			expectedError:         false,
  1665  			expectedUserTeams:     1,
  1666  			expectedUserChannels:  2,
  1667  			expectedExplicitRoles: "",
  1668  			expectedRoles:         "team_user",
  1669  		},
  1670  		{
  1671  			name: "Multiple teams with multiple channels each",
  1672  			data: &[]UserTeamImportData{
  1673  				{
  1674  					Name: &th.BasicTeam.Name,
  1675  					Channels: &[]UserChannelImportData{
  1676  						{
  1677  							Name: &th.BasicChannel.Name,
  1678  						},
  1679  						{
  1680  							Name: &channel2.Name,
  1681  						},
  1682  					},
  1683  				},
  1684  				{
  1685  					Name: &team2.Name,
  1686  					Channels: &[]UserChannelImportData{
  1687  						{
  1688  							Name: &channel3.Name,
  1689  						},
  1690  						{
  1691  							Name: model.NewString("town-square"),
  1692  						},
  1693  					},
  1694  				},
  1695  			},
  1696  			expectedError:        false,
  1697  			expectedUserTeams:    2,
  1698  			expectedUserChannels: 5,
  1699  		},
  1700  	}
  1701  
  1702  	for _, tc := range tt {
  1703  		t.Run(tc.name, func(t *testing.T) {
  1704  			user := th.CreateUser()
  1705  
  1706  			// Two times import must end with the same results
  1707  			for x := 0; x < 2; x++ {
  1708  				err := th.App.importUserTeams(user, tc.data)
  1709  				if tc.expectedError {
  1710  					require.NotNil(t, err)
  1711  				} else {
  1712  					require.Nil(t, err)
  1713  				}
  1714  				teamMembers, err := th.App.Srv().Store.Team().GetTeamsForUser(user.Id)
  1715  				require.Nil(t, err)
  1716  				require.Len(t, teamMembers, tc.expectedUserTeams)
  1717  				if tc.expectedUserTeams == 1 {
  1718  					require.Equal(t, tc.expectedExplicitRoles, teamMembers[0].ExplicitRoles, "Not matching expected explicit roles")
  1719  					require.Equal(t, tc.expectedRoles, teamMembers[0].Roles, "not matching expected roles")
  1720  					if tc.expectedTheme != "" {
  1721  						pref, prefErr := th.App.Srv().Store.Preference().Get(user.Id, model.PREFERENCE_CATEGORY_THEME, teamMembers[0].TeamId)
  1722  						require.Nil(t, prefErr)
  1723  						require.Equal(t, tc.expectedTheme, pref.Value)
  1724  					}
  1725  				}
  1726  
  1727  				totalMembers := 0
  1728  				for _, teamMember := range teamMembers {
  1729  					channelMembers, err := th.App.Srv().Store.Channel().GetMembersForUser(teamMember.TeamId, user.Id)
  1730  					require.Nil(t, err)
  1731  					totalMembers += len(*channelMembers)
  1732  				}
  1733  				require.Equal(t, tc.expectedUserChannels, totalMembers)
  1734  			}
  1735  		})
  1736  	}
  1737  
  1738  	t.Run("Should fail if the MaxUserPerTeam is reached", func(t *testing.T) {
  1739  		user := th.CreateUser()
  1740  		data := &[]UserTeamImportData{
  1741  			{
  1742  				Name: &th.BasicTeam.Name,
  1743  			},
  1744  		}
  1745  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 1 })
  1746  		defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 100 })
  1747  		err := th.App.importUserTeams(user, data)
  1748  		require.NotNil(t, err)
  1749  	})
  1750  }
  1751  
  1752  func TestImportUserChannels(t *testing.T) {
  1753  	th := Setup(t).InitBasic()
  1754  	defer th.TearDown()
  1755  	channel2 := th.CreateChannel(th.BasicTeam)
  1756  	customRole := th.CreateRole("test_custom_role")
  1757  	sampleNotifyProps := UserChannelNotifyPropsImportData{
  1758  		Desktop:    model.NewString("all"),
  1759  		Mobile:     model.NewString("none"),
  1760  		MarkUnread: model.NewString("all"),
  1761  	}
  1762  
  1763  	tt := []struct {
  1764  		name                  string
  1765  		data                  *[]UserChannelImportData
  1766  		expectedError         bool
  1767  		expectedUserChannels  int
  1768  		expectedExplicitRoles string
  1769  		expectedRoles         string
  1770  		expectedNotifyProps   *UserChannelNotifyPropsImportData
  1771  	}{
  1772  		{
  1773  			name: "Not existing channel should fail",
  1774  			data: &[]UserChannelImportData{
  1775  				{
  1776  					Name: model.NewString("not-existing-channel-name"),
  1777  				},
  1778  			},
  1779  			expectedError: true,
  1780  		},
  1781  		{
  1782  			name:                 "nil data shouldn't do anything",
  1783  			expectedError:        false,
  1784  			expectedUserChannels: 0,
  1785  		},
  1786  		{
  1787  			name: "Should fail if one of the roles doesn't exists",
  1788  			data: &[]UserChannelImportData{
  1789  				{
  1790  					Name:  &th.BasicChannel.Name,
  1791  					Roles: model.NewString("not-existing-role"),
  1792  				},
  1793  			},
  1794  			expectedError:         true,
  1795  			expectedUserChannels:  1,
  1796  			expectedExplicitRoles: "",
  1797  			expectedRoles:         "channel_user",
  1798  		},
  1799  		{
  1800  			name: "Should success to import explicit role",
  1801  			data: &[]UserChannelImportData{
  1802  				{
  1803  					Name:  &th.BasicChannel.Name,
  1804  					Roles: &customRole.Name,
  1805  				},
  1806  			},
  1807  			expectedError:         false,
  1808  			expectedUserChannels:  1,
  1809  			expectedExplicitRoles: customRole.Name,
  1810  			expectedRoles:         customRole.Name + " channel_user",
  1811  		},
  1812  		{
  1813  			name: "Should success to import admin role",
  1814  			data: &[]UserChannelImportData{
  1815  				{
  1816  					Name:  &th.BasicChannel.Name,
  1817  					Roles: model.NewString(model.CHANNEL_ADMIN_ROLE_ID),
  1818  				},
  1819  			},
  1820  			expectedError:         false,
  1821  			expectedUserChannels:  1,
  1822  			expectedExplicitRoles: "",
  1823  			expectedRoles:         "channel_user channel_admin",
  1824  		},
  1825  		{
  1826  			name: "Should success to import with notifyProps",
  1827  			data: &[]UserChannelImportData{
  1828  				{
  1829  					Name:        &th.BasicChannel.Name,
  1830  					NotifyProps: &sampleNotifyProps,
  1831  				},
  1832  			},
  1833  			expectedError:         false,
  1834  			expectedUserChannels:  1,
  1835  			expectedExplicitRoles: "",
  1836  			expectedRoles:         "channel_user",
  1837  			expectedNotifyProps:   &sampleNotifyProps,
  1838  		},
  1839  		{
  1840  			name: "Should import properly multiple channels",
  1841  			data: &[]UserChannelImportData{
  1842  				{
  1843  					Name: &th.BasicChannel.Name,
  1844  				},
  1845  				{
  1846  					Name: &channel2.Name,
  1847  				},
  1848  			},
  1849  			expectedError:        false,
  1850  			expectedUserChannels: 2,
  1851  		},
  1852  	}
  1853  
  1854  	for _, tc := range tt {
  1855  		t.Run(tc.name, func(t *testing.T) {
  1856  			user := th.CreateUser()
  1857  			th.App.joinUserToTeam(th.BasicTeam, user)
  1858  			teamMember, err := th.App.GetTeamMember(th.BasicTeam.Id, user.Id)
  1859  			require.Nil(t, err)
  1860  
  1861  			// Two times import must end with the same results
  1862  			for x := 0; x < 2; x++ {
  1863  				err = th.App.importUserChannels(user, th.BasicTeam, teamMember, tc.data)
  1864  				if tc.expectedError {
  1865  					require.NotNil(t, err)
  1866  				} else {
  1867  					require.Nil(t, err)
  1868  				}
  1869  				channelMembers, err := th.App.Srv().Store.Channel().GetMembersForUser(th.BasicTeam.Id, user.Id)
  1870  				require.Nil(t, err)
  1871  				require.Len(t, *channelMembers, tc.expectedUserChannels)
  1872  				if tc.expectedUserChannels == 1 {
  1873  					channelMember := (*channelMembers)[0]
  1874  					require.Equal(t, tc.expectedExplicitRoles, channelMember.ExplicitRoles, "Not matching expected explicit roles")
  1875  					require.Equal(t, tc.expectedRoles, channelMember.Roles, "not matching expected roles")
  1876  					if tc.expectedNotifyProps != nil {
  1877  						require.Equal(t, *tc.expectedNotifyProps.Desktop, channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP])
  1878  						require.Equal(t, *tc.expectedNotifyProps.Mobile, channelMember.NotifyProps[model.PUSH_NOTIFY_PROP])
  1879  						require.Equal(t, *tc.expectedNotifyProps.MarkUnread, channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP])
  1880  					}
  1881  				}
  1882  			}
  1883  		})
  1884  	}
  1885  }
  1886  
  1887  func TestImportUserDefaultNotifyProps(t *testing.T) {
  1888  	th := Setup(t)
  1889  	defer th.TearDown()
  1890  
  1891  	// Create a valid new user with some, but not all, notify props populated.
  1892  	username := model.NewId()
  1893  	data := UserImportData{
  1894  		Username: &username,
  1895  		Email:    ptrStr(model.NewId() + "@example.com"),
  1896  		NotifyProps: &UserNotifyPropsImportData{
  1897  			Email:       ptrStr("false"),
  1898  			MentionKeys: ptrStr(""),
  1899  		},
  1900  	}
  1901  	require.Nil(t, th.App.importUser(&data, false))
  1902  
  1903  	user, err := th.App.GetUserByUsername(username)
  1904  	require.Nil(t, err)
  1905  
  1906  	// Check the value of the notify prop we specified explicitly in the import data.
  1907  	val, ok := user.NotifyProps[model.EMAIL_NOTIFY_PROP]
  1908  	assert.True(t, ok)
  1909  	assert.Equal(t, "false", val)
  1910  
  1911  	// Check all the other notify props are set to their default values.
  1912  	comparisonUser := model.User{Username: user.Username}
  1913  	comparisonUser.SetDefaultNotifications()
  1914  
  1915  	for key, expectedValue := range comparisonUser.NotifyProps {
  1916  		if key == model.EMAIL_NOTIFY_PROP {
  1917  			continue
  1918  		}
  1919  
  1920  		val, ok := user.NotifyProps[key]
  1921  		assert.True(t, ok)
  1922  		assert.Equal(t, expectedValue, val)
  1923  	}
  1924  }
  1925  
  1926  func TestImportimportMultiplePostLines(t *testing.T) {
  1927  	th := Setup(t)
  1928  	defer th.TearDown()
  1929  
  1930  	// Create a Team.
  1931  	teamName := model.NewRandomTeamName()
  1932  	th.App.importTeam(&TeamImportData{
  1933  		Name:        &teamName,
  1934  		DisplayName: ptrStr("Display Name"),
  1935  		Type:        ptrStr("O"),
  1936  	}, false)
  1937  	team, err := th.App.GetTeamByName(teamName)
  1938  	require.Nil(t, err, "Failed to get team from database.")
  1939  
  1940  	// Create a Channel.
  1941  	channelName := model.NewId()
  1942  	th.App.importChannel(&ChannelImportData{
  1943  		Team:        &teamName,
  1944  		Name:        &channelName,
  1945  		DisplayName: ptrStr("Display Name"),
  1946  		Type:        ptrStr("O"),
  1947  	}, false)
  1948  	channel, err := th.App.GetChannelByName(channelName, team.Id, false)
  1949  	require.Nil(t, err, "Failed to get channel from database.")
  1950  
  1951  	// Create a user.
  1952  	username := model.NewId()
  1953  	th.App.importUser(&UserImportData{
  1954  		Username: &username,
  1955  		Email:    ptrStr(model.NewId() + "@example.com"),
  1956  	}, false)
  1957  	user, err := th.App.GetUserByUsername(username)
  1958  	require.Nil(t, err, "Failed to get user from database.")
  1959  
  1960  	// Count the number of posts in the testing team.
  1961  	initialPostCount, err := th.App.Srv().Store.Post().AnalyticsPostCount(team.Id, false, false)
  1962  	require.Nil(t, err)
  1963  
  1964  	// Try adding an invalid post in dry run mode.
  1965  	data := LineImportWorkerData{
  1966  		LineImportData{
  1967  			Post: &PostImportData{
  1968  				Team:    &teamName,
  1969  				Channel: &channelName,
  1970  				User:    &username,
  1971  			},
  1972  		},
  1973  		25,
  1974  	}
  1975  	errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, true)
  1976  	assert.NotNil(t, err)
  1977  	assert.Equal(t, data.LineNumber, errLine)
  1978  	AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  1979  
  1980  	// Try adding a valid post in dry run mode.
  1981  	data = LineImportWorkerData{
  1982  		LineImportData{
  1983  			Post: &PostImportData{
  1984  				Team:     &teamName,
  1985  				Channel:  &channelName,
  1986  				User:     &username,
  1987  				Message:  ptrStr("Hello"),
  1988  				CreateAt: ptrInt64(model.GetMillis()),
  1989  			},
  1990  		},
  1991  		1,
  1992  	}
  1993  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, true)
  1994  	assert.Nil(t, err)
  1995  	assert.Equal(t, 0, errLine)
  1996  	AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  1997  
  1998  	// Try adding an invalid post in apply mode.
  1999  	data = LineImportWorkerData{
  2000  		LineImportData{
  2001  			Post: &PostImportData{
  2002  				Team:     &teamName,
  2003  				Channel:  &channelName,
  2004  				User:     &username,
  2005  				CreateAt: ptrInt64(model.GetMillis()),
  2006  			},
  2007  		},
  2008  		35,
  2009  	}
  2010  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2011  	assert.NotNil(t, err)
  2012  	assert.Equal(t, data.LineNumber, errLine)
  2013  	AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2014  
  2015  	// Try adding a valid post with invalid team in apply mode.
  2016  	data = LineImportWorkerData{
  2017  		LineImportData{
  2018  			Post: &PostImportData{
  2019  				Team:     ptrStr(model.NewId()),
  2020  				Channel:  &channelName,
  2021  				User:     &username,
  2022  				Message:  ptrStr("Message"),
  2023  				CreateAt: ptrInt64(model.GetMillis()),
  2024  			},
  2025  		},
  2026  		10,
  2027  	}
  2028  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2029  	assert.NotNil(t, err)
  2030  	// Batch will fail when searching for teams, so no specific line
  2031  	// is associated with the error
  2032  	assert.Equal(t, 0, errLine)
  2033  	AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2034  
  2035  	// Try adding a valid post with invalid channel in apply mode.
  2036  	data = LineImportWorkerData{
  2037  		LineImportData{
  2038  			Post: &PostImportData{
  2039  				Team:     &teamName,
  2040  				Channel:  ptrStr(model.NewId()),
  2041  				User:     &username,
  2042  				Message:  ptrStr("Message"),
  2043  				CreateAt: ptrInt64(model.GetMillis()),
  2044  			},
  2045  		},
  2046  		7,
  2047  	}
  2048  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2049  	assert.NotNil(t, err)
  2050  	// Batch will fail when searching for channels, so no specific
  2051  	// line is associated with the error
  2052  	assert.Equal(t, 0, errLine)
  2053  	AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2054  
  2055  	// Try adding a valid post with invalid user in apply mode.
  2056  	data = LineImportWorkerData{
  2057  		LineImportData{
  2058  			Post: &PostImportData{
  2059  				Team:     &teamName,
  2060  				Channel:  &channelName,
  2061  				User:     ptrStr(model.NewId()),
  2062  				Message:  ptrStr("Message"),
  2063  				CreateAt: ptrInt64(model.GetMillis()),
  2064  			},
  2065  		},
  2066  		2,
  2067  	}
  2068  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2069  	assert.NotNil(t, err)
  2070  	// Batch will fail when searching for users, so no specific line
  2071  	// is associated with the error
  2072  	assert.Equal(t, 0, errLine)
  2073  	AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2074  
  2075  	// Try adding a valid post in apply mode.
  2076  	time := model.GetMillis()
  2077  	data = LineImportWorkerData{
  2078  		LineImportData{
  2079  			Post: &PostImportData{
  2080  				Team:     &teamName,
  2081  				Channel:  &channelName,
  2082  				User:     &username,
  2083  				Message:  ptrStr("Message"),
  2084  				CreateAt: &time,
  2085  			},
  2086  		},
  2087  		1,
  2088  	}
  2089  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2090  	assert.Nil(t, err)
  2091  	assert.Equal(t, 0, errLine)
  2092  	AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id)
  2093  
  2094  	// Check the post values.
  2095  	posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, time)
  2096  	require.Nil(t, err)
  2097  
  2098  	require.Len(t, posts, 1, "Unexpected number of posts found.")
  2099  
  2100  	post := posts[0]
  2101  	postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2102  	require.False(t, postBool, "Post properties not as expected")
  2103  
  2104  	// Update the post.
  2105  	data = LineImportWorkerData{
  2106  		LineImportData{
  2107  			Post: &PostImportData{
  2108  				Team:     &teamName,
  2109  				Channel:  &channelName,
  2110  				User:     &username,
  2111  				Message:  ptrStr("Message"),
  2112  				CreateAt: &time,
  2113  			},
  2114  		},
  2115  		1,
  2116  	}
  2117  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2118  	assert.Nil(t, err)
  2119  	assert.Equal(t, 0, errLine)
  2120  	AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id)
  2121  
  2122  	// Check the post values.
  2123  	posts, err = th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, time)
  2124  	require.Nil(t, err)
  2125  
  2126  	require.Len(t, posts, 1, "Unexpected number of posts found.")
  2127  
  2128  	post = posts[0]
  2129  	postBool = post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2130  	require.False(t, postBool, "Post properties not as expected")
  2131  
  2132  	// Save the post with a different time.
  2133  	newTime := time + 1
  2134  	data = LineImportWorkerData{
  2135  		LineImportData{
  2136  			Post: &PostImportData{
  2137  				Team:     &teamName,
  2138  				Channel:  &channelName,
  2139  				User:     &username,
  2140  				Message:  ptrStr("Message"),
  2141  				CreateAt: &newTime,
  2142  			},
  2143  		},
  2144  		1,
  2145  	}
  2146  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2147  	assert.Nil(t, err)
  2148  	assert.Equal(t, 0, errLine)
  2149  	AssertAllPostsCount(t, th.App, initialPostCount, 2, team.Id)
  2150  
  2151  	// Save the post with a different message.
  2152  	data = LineImportWorkerData{
  2153  		LineImportData{
  2154  			Post: &PostImportData{
  2155  				Team:     &teamName,
  2156  				Channel:  &channelName,
  2157  				User:     &username,
  2158  				Message:  ptrStr("Message 2"),
  2159  				CreateAt: &time,
  2160  			},
  2161  		},
  2162  		1,
  2163  	}
  2164  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2165  	assert.Nil(t, err)
  2166  	assert.Equal(t, 0, errLine)
  2167  	AssertAllPostsCount(t, th.App, initialPostCount, 3, team.Id)
  2168  
  2169  	// Test with hashtags
  2170  	hashtagTime := time + 2
  2171  	data = LineImportWorkerData{
  2172  		LineImportData{
  2173  			Post: &PostImportData{
  2174  				Team:     &teamName,
  2175  				Channel:  &channelName,
  2176  				User:     &username,
  2177  				Message:  ptrStr("Message 2 #hashtagmashupcity"),
  2178  				CreateAt: &hashtagTime,
  2179  			},
  2180  		},
  2181  		1,
  2182  	}
  2183  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2184  	assert.Nil(t, err)
  2185  	assert.Equal(t, 0, errLine)
  2186  	AssertAllPostsCount(t, th.App, initialPostCount, 4, team.Id)
  2187  
  2188  	posts, err = th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, hashtagTime)
  2189  	require.Nil(t, err)
  2190  
  2191  	require.Len(t, posts, 1, "Unexpected number of posts found.")
  2192  
  2193  	post = posts[0]
  2194  	postBool = post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2195  	require.False(t, postBool, "Post properties not as expected")
  2196  
  2197  	require.Equal(t, "#hashtagmashupcity", post.Hashtags, "Hashtags not as expected: %s", post.Hashtags)
  2198  
  2199  	// Post with flags.
  2200  	username2 := model.NewId()
  2201  	th.App.importUser(&UserImportData{
  2202  		Username: &username2,
  2203  		Email:    ptrStr(model.NewId() + "@example.com"),
  2204  	}, false)
  2205  	user2, err := th.App.GetUserByUsername(username2)
  2206  	require.Nil(t, err, "Failed to get user from database.")
  2207  
  2208  	flagsTime := hashtagTime + 1
  2209  	data = LineImportWorkerData{
  2210  		LineImportData{
  2211  			Post: &PostImportData{
  2212  				Team:     &teamName,
  2213  				Channel:  &channelName,
  2214  				User:     &username,
  2215  				Message:  ptrStr("Message with Favorites"),
  2216  				CreateAt: &flagsTime,
  2217  				FlaggedBy: &[]string{
  2218  					username,
  2219  					username2,
  2220  				},
  2221  			},
  2222  		},
  2223  		1,
  2224  	}
  2225  
  2226  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2227  	assert.Nil(t, err, "Expected success.")
  2228  	assert.Equal(t, 0, errLine)
  2229  
  2230  	AssertAllPostsCount(t, th.App, initialPostCount, 5, team.Id)
  2231  
  2232  	// Check the post values.
  2233  	posts, err = th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, flagsTime)
  2234  	require.Nil(t, err)
  2235  
  2236  	require.Len(t, posts, 1, "Unexpected number of posts found.")
  2237  
  2238  	post = posts[0]
  2239  	postBool = post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2240  	require.False(t, postBool, "Post properties not as expected")
  2241  
  2242  	checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  2243  	checkPreference(t, th.App, user2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  2244  
  2245  	// Post with reaction.
  2246  	reactionPostTime := hashtagTime + 2
  2247  	reactionTime := hashtagTime + 3
  2248  	data = LineImportWorkerData{
  2249  		LineImportData{
  2250  			Post: &PostImportData{
  2251  				Team:     &teamName,
  2252  				Channel:  &channelName,
  2253  				User:     &username,
  2254  				Message:  ptrStr("Message with reaction"),
  2255  				CreateAt: &reactionPostTime,
  2256  				Reactions: &[]ReactionImportData{{
  2257  					User:      &user2.Username,
  2258  					EmojiName: ptrStr("+1"),
  2259  					CreateAt:  &reactionTime,
  2260  				}},
  2261  			},
  2262  		},
  2263  		1,
  2264  	}
  2265  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2266  	assert.Nil(t, err, "Expected success.")
  2267  	assert.Equal(t, 0, errLine)
  2268  
  2269  	AssertAllPostsCount(t, th.App, initialPostCount, 6, team.Id)
  2270  
  2271  	// Check the post values.
  2272  	posts, err = th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, reactionPostTime)
  2273  	require.Nil(t, err)
  2274  
  2275  	require.Len(t, posts, 1, "Unexpected number of posts found.")
  2276  
  2277  	post = posts[0]
  2278  	postBool = post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id || !post.HasReactions
  2279  	require.False(t, postBool, "Post properties not as expected")
  2280  
  2281  	reactions, nErr := th.App.Srv().Store.Reaction().GetForPost(post.Id, false)
  2282  	require.Nil(t, nErr, "Can't get reaction")
  2283  
  2284  	require.Len(t, reactions, 1, "Invalid number of reactions")
  2285  
  2286  	// Post with reply.
  2287  	replyPostTime := hashtagTime + 4
  2288  	replyTime := hashtagTime + 5
  2289  	data = LineImportWorkerData{
  2290  		LineImportData{
  2291  			Post: &PostImportData{
  2292  				Team:     &teamName,
  2293  				Channel:  &channelName,
  2294  				User:     &username,
  2295  				Message:  ptrStr("Message with reply"),
  2296  				CreateAt: &replyPostTime,
  2297  				Replies: &[]ReplyImportData{{
  2298  					User:     &user2.Username,
  2299  					Message:  ptrStr("Message reply"),
  2300  					CreateAt: &replyTime,
  2301  				}},
  2302  			},
  2303  		},
  2304  		1,
  2305  	}
  2306  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2307  	assert.Nil(t, err, "Expected success.")
  2308  	assert.Equal(t, 0, errLine)
  2309  
  2310  	AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id)
  2311  
  2312  	// Check the post values.
  2313  	posts, err = th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, replyPostTime)
  2314  	require.Nil(t, err)
  2315  
  2316  	require.Len(t, posts, 1, "Unexpected number of posts found.")
  2317  
  2318  	post = posts[0]
  2319  	postBool = post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2320  	require.False(t, postBool, "Post properties not as expected")
  2321  
  2322  	// Check the reply values.
  2323  	replies, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, replyTime)
  2324  	require.Nil(t, err)
  2325  
  2326  	require.Len(t, replies, 1, "Unexpected number of posts found.")
  2327  
  2328  	reply := replies[0]
  2329  	replyBool := reply.Message != *(*data.Post.Replies)[0].Message || reply.CreateAt != *(*data.Post.Replies)[0].CreateAt || reply.UserId != user2.Id
  2330  	require.False(t, replyBool, "Post properties not as expected")
  2331  
  2332  	require.Equal(t, post.Id, reply.RootId, "Unexpected reply RootId")
  2333  
  2334  	// Update post with replies.
  2335  	data = LineImportWorkerData{
  2336  		LineImportData{
  2337  			Post: &PostImportData{
  2338  				Team:     &teamName,
  2339  				Channel:  &channelName,
  2340  				User:     &user2.Username,
  2341  				Message:  ptrStr("Message with reply"),
  2342  				CreateAt: &replyPostTime,
  2343  				Replies: &[]ReplyImportData{{
  2344  					User:     &username,
  2345  					Message:  ptrStr("Message reply"),
  2346  					CreateAt: &replyTime,
  2347  				}},
  2348  			},
  2349  		},
  2350  		1,
  2351  	}
  2352  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2353  	assert.Nil(t, err, "Expected success.")
  2354  	assert.Equal(t, 0, errLine)
  2355  
  2356  	AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id)
  2357  
  2358  	// Create new post with replies based on the previous one.
  2359  	data = LineImportWorkerData{
  2360  		LineImportData{
  2361  			Post: &PostImportData{
  2362  				Team:     &teamName,
  2363  				Channel:  &channelName,
  2364  				User:     &user2.Username,
  2365  				Message:  ptrStr("Message with reply 2"),
  2366  				CreateAt: &replyPostTime,
  2367  				Replies: &[]ReplyImportData{{
  2368  					User:     &username,
  2369  					Message:  ptrStr("Message reply"),
  2370  					CreateAt: &replyTime,
  2371  				}},
  2372  			},
  2373  		},
  2374  		1,
  2375  	}
  2376  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2377  	assert.Nil(t, err, "Expected success.")
  2378  	assert.Equal(t, 0, errLine)
  2379  
  2380  	AssertAllPostsCount(t, th.App, initialPostCount, 10, team.Id)
  2381  
  2382  	// Create new reply for existing post with replies.
  2383  	data = LineImportWorkerData{
  2384  		LineImportData{
  2385  			Post: &PostImportData{
  2386  				Team:     &teamName,
  2387  				Channel:  &channelName,
  2388  				User:     &user2.Username,
  2389  				Message:  ptrStr("Message with reply"),
  2390  				CreateAt: &replyPostTime,
  2391  				Replies: &[]ReplyImportData{{
  2392  					User:     &username,
  2393  					Message:  ptrStr("Message reply 2"),
  2394  					CreateAt: &replyTime,
  2395  				}},
  2396  			},
  2397  		},
  2398  		1,
  2399  	}
  2400  	errLine, err = th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2401  	assert.Nil(t, err, "Expected success.")
  2402  	assert.Equal(t, 0, errLine)
  2403  
  2404  	AssertAllPostsCount(t, th.App, initialPostCount, 11, team.Id)
  2405  }
  2406  
  2407  func TestImportImportPost(t *testing.T) {
  2408  	th := Setup(t)
  2409  	defer th.TearDown()
  2410  
  2411  	// Create a Team.
  2412  	teamName := model.NewRandomTeamName()
  2413  	th.App.importTeam(&TeamImportData{
  2414  		Name:        &teamName,
  2415  		DisplayName: ptrStr("Display Name"),
  2416  		Type:        ptrStr("O"),
  2417  	}, false)
  2418  	team, appErr := th.App.GetTeamByName(teamName)
  2419  	require.Nil(t, appErr, "Failed to get team from database.")
  2420  
  2421  	// Create a Channel.
  2422  	channelName := model.NewId()
  2423  	th.App.importChannel(&ChannelImportData{
  2424  		Team:        &teamName,
  2425  		Name:        &channelName,
  2426  		DisplayName: ptrStr("Display Name"),
  2427  		Type:        ptrStr("O"),
  2428  	}, false)
  2429  	channel, appErr := th.App.GetChannelByName(channelName, team.Id, false)
  2430  	require.Nil(t, appErr, "Failed to get channel from database.")
  2431  
  2432  	// Create a user.
  2433  	username := model.NewId()
  2434  	th.App.importUser(&UserImportData{
  2435  		Username: &username,
  2436  		Email:    ptrStr(model.NewId() + "@example.com"),
  2437  	}, false)
  2438  	user, appErr := th.App.GetUserByUsername(username)
  2439  	require.Nil(t, appErr, "Failed to get user from database.")
  2440  
  2441  	username2 := model.NewId()
  2442  	th.App.importUser(&UserImportData{
  2443  		Username: &username2,
  2444  		Email:    ptrStr(model.NewId() + "@example.com"),
  2445  	}, false)
  2446  	user2, appErr := th.App.GetUserByUsername(username2)
  2447  	require.Nil(t, appErr, "Failed to get user from database.")
  2448  
  2449  	// Count the number of posts in the testing team.
  2450  	initialPostCount, appErr := th.App.Srv().Store.Post().AnalyticsPostCount(team.Id, false, false)
  2451  	require.Nil(t, appErr)
  2452  
  2453  	time := model.GetMillis()
  2454  	hashtagTime := time + 2
  2455  	replyPostTime := hashtagTime + 4
  2456  	replyTime := hashtagTime + 5
  2457  
  2458  	t.Run("Try adding an invalid post in dry run mode", func(t *testing.T) {
  2459  		data := LineImportWorkerData{
  2460  			LineImportData{
  2461  				Post: &PostImportData{
  2462  					Team:    &teamName,
  2463  					Channel: &channelName,
  2464  					User:    &username,
  2465  				},
  2466  			},
  2467  			12,
  2468  		}
  2469  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, true)
  2470  		assert.NotNil(t, err)
  2471  		assert.Equal(t, data.LineNumber, errLine)
  2472  		AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2473  	})
  2474  
  2475  	t.Run("Try adding a valid post in dry run mode", func(t *testing.T) {
  2476  		data := LineImportWorkerData{
  2477  			LineImportData{
  2478  				Post: &PostImportData{
  2479  					Team:     &teamName,
  2480  					Channel:  &channelName,
  2481  					User:     &username,
  2482  					Message:  ptrStr("Hello"),
  2483  					CreateAt: ptrInt64(model.GetMillis()),
  2484  				},
  2485  			},
  2486  			1,
  2487  		}
  2488  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, true)
  2489  		assert.Nil(t, err)
  2490  		assert.Equal(t, 0, errLine)
  2491  		AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2492  	})
  2493  
  2494  	t.Run("Try adding an invalid post in apply mode", func(t *testing.T) {
  2495  		data := LineImportWorkerData{
  2496  			LineImportData{
  2497  				Post: &PostImportData{
  2498  					Team:     &teamName,
  2499  					Channel:  &channelName,
  2500  					User:     &username,
  2501  					CreateAt: ptrInt64(model.GetMillis()),
  2502  				},
  2503  			},
  2504  			2,
  2505  		}
  2506  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2507  		assert.NotNil(t, err)
  2508  		assert.Equal(t, data.LineNumber, errLine)
  2509  		AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2510  	})
  2511  
  2512  	t.Run("Try adding a valid post with invalid team in apply mode", func(t *testing.T) {
  2513  		data := LineImportWorkerData{
  2514  			LineImportData{
  2515  				Post: &PostImportData{
  2516  					Team:     ptrStr(model.NewId()),
  2517  					Channel:  &channelName,
  2518  					User:     &username,
  2519  					Message:  ptrStr("Message"),
  2520  					CreateAt: ptrInt64(model.GetMillis()),
  2521  				},
  2522  			},
  2523  			7,
  2524  		}
  2525  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2526  		assert.NotNil(t, err)
  2527  		assert.Equal(t, 0, errLine)
  2528  		AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2529  	})
  2530  
  2531  	t.Run("Try adding a valid post with invalid channel in apply mode", func(t *testing.T) {
  2532  		data := LineImportWorkerData{
  2533  			LineImportData{
  2534  				Post: &PostImportData{
  2535  					Team:     &teamName,
  2536  					Channel:  ptrStr(model.NewId()),
  2537  					User:     &username,
  2538  					Message:  ptrStr("Message"),
  2539  					CreateAt: ptrInt64(model.GetMillis()),
  2540  				},
  2541  			},
  2542  			8,
  2543  		}
  2544  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2545  		assert.NotNil(t, err)
  2546  		assert.Equal(t, 0, errLine)
  2547  		AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2548  	})
  2549  
  2550  	t.Run("Try adding a valid post with invalid user in apply mode", func(t *testing.T) {
  2551  		data := LineImportWorkerData{
  2552  			LineImportData{
  2553  				Post: &PostImportData{
  2554  					Team:     &teamName,
  2555  					Channel:  &channelName,
  2556  					User:     ptrStr(model.NewId()),
  2557  					Message:  ptrStr("Message"),
  2558  					CreateAt: ptrInt64(model.GetMillis()),
  2559  				},
  2560  			},
  2561  			9,
  2562  		}
  2563  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2564  		assert.NotNil(t, err)
  2565  		assert.Equal(t, 0, errLine)
  2566  		AssertAllPostsCount(t, th.App, initialPostCount, 0, team.Id)
  2567  	})
  2568  
  2569  	t.Run("Try adding a valid post in apply mode", func(t *testing.T) {
  2570  		data := LineImportWorkerData{
  2571  			LineImportData{
  2572  				Post: &PostImportData{
  2573  					Team:     &teamName,
  2574  					Channel:  &channelName,
  2575  					User:     &username,
  2576  					Message:  ptrStr("Message"),
  2577  					CreateAt: &time,
  2578  				},
  2579  			},
  2580  			1,
  2581  		}
  2582  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2583  		assert.Nil(t, err)
  2584  		assert.Equal(t, 0, errLine)
  2585  		AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id)
  2586  
  2587  		// Check the post values.
  2588  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, time)
  2589  		require.Nil(t, err)
  2590  
  2591  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  2592  
  2593  		post := posts[0]
  2594  		postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2595  		require.False(t, postBool, "Post properties not as expected")
  2596  	})
  2597  
  2598  	t.Run("Update the post", func(t *testing.T) {
  2599  		data := LineImportWorkerData{
  2600  			LineImportData{
  2601  				Post: &PostImportData{
  2602  					Team:     &teamName,
  2603  					Channel:  &channelName,
  2604  					User:     &username2,
  2605  					Message:  ptrStr("Message"),
  2606  					CreateAt: &time,
  2607  				},
  2608  			},
  2609  			1,
  2610  		}
  2611  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2612  		assert.Nil(t, err)
  2613  		assert.Equal(t, 0, errLine)
  2614  		AssertAllPostsCount(t, th.App, initialPostCount, 1, team.Id)
  2615  
  2616  		// Check the post values.
  2617  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, time)
  2618  		require.Nil(t, err)
  2619  
  2620  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  2621  
  2622  		post := posts[0]
  2623  		postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user2.Id
  2624  		require.False(t, postBool, "Post properties not as expected")
  2625  	})
  2626  
  2627  	t.Run("Save the post with a different time", func(t *testing.T) {
  2628  		newTime := time + 1
  2629  		data := LineImportWorkerData{
  2630  			LineImportData{
  2631  				Post: &PostImportData{
  2632  					Team:     &teamName,
  2633  					Channel:  &channelName,
  2634  					User:     &username,
  2635  					Message:  ptrStr("Message"),
  2636  					CreateAt: &newTime,
  2637  				},
  2638  			},
  2639  			1,
  2640  		}
  2641  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2642  		assert.Nil(t, err)
  2643  		assert.Equal(t, 0, errLine)
  2644  		AssertAllPostsCount(t, th.App, initialPostCount, 2, team.Id)
  2645  	})
  2646  
  2647  	t.Run("Save the post with a different message", func(t *testing.T) {
  2648  		data := LineImportWorkerData{
  2649  			LineImportData{
  2650  				Post: &PostImportData{
  2651  					Team:     &teamName,
  2652  					Channel:  &channelName,
  2653  					User:     &username,
  2654  					Message:  ptrStr("Message 2"),
  2655  					CreateAt: &time,
  2656  				},
  2657  			},
  2658  			1,
  2659  		}
  2660  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2661  		assert.Nil(t, err)
  2662  		assert.Equal(t, 0, errLine)
  2663  		AssertAllPostsCount(t, th.App, initialPostCount, 3, team.Id)
  2664  	})
  2665  
  2666  	t.Run("Test with hashtag", func(t *testing.T) {
  2667  		data := LineImportWorkerData{
  2668  			LineImportData{
  2669  				Post: &PostImportData{
  2670  					Team:     &teamName,
  2671  					Channel:  &channelName,
  2672  					User:     &username,
  2673  					Message:  ptrStr("Message 2 #hashtagmashupcity"),
  2674  					CreateAt: &hashtagTime,
  2675  				},
  2676  			},
  2677  			1,
  2678  		}
  2679  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2680  		assert.Nil(t, err)
  2681  		assert.Equal(t, 0, errLine)
  2682  		AssertAllPostsCount(t, th.App, initialPostCount, 4, team.Id)
  2683  
  2684  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, hashtagTime)
  2685  		require.Nil(t, err)
  2686  
  2687  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  2688  
  2689  		post := posts[0]
  2690  		postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2691  		require.False(t, postBool, "Post properties not as expected")
  2692  
  2693  		require.Equal(t, "#hashtagmashupcity", post.Hashtags, "Hashtags not as expected: %s", post.Hashtags)
  2694  	})
  2695  
  2696  	t.Run("Post with flags", func(t *testing.T) {
  2697  		flagsTime := hashtagTime + 1
  2698  		data := LineImportWorkerData{
  2699  			LineImportData{
  2700  				Post: &PostImportData{
  2701  					Team:     &teamName,
  2702  					Channel:  &channelName,
  2703  					User:     &username,
  2704  					Message:  ptrStr("Message with Favorites"),
  2705  					CreateAt: &flagsTime,
  2706  					FlaggedBy: &[]string{
  2707  						username,
  2708  						username2,
  2709  					},
  2710  				},
  2711  			},
  2712  			1,
  2713  		}
  2714  
  2715  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2716  		require.Nil(t, err, "Expected success.")
  2717  		require.Equal(t, 0, errLine)
  2718  
  2719  		AssertAllPostsCount(t, th.App, initialPostCount, 5, team.Id)
  2720  
  2721  		// Check the post values.
  2722  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, flagsTime)
  2723  		require.Nil(t, err)
  2724  
  2725  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  2726  
  2727  		post := posts[0]
  2728  		postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2729  		require.False(t, postBool, "Post properties not as expected")
  2730  
  2731  		checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  2732  		checkPreference(t, th.App, user2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  2733  	})
  2734  
  2735  	t.Run("Post with reaction", func(t *testing.T) {
  2736  		reactionPostTime := hashtagTime + 2
  2737  		reactionTime := hashtagTime + 3
  2738  		data := LineImportWorkerData{
  2739  			LineImportData{
  2740  				Post: &PostImportData{
  2741  					Team:     &teamName,
  2742  					Channel:  &channelName,
  2743  					User:     &username,
  2744  					Message:  ptrStr("Message with reaction"),
  2745  					CreateAt: &reactionPostTime,
  2746  					Reactions: &[]ReactionImportData{{
  2747  						User:      &user2.Username,
  2748  						EmojiName: ptrStr("+1"),
  2749  						CreateAt:  &reactionTime,
  2750  					}},
  2751  				},
  2752  			},
  2753  			1,
  2754  		}
  2755  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2756  		require.Nil(t, err, "Expected success.")
  2757  		require.Equal(t, 0, errLine)
  2758  
  2759  		AssertAllPostsCount(t, th.App, initialPostCount, 6, team.Id)
  2760  
  2761  		// Check the post values.
  2762  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, reactionPostTime)
  2763  		require.Nil(t, err)
  2764  
  2765  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  2766  
  2767  		post := posts[0]
  2768  		postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id || !post.HasReactions
  2769  		require.False(t, postBool, "Post properties not as expected")
  2770  
  2771  		reactions, nErr := th.App.Srv().Store.Reaction().GetForPost(post.Id, false)
  2772  		require.Nil(t, nErr, "Can't get reaction")
  2773  
  2774  		require.Len(t, reactions, 1, "Invalid number of reactions")
  2775  	})
  2776  
  2777  	t.Run("Post with reply", func(t *testing.T) {
  2778  		data := LineImportWorkerData{
  2779  			LineImportData{
  2780  				Post: &PostImportData{
  2781  					Team:     &teamName,
  2782  					Channel:  &channelName,
  2783  					User:     &username,
  2784  					Message:  ptrStr("Message with reply"),
  2785  					CreateAt: &replyPostTime,
  2786  					Replies: &[]ReplyImportData{{
  2787  						User:     &user2.Username,
  2788  						Message:  ptrStr("Message reply"),
  2789  						CreateAt: &replyTime,
  2790  					}},
  2791  				},
  2792  			},
  2793  			1,
  2794  		}
  2795  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2796  		require.Nil(t, err, "Expected success.")
  2797  		require.Equal(t, 0, errLine)
  2798  
  2799  		AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id)
  2800  
  2801  		// Check the post values.
  2802  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, replyPostTime)
  2803  		require.Nil(t, err)
  2804  
  2805  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  2806  
  2807  		post := posts[0]
  2808  		postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id
  2809  		require.False(t, postBool, "Post properties not as expected")
  2810  
  2811  		// Check the reply values.
  2812  		replies, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, replyTime)
  2813  		require.Nil(t, err)
  2814  
  2815  		require.Len(t, replies, 1, "Unexpected number of posts found.")
  2816  
  2817  		reply := replies[0]
  2818  		replyBool := reply.Message != *(*data.Post.Replies)[0].Message || reply.CreateAt != *(*data.Post.Replies)[0].CreateAt || reply.UserId != user2.Id
  2819  		require.False(t, replyBool, "Post properties not as expected")
  2820  
  2821  		require.Equal(t, post.Id, reply.RootId, "Unexpected reply RootId")
  2822  	})
  2823  
  2824  	t.Run("Update post with replies", func(t *testing.T) {
  2825  		data := LineImportWorkerData{
  2826  			LineImportData{
  2827  				Post: &PostImportData{
  2828  					Team:     &teamName,
  2829  					Channel:  &channelName,
  2830  					User:     &user2.Username,
  2831  					Message:  ptrStr("Message with reply"),
  2832  					CreateAt: &replyPostTime,
  2833  					Replies: &[]ReplyImportData{{
  2834  						User:     &username,
  2835  						Message:  ptrStr("Message reply"),
  2836  						CreateAt: &replyTime,
  2837  					}},
  2838  				},
  2839  			},
  2840  			1,
  2841  		}
  2842  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2843  		require.Nil(t, err, "Expected success.")
  2844  		require.Equal(t, 0, errLine)
  2845  
  2846  		AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id)
  2847  	})
  2848  
  2849  	t.Run("Create new post with replies based on the previous one", func(t *testing.T) {
  2850  		data := LineImportWorkerData{
  2851  			LineImportData{
  2852  				Post: &PostImportData{
  2853  					Team:     &teamName,
  2854  					Channel:  &channelName,
  2855  					User:     &user2.Username,
  2856  					Message:  ptrStr("Message with reply 2"),
  2857  					CreateAt: &replyPostTime,
  2858  					Replies: &[]ReplyImportData{{
  2859  						User:     &username,
  2860  						Message:  ptrStr("Message reply"),
  2861  						CreateAt: &replyTime,
  2862  					}},
  2863  				},
  2864  			},
  2865  			1,
  2866  		}
  2867  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2868  		require.Nil(t, err, "Expected success.")
  2869  		require.Equal(t, 0, errLine)
  2870  
  2871  		AssertAllPostsCount(t, th.App, initialPostCount, 10, team.Id)
  2872  	})
  2873  
  2874  	t.Run("Create new reply for existing post with replies", func(t *testing.T) {
  2875  		data := LineImportWorkerData{
  2876  			LineImportData{
  2877  				Post: &PostImportData{
  2878  					Team:     &teamName,
  2879  					Channel:  &channelName,
  2880  					User:     &user2.Username,
  2881  					Message:  ptrStr("Message with reply"),
  2882  					CreateAt: &replyPostTime,
  2883  					Replies: &[]ReplyImportData{{
  2884  						User:     &username,
  2885  						Message:  ptrStr("Message reply 2"),
  2886  						CreateAt: &replyTime,
  2887  					}},
  2888  				},
  2889  			},
  2890  			1,
  2891  		}
  2892  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  2893  		require.Nil(t, err, "Expected success.")
  2894  		require.Equal(t, 0, errLine)
  2895  
  2896  		AssertAllPostsCount(t, th.App, initialPostCount, 11, team.Id)
  2897  	})
  2898  }
  2899  
  2900  func TestImportImportDirectChannel(t *testing.T) {
  2901  	th := Setup(t).InitBasic()
  2902  	defer th.TearDown()
  2903  
  2904  	// Check how many channels are in the database.
  2905  	directChannelCount, err := th.App.Srv().Store.Channel().AnalyticsTypeCount("", model.CHANNEL_DIRECT)
  2906  	require.Nil(t, err, "Failed to get direct channel count.")
  2907  
  2908  	groupChannelCount, err := th.App.Srv().Store.Channel().AnalyticsTypeCount("", model.CHANNEL_GROUP)
  2909  	require.Nil(t, err, "Failed to get group channel count.")
  2910  
  2911  	// Do an invalid channel in dry-run mode.
  2912  	data := DirectChannelImportData{
  2913  		Members: &[]string{
  2914  			model.NewId(),
  2915  		},
  2916  		Header: ptrStr("Channel Header"),
  2917  	}
  2918  	err = th.App.importDirectChannel(&data, true)
  2919  	require.NotNil(t, err)
  2920  
  2921  	// Check that no more channels are in the DB.
  2922  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
  2923  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2924  
  2925  	// Do a valid DIRECT channel with a nonexistent member in dry-run mode.
  2926  	data.Members = &[]string{
  2927  		model.NewId(),
  2928  		model.NewId(),
  2929  	}
  2930  	err = th.App.importDirectChannel(&data, true)
  2931  	require.Nil(t, err)
  2932  
  2933  	// Check that no more channels are in the DB.
  2934  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
  2935  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2936  
  2937  	// Do a valid GROUP channel with a nonexistent member in dry-run mode.
  2938  	data.Members = &[]string{
  2939  		model.NewId(),
  2940  		model.NewId(),
  2941  		model.NewId(),
  2942  	}
  2943  	err = th.App.importDirectChannel(&data, true)
  2944  	require.Nil(t, err)
  2945  
  2946  	// Check that no more channels are in the DB.
  2947  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
  2948  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2949  
  2950  	// Do an invalid channel in apply mode.
  2951  	data.Members = &[]string{
  2952  		model.NewId(),
  2953  	}
  2954  	err = th.App.importDirectChannel(&data, false)
  2955  	require.NotNil(t, err)
  2956  
  2957  	// Check that no more channels are in the DB.
  2958  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount)
  2959  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2960  
  2961  	// Do a valid DIRECT channel.
  2962  	data.Members = &[]string{
  2963  		th.BasicUser.Username,
  2964  		th.BasicUser2.Username,
  2965  	}
  2966  	err = th.App.importDirectChannel(&data, false)
  2967  	require.Nil(t, err)
  2968  
  2969  	// Check that one more DIRECT channel is in the DB.
  2970  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  2971  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2972  
  2973  	// Do the same DIRECT channel again.
  2974  	err = th.App.importDirectChannel(&data, false)
  2975  	require.Nil(t, err)
  2976  
  2977  	// Check that no more channels are in the DB.
  2978  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  2979  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2980  
  2981  	// Update the channel's HEADER
  2982  	data.Header = ptrStr("New Channel Header 2")
  2983  	err = th.App.importDirectChannel(&data, false)
  2984  	require.Nil(t, err)
  2985  
  2986  	// Check that no more channels are in the DB.
  2987  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  2988  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  2989  
  2990  	// Get the channel to check that the header was updated.
  2991  	channel, err := th.App.GetOrCreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id)
  2992  	require.Nil(t, err)
  2993  	require.Equal(t, channel.Header, *data.Header)
  2994  
  2995  	// Do a GROUP channel with an extra invalid member.
  2996  	user3 := th.CreateUser()
  2997  	data.Members = &[]string{
  2998  		th.BasicUser.Username,
  2999  		th.BasicUser2.Username,
  3000  		user3.Username,
  3001  		model.NewId(),
  3002  	}
  3003  	err = th.App.importDirectChannel(&data, false)
  3004  	require.NotNil(t, err)
  3005  
  3006  	// Check that no more channels are in the DB.
  3007  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  3008  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount)
  3009  
  3010  	// Do a valid GROUP channel.
  3011  	data.Members = &[]string{
  3012  		th.BasicUser.Username,
  3013  		th.BasicUser2.Username,
  3014  		user3.Username,
  3015  	}
  3016  	err = th.App.importDirectChannel(&data, false)
  3017  	require.Nil(t, err)
  3018  
  3019  	// Check that one more GROUP channel is in the DB.
  3020  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  3021  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1)
  3022  
  3023  	// Do the same DIRECT channel again.
  3024  	err = th.App.importDirectChannel(&data, false)
  3025  	require.Nil(t, err)
  3026  
  3027  	// Check that no more channels are in the DB.
  3028  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  3029  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1)
  3030  
  3031  	// Update the channel's HEADER
  3032  	data.Header = ptrStr("New Channel Header 3")
  3033  	err = th.App.importDirectChannel(&data, false)
  3034  	require.Nil(t, err)
  3035  
  3036  	// Check that no more channels are in the DB.
  3037  	AssertChannelCount(t, th.App, model.CHANNEL_DIRECT, directChannelCount+1)
  3038  	AssertChannelCount(t, th.App, model.CHANNEL_GROUP, groupChannelCount+1)
  3039  
  3040  	// Get the channel to check that the header was updated.
  3041  	userIds := []string{
  3042  		th.BasicUser.Id,
  3043  		th.BasicUser2.Id,
  3044  		user3.Id,
  3045  	}
  3046  	channel, err = th.App.createGroupChannel(userIds, th.BasicUser.Id)
  3047  	require.Equal(t, err.Id, store.CHANNEL_EXISTS_ERROR)
  3048  	require.Equal(t, channel.Header, *data.Header)
  3049  
  3050  	// Import a channel with some favorites.
  3051  	data.Members = &[]string{
  3052  		th.BasicUser.Username,
  3053  		th.BasicUser2.Username,
  3054  	}
  3055  	data.FavoritedBy = &[]string{
  3056  		th.BasicUser.Username,
  3057  		th.BasicUser2.Username,
  3058  	}
  3059  	err = th.App.importDirectChannel(&data, false)
  3060  	require.Nil(t, err)
  3061  
  3062  	channel, err = th.App.GetOrCreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id)
  3063  	require.Nil(t, err)
  3064  	checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true")
  3065  	checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, channel.Id, "true")
  3066  }
  3067  
  3068  func TestImportImportDirectPost(t *testing.T) {
  3069  	th := Setup(t).InitBasic()
  3070  	defer th.TearDown()
  3071  
  3072  	// Create the DIRECT channel.
  3073  	channelData := DirectChannelImportData{
  3074  		Members: &[]string{
  3075  			th.BasicUser.Username,
  3076  			th.BasicUser2.Username,
  3077  		},
  3078  	}
  3079  	appErr := th.App.importDirectChannel(&channelData, false)
  3080  	require.Nil(t, appErr)
  3081  
  3082  	// Get the channel.
  3083  	var directChannel *model.Channel
  3084  	channel, appErr := th.App.GetOrCreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id)
  3085  	require.Nil(t, appErr)
  3086  	require.NotEmpty(t, channel)
  3087  	directChannel = channel
  3088  
  3089  	// Get the number of posts in the system.
  3090  	result, appErr := th.App.Srv().Store.Post().AnalyticsPostCount("", false, false)
  3091  	require.Nil(t, appErr)
  3092  	initialPostCount := result
  3093  	initialDate := model.GetMillis()
  3094  
  3095  	t.Run("Try adding an invalid post in dry run mode", func(t *testing.T) {
  3096  		data := LineImportWorkerData{
  3097  			LineImportData{
  3098  				DirectPost: &DirectPostImportData{
  3099  					ChannelMembers: &[]string{
  3100  						th.BasicUser.Username,
  3101  						th.BasicUser2.Username,
  3102  					},
  3103  					User:     ptrStr(th.BasicUser.Username),
  3104  					CreateAt: ptrInt64(model.GetMillis()),
  3105  				},
  3106  			},
  3107  			7,
  3108  		}
  3109  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, true)
  3110  		require.NotNil(t, err)
  3111  		require.Equal(t, data.LineNumber, errLine)
  3112  		AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
  3113  	})
  3114  
  3115  	t.Run("Try adding a valid post in dry run mode", func(t *testing.T) {
  3116  		data := LineImportWorkerData{
  3117  			LineImportData{
  3118  				DirectPost: &DirectPostImportData{
  3119  					ChannelMembers: &[]string{
  3120  						th.BasicUser.Username,
  3121  						th.BasicUser2.Username,
  3122  					},
  3123  					User:     ptrStr(th.BasicUser.Username),
  3124  					Message:  ptrStr("Message"),
  3125  					CreateAt: ptrInt64(model.GetMillis()),
  3126  				},
  3127  			},
  3128  			1,
  3129  		}
  3130  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, true)
  3131  		require.Nil(t, err)
  3132  		require.Equal(t, 0, errLine)
  3133  		AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
  3134  	})
  3135  
  3136  	t.Run("Try adding an invalid post in apply mode", func(t *testing.T) {
  3137  		data := LineImportWorkerData{
  3138  			LineImportData{
  3139  				DirectPost: &DirectPostImportData{
  3140  					ChannelMembers: &[]string{
  3141  						th.BasicUser.Username,
  3142  						model.NewId(),
  3143  					},
  3144  					User:     ptrStr(th.BasicUser.Username),
  3145  					Message:  ptrStr("Message"),
  3146  					CreateAt: ptrInt64(model.GetMillis()),
  3147  				},
  3148  			},
  3149  			9,
  3150  		}
  3151  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3152  		require.NotNil(t, err)
  3153  		require.Equal(t, 0, errLine)
  3154  		AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
  3155  	})
  3156  
  3157  	t.Run("Try adding a valid post in apply mode", func(t *testing.T) {
  3158  		data := LineImportWorkerData{
  3159  			LineImportData{
  3160  				DirectPost: &DirectPostImportData{
  3161  					ChannelMembers: &[]string{
  3162  						th.BasicUser.Username,
  3163  						th.BasicUser2.Username,
  3164  					},
  3165  					User:     ptrStr(th.BasicUser.Username),
  3166  					Message:  ptrStr("Message"),
  3167  					CreateAt: ptrInt64(initialDate),
  3168  				},
  3169  			},
  3170  			1,
  3171  		}
  3172  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3173  		require.Nil(t, err)
  3174  		require.Equal(t, 0, errLine)
  3175  		AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
  3176  
  3177  		// Check the post values.
  3178  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt)
  3179  		require.Nil(t, err)
  3180  		require.Len(t, posts, 1)
  3181  
  3182  		post := posts[0]
  3183  		require.Equal(t, post.Message, *data.DirectPost.Message)
  3184  		require.Equal(t, post.CreateAt, *data.DirectPost.CreateAt)
  3185  		require.Equal(t, post.UserId, th.BasicUser.Id)
  3186  	})
  3187  
  3188  	t.Run("Import the post again", func(t *testing.T) {
  3189  		data := LineImportWorkerData{
  3190  			LineImportData{
  3191  				DirectPost: &DirectPostImportData{
  3192  					ChannelMembers: &[]string{
  3193  						th.BasicUser.Username,
  3194  						th.BasicUser2.Username,
  3195  					},
  3196  					User:     ptrStr(th.BasicUser.Username),
  3197  					Message:  ptrStr("Message"),
  3198  					CreateAt: ptrInt64(initialDate),
  3199  				},
  3200  			},
  3201  			1,
  3202  		}
  3203  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3204  		require.Nil(t, err)
  3205  		require.Equal(t, 0, errLine)
  3206  		AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
  3207  
  3208  		// Check the post values.
  3209  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt)
  3210  		require.Nil(t, err)
  3211  		require.Len(t, posts, 1)
  3212  
  3213  		post := posts[0]
  3214  		require.Equal(t, post.Message, *data.DirectPost.Message)
  3215  		require.Equal(t, post.CreateAt, *data.DirectPost.CreateAt)
  3216  		require.Equal(t, post.UserId, th.BasicUser.Id)
  3217  	})
  3218  
  3219  	t.Run("Save the post with a different time", func(t *testing.T) {
  3220  		data := LineImportWorkerData{
  3221  			LineImportData{
  3222  				DirectPost: &DirectPostImportData{
  3223  					ChannelMembers: &[]string{
  3224  						th.BasicUser.Username,
  3225  						th.BasicUser2.Username,
  3226  					},
  3227  					User:     ptrStr(th.BasicUser.Username),
  3228  					Message:  ptrStr("Message"),
  3229  					CreateAt: ptrInt64(initialDate + 1),
  3230  				},
  3231  			},
  3232  			1,
  3233  		}
  3234  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3235  		require.Nil(t, err)
  3236  		require.Equal(t, 0, errLine)
  3237  		AssertAllPostsCount(t, th.App, initialPostCount, 2, "")
  3238  	})
  3239  
  3240  	t.Run("Save the post with a different message", func(t *testing.T) {
  3241  		data := LineImportWorkerData{
  3242  			LineImportData{
  3243  				DirectPost: &DirectPostImportData{
  3244  					ChannelMembers: &[]string{
  3245  						th.BasicUser.Username,
  3246  						th.BasicUser2.Username,
  3247  					},
  3248  					User:     ptrStr(th.BasicUser.Username),
  3249  					Message:  ptrStr("Message 2"),
  3250  					CreateAt: ptrInt64(initialDate + 1),
  3251  				},
  3252  			},
  3253  			1,
  3254  		}
  3255  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3256  		require.Nil(t, err)
  3257  		require.Equal(t, 0, errLine)
  3258  		AssertAllPostsCount(t, th.App, initialPostCount, 3, "")
  3259  	})
  3260  
  3261  	t.Run("Test with hashtag", func(t *testing.T) {
  3262  		data := LineImportWorkerData{
  3263  			LineImportData{
  3264  				DirectPost: &DirectPostImportData{
  3265  					ChannelMembers: &[]string{
  3266  						th.BasicUser.Username,
  3267  						th.BasicUser2.Username,
  3268  					},
  3269  					User:     ptrStr(th.BasicUser.Username),
  3270  					Message:  ptrStr("Message 2 #hashtagmashupcity"),
  3271  					CreateAt: ptrInt64(initialDate + 2),
  3272  				},
  3273  			},
  3274  			1,
  3275  		}
  3276  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3277  		require.Nil(t, err)
  3278  		require.Equal(t, 0, errLine)
  3279  		AssertAllPostsCount(t, th.App, initialPostCount, 4, "")
  3280  
  3281  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt)
  3282  		require.Nil(t, err)
  3283  		require.Len(t, posts, 1)
  3284  
  3285  		post := posts[0]
  3286  		require.Equal(t, post.Message, *data.DirectPost.Message)
  3287  		require.Equal(t, post.CreateAt, *data.DirectPost.CreateAt)
  3288  		require.Equal(t, post.UserId, th.BasicUser.Id)
  3289  		require.Equal(t, post.Hashtags, "#hashtagmashupcity")
  3290  	})
  3291  
  3292  	t.Run("Test with some flags", func(t *testing.T) {
  3293  		data := LineImportWorkerData{
  3294  			LineImportData{
  3295  				DirectPost: &DirectPostImportData{
  3296  					ChannelMembers: &[]string{
  3297  						th.BasicUser.Username,
  3298  						th.BasicUser2.Username,
  3299  					},
  3300  					FlaggedBy: &[]string{
  3301  						th.BasicUser.Username,
  3302  						th.BasicUser2.Username,
  3303  					},
  3304  					User:     ptrStr(th.BasicUser.Username),
  3305  					Message:  ptrStr("Message"),
  3306  					CreateAt: ptrInt64(model.GetMillis()),
  3307  				},
  3308  			},
  3309  			1,
  3310  		}
  3311  
  3312  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3313  		require.Nil(t, err)
  3314  		require.Equal(t, 0, errLine)
  3315  
  3316  		// Check the post values.
  3317  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt)
  3318  		require.Nil(t, err)
  3319  		require.Len(t, posts, 1)
  3320  
  3321  		post := posts[0]
  3322  		checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  3323  		checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  3324  	})
  3325  
  3326  	// ------------------ Group Channel -------------------------
  3327  
  3328  	// Create the GROUP channel.
  3329  	user3 := th.CreateUser()
  3330  	channelData = DirectChannelImportData{
  3331  		Members: &[]string{
  3332  			th.BasicUser.Username,
  3333  			th.BasicUser2.Username,
  3334  			user3.Username,
  3335  		},
  3336  	}
  3337  	appErr = th.App.importDirectChannel(&channelData, false)
  3338  	require.Nil(t, appErr)
  3339  
  3340  	// Get the channel.
  3341  	var groupChannel *model.Channel
  3342  	userIds := []string{
  3343  		th.BasicUser.Id,
  3344  		th.BasicUser2.Id,
  3345  		user3.Id,
  3346  	}
  3347  	channel, appErr = th.App.createGroupChannel(userIds, th.BasicUser.Id)
  3348  	require.Equal(t, appErr.Id, store.CHANNEL_EXISTS_ERROR)
  3349  	groupChannel = channel
  3350  
  3351  	// Get the number of posts in the system.
  3352  	result, appErr = th.App.Srv().Store.Post().AnalyticsPostCount("", false, false)
  3353  	require.Nil(t, appErr)
  3354  	initialPostCount = result
  3355  
  3356  	t.Run("Try adding an invalid post in dry run mode", func(t *testing.T) {
  3357  		data := LineImportWorkerData{
  3358  			LineImportData{
  3359  				DirectPost: &DirectPostImportData{
  3360  					ChannelMembers: &[]string{
  3361  						th.BasicUser.Username,
  3362  						th.BasicUser2.Username,
  3363  						user3.Username,
  3364  					},
  3365  					User:     ptrStr(th.BasicUser.Username),
  3366  					CreateAt: ptrInt64(model.GetMillis()),
  3367  				},
  3368  			},
  3369  			4,
  3370  		}
  3371  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, true)
  3372  		require.NotNil(t, err)
  3373  		require.Equal(t, data.LineNumber, errLine)
  3374  		AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
  3375  	})
  3376  
  3377  	t.Run("Try adding a valid post in dry run mode", func(t *testing.T) {
  3378  		data := LineImportWorkerData{
  3379  			LineImportData{
  3380  				DirectPost: &DirectPostImportData{
  3381  					ChannelMembers: &[]string{
  3382  						th.BasicUser.Username,
  3383  						th.BasicUser2.Username,
  3384  						user3.Username,
  3385  					},
  3386  					User:     ptrStr(th.BasicUser.Username),
  3387  					Message:  ptrStr("Message"),
  3388  					CreateAt: ptrInt64(model.GetMillis()),
  3389  				},
  3390  			},
  3391  			1,
  3392  		}
  3393  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, true)
  3394  		require.Nil(t, err)
  3395  		require.Equal(t, 0, errLine)
  3396  		AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
  3397  	})
  3398  
  3399  	t.Run("Try adding an invalid post in apply mode", func(t *testing.T) {
  3400  		data := LineImportWorkerData{
  3401  			LineImportData{
  3402  				DirectPost: &DirectPostImportData{
  3403  					ChannelMembers: &[]string{
  3404  						th.BasicUser.Username,
  3405  						th.BasicUser2.Username,
  3406  						user3.Username,
  3407  						model.NewId(),
  3408  					},
  3409  					User:     ptrStr(th.BasicUser.Username),
  3410  					Message:  ptrStr("Message"),
  3411  					CreateAt: ptrInt64(model.GetMillis()),
  3412  				},
  3413  			},
  3414  			8,
  3415  		}
  3416  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3417  		require.NotNil(t, err)
  3418  		require.Equal(t, 0, errLine)
  3419  		AssertAllPostsCount(t, th.App, initialPostCount, 0, "")
  3420  	})
  3421  
  3422  	t.Run("Try adding a valid post in apply mode", func(t *testing.T) {
  3423  		data := LineImportWorkerData{
  3424  			LineImportData{
  3425  				DirectPost: &DirectPostImportData{
  3426  					ChannelMembers: &[]string{
  3427  						th.BasicUser.Username,
  3428  						th.BasicUser2.Username,
  3429  						user3.Username,
  3430  					},
  3431  					User:     ptrStr(th.BasicUser.Username),
  3432  					Message:  ptrStr("Message"),
  3433  					CreateAt: ptrInt64(initialDate + 10),
  3434  				},
  3435  			},
  3436  			1,
  3437  		}
  3438  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3439  		require.Nil(t, err)
  3440  		require.Equal(t, 0, errLine)
  3441  		AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
  3442  
  3443  		// Check the post values.
  3444  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.DirectPost.CreateAt)
  3445  		require.Nil(t, err)
  3446  		require.Len(t, posts, 1)
  3447  
  3448  		post := posts[0]
  3449  		require.Equal(t, post.Message, *data.DirectPost.Message)
  3450  		require.Equal(t, post.CreateAt, *data.DirectPost.CreateAt)
  3451  		require.Equal(t, post.UserId, th.BasicUser.Id)
  3452  	})
  3453  
  3454  	t.Run("Import the post again", func(t *testing.T) {
  3455  		data := LineImportWorkerData{
  3456  			LineImportData{
  3457  				DirectPost: &DirectPostImportData{
  3458  					ChannelMembers: &[]string{
  3459  						th.BasicUser.Username,
  3460  						th.BasicUser2.Username,
  3461  						user3.Username,
  3462  					},
  3463  					User:     ptrStr(th.BasicUser.Username),
  3464  					Message:  ptrStr("Message"),
  3465  					CreateAt: ptrInt64(initialDate + 10),
  3466  				},
  3467  			},
  3468  			1,
  3469  		}
  3470  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3471  		require.Nil(t, err)
  3472  		require.Equal(t, 0, errLine)
  3473  		AssertAllPostsCount(t, th.App, initialPostCount, 1, "")
  3474  
  3475  		// Check the post values.
  3476  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.DirectPost.CreateAt)
  3477  		require.Nil(t, err)
  3478  		require.Len(t, posts, 1)
  3479  
  3480  		post := posts[0]
  3481  		require.Equal(t, post.Message, *data.DirectPost.Message)
  3482  		require.Equal(t, post.CreateAt, *data.DirectPost.CreateAt)
  3483  		require.Equal(t, post.UserId, th.BasicUser.Id)
  3484  	})
  3485  
  3486  	t.Run("Save the post with a different time", func(t *testing.T) {
  3487  		data := LineImportWorkerData{
  3488  			LineImportData{
  3489  				DirectPost: &DirectPostImportData{
  3490  					ChannelMembers: &[]string{
  3491  						th.BasicUser.Username,
  3492  						th.BasicUser2.Username,
  3493  						user3.Username,
  3494  					},
  3495  					User:     ptrStr(th.BasicUser.Username),
  3496  					Message:  ptrStr("Message"),
  3497  					CreateAt: ptrInt64(initialDate + 11),
  3498  				},
  3499  			},
  3500  			1,
  3501  		}
  3502  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3503  		require.Nil(t, err)
  3504  		require.Equal(t, 0, errLine)
  3505  		AssertAllPostsCount(t, th.App, initialPostCount, 2, "")
  3506  	})
  3507  
  3508  	t.Run("Save the post with a different message", func(t *testing.T) {
  3509  		data := LineImportWorkerData{
  3510  			LineImportData{
  3511  				DirectPost: &DirectPostImportData{
  3512  					ChannelMembers: &[]string{
  3513  						th.BasicUser.Username,
  3514  						th.BasicUser2.Username,
  3515  						user3.Username,
  3516  					},
  3517  					User:     ptrStr(th.BasicUser.Username),
  3518  					Message:  ptrStr("Message 2"),
  3519  					CreateAt: ptrInt64(initialDate + 11),
  3520  				},
  3521  			},
  3522  			1,
  3523  		}
  3524  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3525  		require.Nil(t, err)
  3526  		require.Equal(t, 0, errLine)
  3527  		AssertAllPostsCount(t, th.App, initialPostCount, 3, "")
  3528  	})
  3529  
  3530  	t.Run("Test with hashtag", func(t *testing.T) {
  3531  		data := LineImportWorkerData{
  3532  			LineImportData{
  3533  				DirectPost: &DirectPostImportData{
  3534  					ChannelMembers: &[]string{
  3535  						th.BasicUser.Username,
  3536  						th.BasicUser2.Username,
  3537  						user3.Username,
  3538  					},
  3539  					User:     ptrStr(th.BasicUser.Username),
  3540  					Message:  ptrStr("Message 2 #hashtagmashupcity"),
  3541  					CreateAt: ptrInt64(initialDate + 12),
  3542  				},
  3543  			},
  3544  			1,
  3545  		}
  3546  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3547  		require.Nil(t, err)
  3548  		require.Equal(t, 0, errLine)
  3549  		AssertAllPostsCount(t, th.App, initialPostCount, 4, "")
  3550  
  3551  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.DirectPost.CreateAt)
  3552  		require.Nil(t, err)
  3553  		require.Len(t, posts, 1)
  3554  
  3555  		post := posts[0]
  3556  		require.Equal(t, post.Message, *data.DirectPost.Message)
  3557  		require.Equal(t, post.CreateAt, *data.DirectPost.CreateAt)
  3558  		require.Equal(t, post.UserId, th.BasicUser.Id)
  3559  		require.Equal(t, post.Hashtags, "#hashtagmashupcity")
  3560  	})
  3561  
  3562  	t.Run("Test with some flags", func(t *testing.T) {
  3563  		data := LineImportWorkerData{
  3564  			LineImportData{
  3565  				DirectPost: &DirectPostImportData{
  3566  					ChannelMembers: &[]string{
  3567  						th.BasicUser.Username,
  3568  						th.BasicUser2.Username,
  3569  						user3.Username,
  3570  					},
  3571  					FlaggedBy: &[]string{
  3572  						th.BasicUser.Username,
  3573  						th.BasicUser2.Username,
  3574  					},
  3575  					User:     ptrStr(th.BasicUser.Username),
  3576  					Message:  ptrStr("Message"),
  3577  					CreateAt: ptrInt64(model.GetMillis()),
  3578  				},
  3579  			},
  3580  			1,
  3581  		}
  3582  
  3583  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3584  		require.Nil(t, err)
  3585  		require.Equal(t, 0, errLine)
  3586  
  3587  		AssertAllPostsCount(t, th.App, initialPostCount, 5, "")
  3588  
  3589  		// Check the post values.
  3590  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.DirectPost.CreateAt)
  3591  		require.Nil(t, err)
  3592  		require.Len(t, posts, 1)
  3593  
  3594  		post := posts[0]
  3595  		checkPreference(t, th.App, th.BasicUser.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  3596  		checkPreference(t, th.App, th.BasicUser2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
  3597  	})
  3598  
  3599  	t.Run("Post with reaction", func(t *testing.T) {
  3600  		reactionPostTime := ptrInt64(initialDate + 22)
  3601  		reactionTime := ptrInt64(initialDate + 23)
  3602  		data := LineImportWorkerData{
  3603  			LineImportData{
  3604  				DirectPost: &DirectPostImportData{
  3605  					ChannelMembers: &[]string{
  3606  						th.BasicUser.Username,
  3607  						th.BasicUser2.Username,
  3608  						user3.Username,
  3609  					},
  3610  					User:     ptrStr(th.BasicUser.Username),
  3611  					Message:  ptrStr("Message with reaction"),
  3612  					CreateAt: reactionPostTime,
  3613  					Reactions: &[]ReactionImportData{{
  3614  						User:      ptrStr(th.BasicUser2.Username),
  3615  						EmojiName: ptrStr("+1"),
  3616  						CreateAt:  reactionTime,
  3617  					}},
  3618  				},
  3619  			},
  3620  			1,
  3621  		}
  3622  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3623  		require.Nil(t, err, "Expected success.")
  3624  		require.Equal(t, 0, errLine)
  3625  
  3626  		AssertAllPostsCount(t, th.App, initialPostCount, 6, "")
  3627  
  3628  		// Check the post values.
  3629  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.DirectPost.CreateAt)
  3630  		require.Nil(t, err)
  3631  
  3632  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  3633  
  3634  		post := posts[0]
  3635  		postBool := post.Message != *data.DirectPost.Message || post.CreateAt != *data.DirectPost.CreateAt || post.UserId != th.BasicUser.Id || !post.HasReactions
  3636  		require.False(t, postBool, "Post properties not as expected")
  3637  
  3638  		reactions, nErr := th.App.Srv().Store.Reaction().GetForPost(post.Id, false)
  3639  		require.Nil(t, nErr, "Can't get reaction")
  3640  
  3641  		require.Len(t, reactions, 1, "Invalid number of reactions")
  3642  	})
  3643  
  3644  	t.Run("Post with reply", func(t *testing.T) {
  3645  		replyPostTime := ptrInt64(initialDate + 25)
  3646  		replyTime := ptrInt64(initialDate + 26)
  3647  		data := LineImportWorkerData{
  3648  			LineImportData{
  3649  				DirectPost: &DirectPostImportData{
  3650  					ChannelMembers: &[]string{
  3651  						th.BasicUser.Username,
  3652  						th.BasicUser2.Username,
  3653  						user3.Username,
  3654  					},
  3655  					User:     ptrStr(th.BasicUser.Username),
  3656  					Message:  ptrStr("Message with reply"),
  3657  					CreateAt: replyPostTime,
  3658  					Replies: &[]ReplyImportData{{
  3659  						User:     ptrStr(th.BasicUser2.Username),
  3660  						Message:  ptrStr("Message reply"),
  3661  						CreateAt: replyTime,
  3662  					}},
  3663  				},
  3664  			},
  3665  			1,
  3666  		}
  3667  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3668  		require.Nil(t, err, "Expected success.")
  3669  		require.Equal(t, 0, errLine)
  3670  
  3671  		AssertAllPostsCount(t, th.App, initialPostCount, 8, "")
  3672  
  3673  		// Check the post values.
  3674  		posts, err := th.App.Srv().Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.DirectPost.CreateAt)
  3675  		require.Nil(t, err)
  3676  
  3677  		require.Len(t, posts, 1, "Unexpected number of posts found.")
  3678  
  3679  		post := posts[0]
  3680  		postBool := post.Message != *data.DirectPost.Message || post.CreateAt != *data.DirectPost.CreateAt || post.UserId != th.BasicUser.Id
  3681  		require.False(t, postBool, "Post properties not as expected")
  3682  
  3683  		// Check the reply values.
  3684  		replies, err := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, *replyTime)
  3685  		require.Nil(t, err)
  3686  
  3687  		require.Len(t, replies, 1, "Unexpected number of posts found.")
  3688  
  3689  		reply := replies[0]
  3690  		replyBool := reply.Message != *(*data.DirectPost.Replies)[0].Message || reply.CreateAt != *(*data.DirectPost.Replies)[0].CreateAt || reply.UserId != th.BasicUser2.Id
  3691  		require.False(t, replyBool, "Post properties not as expected")
  3692  
  3693  		require.Equal(t, post.Id, reply.RootId, "Unexpected reply RootId")
  3694  	})
  3695  
  3696  	t.Run("Update post with replies", func(t *testing.T) {
  3697  		replyPostTime := ptrInt64(initialDate + 25)
  3698  		replyTime := ptrInt64(initialDate + 26)
  3699  		data := LineImportWorkerData{
  3700  			LineImportData{
  3701  				DirectPost: &DirectPostImportData{
  3702  					ChannelMembers: &[]string{
  3703  						th.BasicUser.Username,
  3704  						th.BasicUser2.Username,
  3705  						user3.Username,
  3706  					},
  3707  					User:     ptrStr(th.BasicUser2.Username),
  3708  					Message:  ptrStr("Message with reply"),
  3709  					CreateAt: replyPostTime,
  3710  					Replies: &[]ReplyImportData{{
  3711  						User:     ptrStr(th.BasicUser.Username),
  3712  						Message:  ptrStr("Message reply"),
  3713  						CreateAt: replyTime,
  3714  					}},
  3715  				},
  3716  			},
  3717  			1,
  3718  		}
  3719  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3720  		require.Nil(t, err, "Expected success.")
  3721  		require.Equal(t, 0, errLine)
  3722  
  3723  		AssertAllPostsCount(t, th.App, initialPostCount, 8, "")
  3724  	})
  3725  
  3726  	t.Run("Create new post with replies based on the previous one", func(t *testing.T) {
  3727  		replyPostTime := ptrInt64(initialDate + 27)
  3728  		replyTime := ptrInt64(initialDate + 28)
  3729  		data := LineImportWorkerData{
  3730  			LineImportData{
  3731  				DirectPost: &DirectPostImportData{
  3732  					ChannelMembers: &[]string{
  3733  						th.BasicUser.Username,
  3734  						th.BasicUser2.Username,
  3735  						user3.Username,
  3736  					},
  3737  					User:     ptrStr(th.BasicUser2.Username),
  3738  					Message:  ptrStr("Message with reply 2"),
  3739  					CreateAt: replyPostTime,
  3740  					Replies: &[]ReplyImportData{{
  3741  						User:     ptrStr(th.BasicUser.Username),
  3742  						Message:  ptrStr("Message reply"),
  3743  						CreateAt: replyTime,
  3744  					}},
  3745  				},
  3746  			},
  3747  			1,
  3748  		}
  3749  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3750  		require.Nil(t, err, "Expected success.")
  3751  		require.Equal(t, 0, errLine)
  3752  
  3753  		AssertAllPostsCount(t, th.App, initialPostCount, 10, "")
  3754  	})
  3755  
  3756  	t.Run("Create new reply for existing post with replies", func(t *testing.T) {
  3757  		replyPostTime := ptrInt64(initialDate + 25)
  3758  		replyTime := ptrInt64(initialDate + 29)
  3759  		data := LineImportWorkerData{
  3760  			LineImportData{
  3761  				DirectPost: &DirectPostImportData{
  3762  					ChannelMembers: &[]string{
  3763  						th.BasicUser.Username,
  3764  						th.BasicUser2.Username,
  3765  						user3.Username,
  3766  					},
  3767  					User:     ptrStr(th.BasicUser2.Username),
  3768  					Message:  ptrStr("Message with reply"),
  3769  					CreateAt: replyPostTime,
  3770  					Replies: &[]ReplyImportData{{
  3771  						User:     ptrStr(th.BasicUser.Username),
  3772  						Message:  ptrStr("Message reply 2"),
  3773  						CreateAt: replyTime,
  3774  					}},
  3775  				},
  3776  			},
  3777  			1,
  3778  		}
  3779  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{data}, false)
  3780  		require.Nil(t, err, "Expected success.")
  3781  		require.Equal(t, 0, errLine)
  3782  
  3783  		AssertAllPostsCount(t, th.App, initialPostCount, 11, "")
  3784  	})
  3785  }
  3786  
  3787  func TestImportImportEmoji(t *testing.T) {
  3788  	th := Setup(t)
  3789  	defer th.TearDown()
  3790  
  3791  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCustomEmoji = true })
  3792  
  3793  	testsDir, _ := fileutils.FindDir("tests")
  3794  	testImage := filepath.Join(testsDir, "test.png")
  3795  
  3796  	data := EmojiImportData{Name: ptrStr(model.NewId())}
  3797  	err := th.App.importEmoji(&data, true)
  3798  	assert.NotNil(t, err, "Invalid emoji should have failed dry run")
  3799  
  3800  	emoji, nErr := th.App.Srv().Store.Emoji().GetByName(*data.Name, true)
  3801  	assert.Nil(t, emoji, "Emoji should not have been imported")
  3802  	assert.NotNil(t, nErr)
  3803  
  3804  	data.Image = ptrStr(testImage)
  3805  	err = th.App.importEmoji(&data, true)
  3806  	assert.Nil(t, err, "Valid emoji should have passed dry run")
  3807  
  3808  	data = EmojiImportData{Name: ptrStr(model.NewId())}
  3809  	err = th.App.importEmoji(&data, false)
  3810  	assert.NotNil(t, err, "Invalid emoji should have failed apply mode")
  3811  
  3812  	data.Image = ptrStr("non-existent-file")
  3813  	err = th.App.importEmoji(&data, false)
  3814  	assert.NotNil(t, err, "Emoji with bad image file should have failed apply mode")
  3815  
  3816  	data.Image = ptrStr(testImage)
  3817  	err = th.App.importEmoji(&data, false)
  3818  	assert.Nil(t, err, "Valid emoji should have succeeded apply mode")
  3819  
  3820  	emoji, nErr = th.App.Srv().Store.Emoji().GetByName(*data.Name, true)
  3821  	assert.NotNil(t, emoji, "Emoji should have been imported")
  3822  	assert.Nil(t, nErr, "Emoji should have been imported without any error")
  3823  
  3824  	err = th.App.importEmoji(&data, false)
  3825  	assert.Nil(t, err, "Second run should have succeeded apply mode")
  3826  }
  3827  
  3828  func TestImportAttachment(t *testing.T) {
  3829  	th := Setup(t)
  3830  	defer th.TearDown()
  3831  
  3832  	testsDir, _ := fileutils.FindDir("tests")
  3833  	testImage := filepath.Join(testsDir, "test.png")
  3834  	invalidPath := "some-invalid-path"
  3835  
  3836  	userId := model.NewId()
  3837  	data := AttachmentImportData{Path: &testImage}
  3838  	_, err := th.App.importAttachment(&data, &model.Post{UserId: userId, ChannelId: "some-channel"}, "some-team", true)
  3839  	assert.Nil(t, err, "sample run without errors")
  3840  
  3841  	attachments := GetAttachments(userId, th, t)
  3842  	assert.Len(t, attachments, 1)
  3843  
  3844  	data = AttachmentImportData{Path: &invalidPath}
  3845  	_, err = th.App.importAttachment(&data, &model.Post{UserId: model.NewId(), ChannelId: "some-channel"}, "some-team", true)
  3846  	assert.NotNil(t, err, "should have failed when opening the file")
  3847  	assert.Equal(t, err.Id, "app.import.attachment.bad_file.error")
  3848  }
  3849  
  3850  func TestImportPostAndRepliesWithAttachments(t *testing.T) {
  3851  	th := Setup(t)
  3852  	defer th.TearDown()
  3853  
  3854  	// Create a Team.
  3855  	teamName := model.NewRandomTeamName()
  3856  	th.App.importTeam(&TeamImportData{
  3857  		Name:        &teamName,
  3858  		DisplayName: ptrStr("Display Name"),
  3859  		Type:        ptrStr("O"),
  3860  	}, false)
  3861  	team, appErr := th.App.GetTeamByName(teamName)
  3862  	require.Nil(t, appErr, "Failed to get team from database.")
  3863  
  3864  	// Create a Channel.
  3865  	channelName := model.NewId()
  3866  	th.App.importChannel(&ChannelImportData{
  3867  		Team:        &teamName,
  3868  		Name:        &channelName,
  3869  		DisplayName: ptrStr("Display Name"),
  3870  		Type:        ptrStr("O"),
  3871  	}, false)
  3872  	_, appErr = th.App.GetChannelByName(channelName, team.Id, false)
  3873  	require.Nil(t, appErr, "Failed to get channel from database.")
  3874  
  3875  	// Create a user3.
  3876  	username := model.NewId()
  3877  	th.App.importUser(&UserImportData{
  3878  		Username: &username,
  3879  		Email:    ptrStr(model.NewId() + "@example.com"),
  3880  	}, false)
  3881  	user3, appErr := th.App.GetUserByUsername(username)
  3882  	require.Nil(t, appErr, "Failed to get user3 from database.")
  3883  
  3884  	username2 := model.NewId()
  3885  	th.App.importUser(&UserImportData{
  3886  		Username: &username2,
  3887  		Email:    ptrStr(model.NewId() + "@example.com"),
  3888  	}, false)
  3889  	user2, appErr := th.App.GetUserByUsername(username2)
  3890  	require.Nil(t, appErr, "Failed to get user3 from database.")
  3891  
  3892  	// Create direct post users.
  3893  	username3 := model.NewId()
  3894  	th.App.importUser(&UserImportData{
  3895  		Username: &username3,
  3896  		Email:    ptrStr(model.NewId() + "@example.com"),
  3897  	}, false)
  3898  	user3, appErr = th.App.GetUserByUsername(username3)
  3899  	require.Nil(t, appErr, "Failed to get user3 from database.")
  3900  
  3901  	username4 := model.NewId()
  3902  	th.App.importUser(&UserImportData{
  3903  		Username: &username4,
  3904  		Email:    ptrStr(model.NewId() + "@example.com"),
  3905  	}, false)
  3906  
  3907  	user4, appErr := th.App.GetUserByUsername(username4)
  3908  	require.Nil(t, appErr, "Failed to get user3 from database.")
  3909  
  3910  	// Post with attachments
  3911  	time := model.GetMillis()
  3912  	attachmentsPostTime := time
  3913  	attachmentsReplyTime := time + 1
  3914  	testsDir, _ := fileutils.FindDir("tests")
  3915  	testImage := filepath.Join(testsDir, "test.png")
  3916  	testMarkDown := filepath.Join(testsDir, "test-attachments.md")
  3917  	data := LineImportWorkerData{
  3918  		LineImportData{
  3919  			Post: &PostImportData{
  3920  				Team:        &teamName,
  3921  				Channel:     &channelName,
  3922  				User:        &username3,
  3923  				Message:     ptrStr("Message with reply"),
  3924  				CreateAt:    &attachmentsPostTime,
  3925  				Attachments: &[]AttachmentImportData{{Path: &testImage}, {Path: &testMarkDown}},
  3926  				Replies: &[]ReplyImportData{{
  3927  					User:        &user4.Username,
  3928  					Message:     ptrStr("Message reply"),
  3929  					CreateAt:    &attachmentsReplyTime,
  3930  					Attachments: &[]AttachmentImportData{{Path: &testImage}},
  3931  				}},
  3932  			},
  3933  		},
  3934  		19,
  3935  	}
  3936  
  3937  	t.Run("import with attachment", func(t *testing.T) {
  3938  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  3939  		require.Nil(t, err)
  3940  		require.Equal(t, 0, errLine)
  3941  
  3942  		attachments := GetAttachments(user3.Id, th, t)
  3943  		require.Len(t, attachments, 2)
  3944  		assert.Contains(t, attachments[0].Path, team.Id)
  3945  		assert.Contains(t, attachments[1].Path, team.Id)
  3946  		AssertFileIdsInPost(attachments, th, t)
  3947  
  3948  		attachments = GetAttachments(user4.Id, th, t)
  3949  		require.Len(t, attachments, 1)
  3950  		assert.Contains(t, attachments[0].Path, team.Id)
  3951  		AssertFileIdsInPost(attachments, th, t)
  3952  	})
  3953  
  3954  	t.Run("import existing post with new attachment", func(t *testing.T) {
  3955  		data.Post.Attachments = &[]AttachmentImportData{{Path: &testImage}}
  3956  		errLine, err := th.App.importMultiplePostLines([]LineImportWorkerData{data}, false)
  3957  		require.Nil(t, err)
  3958  		require.Equal(t, 0, errLine)
  3959  
  3960  		attachments := GetAttachments(user3.Id, th, t)
  3961  		require.Len(t, attachments, 1)
  3962  		assert.Contains(t, attachments[0].Path, team.Id)
  3963  		AssertFileIdsInPost(attachments, th, t)
  3964  
  3965  		attachments = GetAttachments(user4.Id, th, t)
  3966  		require.Len(t, attachments, 1)
  3967  		assert.Contains(t, attachments[0].Path, team.Id)
  3968  		AssertFileIdsInPost(attachments, th, t)
  3969  	})
  3970  
  3971  	t.Run("Reply with Attachments in Direct Pos", func(t *testing.T) {
  3972  		directImportData := LineImportWorkerData{
  3973  			LineImportData{
  3974  				DirectPost: &DirectPostImportData{
  3975  					ChannelMembers: &[]string{
  3976  						user3.Username,
  3977  						user2.Username,
  3978  					},
  3979  					User:     &user3.Username,
  3980  					Message:  ptrStr("Message with Replies"),
  3981  					CreateAt: ptrInt64(model.GetMillis()),
  3982  					Replies: &[]ReplyImportData{{
  3983  						User:        &user2.Username,
  3984  						Message:     ptrStr("Message reply with attachment"),
  3985  						CreateAt:    ptrInt64(model.GetMillis()),
  3986  						Attachments: &[]AttachmentImportData{{Path: &testImage}},
  3987  					}},
  3988  				},
  3989  			},
  3990  			7,
  3991  		}
  3992  
  3993  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{directImportData}, false)
  3994  		require.Nil(t, err, "Expected success.")
  3995  		require.Equal(t, 0, errLine)
  3996  
  3997  		attachments := GetAttachments(user2.Id, th, t)
  3998  		require.Len(t, attachments, 1)
  3999  		assert.Contains(t, attachments[0].Path, "noteam")
  4000  		AssertFileIdsInPost(attachments, th, t)
  4001  	})
  4002  }
  4003  
  4004  func TestImportDirectPostWithAttachments(t *testing.T) {
  4005  	th := Setup(t)
  4006  	defer th.TearDown()
  4007  
  4008  	testsDir, _ := fileutils.FindDir("tests")
  4009  	testImage := filepath.Join(testsDir, "test.png")
  4010  	testImage2 := filepath.Join(testsDir, "test.svg")
  4011  	// create a temp file with same name as original but with a different first byte
  4012  	tmpFolder, _ := ioutil.TempDir("", "imgFake")
  4013  	testImageFake := filepath.Join(tmpFolder, "test.png")
  4014  	fakeFileData, _ := ioutil.ReadFile(testImage)
  4015  	fakeFileData[0] = 0
  4016  	_ = ioutil.WriteFile(testImageFake, fakeFileData, 0644)
  4017  	defer os.RemoveAll(tmpFolder)
  4018  
  4019  	// Create a user.
  4020  	username := model.NewId()
  4021  	th.App.importUser(&UserImportData{
  4022  		Username: &username,
  4023  		Email:    ptrStr(model.NewId() + "@example.com"),
  4024  	}, false)
  4025  	user1, appErr := th.App.GetUserByUsername(username)
  4026  	require.Nil(t, appErr, "Failed to get user1 from database.")
  4027  
  4028  	username2 := model.NewId()
  4029  	th.App.importUser(&UserImportData{
  4030  		Username: &username2,
  4031  		Email:    ptrStr(model.NewId() + "@example.com"),
  4032  	}, false)
  4033  
  4034  	user2, appErr := th.App.GetUserByUsername(username2)
  4035  	require.Nil(t, appErr, "Failed to get user2 from database.")
  4036  
  4037  	directImportData := LineImportWorkerData{
  4038  		LineImportData{
  4039  			DirectPost: &DirectPostImportData{
  4040  				ChannelMembers: &[]string{
  4041  					user1.Username,
  4042  					user2.Username,
  4043  				},
  4044  				User:        &user1.Username,
  4045  				Message:     ptrStr("Direct message"),
  4046  				CreateAt:    ptrInt64(model.GetMillis()),
  4047  				Attachments: &[]AttachmentImportData{{Path: &testImage}},
  4048  			},
  4049  		},
  4050  		3,
  4051  	}
  4052  
  4053  	t.Run("Regular import of attachment", func(t *testing.T) {
  4054  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{directImportData}, false)
  4055  		require.Nil(t, err, "Expected success.")
  4056  		require.Equal(t, 0, errLine)
  4057  
  4058  		attachments := GetAttachments(user1.Id, th, t)
  4059  		require.Len(t, attachments, 1)
  4060  		assert.Contains(t, attachments[0].Path, "noteam")
  4061  		AssertFileIdsInPost(attachments, th, t)
  4062  	})
  4063  
  4064  	t.Run("Attempt to import again with same file entirely, should NOT add an attachment", func(t *testing.T) {
  4065  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{directImportData}, false)
  4066  		require.Nil(t, err, "Expected success.")
  4067  		require.Equal(t, 0, errLine)
  4068  
  4069  		attachments := GetAttachments(user1.Id, th, t)
  4070  		require.Len(t, attachments, 1)
  4071  	})
  4072  
  4073  	t.Run("Attempt to import again with same name and size but different content, SHOULD add an attachment", func(t *testing.T) {
  4074  		directImportDataFake := LineImportWorkerData{
  4075  			LineImportData{
  4076  				DirectPost: &DirectPostImportData{
  4077  					ChannelMembers: &[]string{
  4078  						user1.Username,
  4079  						user2.Username,
  4080  					},
  4081  					User:        &user1.Username,
  4082  					Message:     ptrStr("Direct message"),
  4083  					CreateAt:    ptrInt64(model.GetMillis()),
  4084  					Attachments: &[]AttachmentImportData{{Path: &testImageFake}},
  4085  				},
  4086  			},
  4087  			2,
  4088  		}
  4089  
  4090  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{directImportDataFake}, false)
  4091  		require.Nil(t, err, "Expected success.")
  4092  		require.Equal(t, 0, errLine)
  4093  
  4094  		attachments := GetAttachments(user1.Id, th, t)
  4095  		require.Len(t, attachments, 2)
  4096  	})
  4097  
  4098  	t.Run("Attempt to import again with same data, SHOULD add an attachment, since it's different name", func(t *testing.T) {
  4099  		directImportData2 := LineImportWorkerData{
  4100  			LineImportData{
  4101  				DirectPost: &DirectPostImportData{
  4102  					ChannelMembers: &[]string{
  4103  						user1.Username,
  4104  						user2.Username,
  4105  					},
  4106  					User:        &user1.Username,
  4107  					Message:     ptrStr("Direct message"),
  4108  					CreateAt:    ptrInt64(model.GetMillis()),
  4109  					Attachments: &[]AttachmentImportData{{Path: &testImage2}},
  4110  				},
  4111  			},
  4112  			2,
  4113  		}
  4114  
  4115  		errLine, err := th.App.importMultipleDirectPostLines([]LineImportWorkerData{directImportData2}, false)
  4116  		require.Nil(t, err, "Expected success.")
  4117  		require.Equal(t, 0, errLine)
  4118  
  4119  		attachments := GetAttachments(user1.Id, th, t)
  4120  		require.Len(t, attachments, 3)
  4121  	})
  4122  }