Files
mattermost/app/import_test.go
Sandeep Sukhani 7f9e1273d7 [MM-12667] Allow including deactivated users in bulk import and export (#10353)
* [MM-12667] Allow including deactivated users in bulk import and export

1. Added `deleteAt` for user type import line
2. Adding deactivated users data in bulk export
3. Importing deactivated users data in bulk import

Added/Updated relevant test cases

* Fixed export of replies to posts by deleted users.
Updated tests for same
2019-03-01 15:50:24 +00:00

258 lines
11 KiB
Go

// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"path/filepath"
"runtime/debug"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils/fileutils"
)
func ptrStr(s string) *string {
return &s
}
func ptrInt64(i int64) *int64 {
return &i
}
func ptrInt(i int) *int {
return &i
}
func ptrBool(b bool) *bool {
return &b
}
func checkPreference(t *testing.T, a *App, userId string, category string, name string, value string) {
if res := <-a.Srv.Store.Preference().GetCategory(userId, category); res.Err != nil {
debug.PrintStack()
t.Fatalf("Failed to get preferences for user %v with category %v", userId, category)
} else {
preferences := res.Data.(model.Preferences)
found := false
for _, preference := range preferences {
if preference.Name == name {
found = true
if preference.Value != value {
debug.PrintStack()
t.Fatalf("Preference for user %v in category %v with name %v has value %v, expected %v", userId, category, name, preference.Value, value)
}
break
}
}
if !found {
debug.PrintStack()
t.Fatalf("Did not find preference for user %v in category %v with name %v", userId, category, name)
}
}
}
func checkNotifyProp(t *testing.T, user *model.User, key string, value string) {
if actual, ok := user.NotifyProps[key]; !ok {
debug.PrintStack()
t.Fatalf("Notify prop %v not found. User: %v", key, user.Id)
} else if actual != value {
debug.PrintStack()
t.Fatalf("Notify Prop %v was %v but expected %v. User: %v", key, actual, value, user.Id)
}
}
func checkError(t *testing.T, err *model.AppError) {
if err == nil {
debug.PrintStack()
t.Fatal("Should have returned an error.")
}
}
func checkNoError(t *testing.T, err *model.AppError) {
if err != nil {
debug.PrintStack()
t.Fatalf("Unexpected Error: %v", err.Error())
}
}
func AssertAllPostsCount(t *testing.T, a *App, initialCount int64, change int64, teamName string) {
if result := <-a.Srv.Store.Post().AnalyticsPostCount(teamName, false, false); result.Err != nil {
t.Fatal(result.Err)
} else {
if initialCount+change != result.Data.(int64) {
debug.PrintStack()
t.Fatalf("Did not find the expected number of posts.")
}
}
}
func AssertChannelCount(t *testing.T, a *App, channelType string, expectedCount int64) {
if r := <-a.Srv.Store.Channel().AnalyticsTypeCount("", channelType); r.Err == nil {
count := r.Data.(int64)
if count != expectedCount {
debug.PrintStack()
t.Fatalf("Channel count of type: %v. Expected: %v, Got: %v", channelType, expectedCount, count)
}
} else {
debug.PrintStack()
t.Fatalf("Failed to get channel count.")
}
}
func TestImportImportLine(t *testing.T) {
th := Setup(t)
defer th.TearDown()
// Try import line with an invalid type.
line := LineImportData{
Type: "gibberish",
}
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with invalid type.")
}
// Try import line with team type but nil team.
line.Type = "team"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line of type team with a nil team.")
}
// Try import line with channel type but nil channel.
line.Type = "channel"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type channel with a nil channel.")
}
// Try import line with user type but nil user.
line.Type = "user"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type uesr with a nil user.")
}
// Try import line with post type but nil post.
line.Type = "post"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type post with a nil post.")
}
// Try import line with direct_channel type but nil direct_channel.
line.Type = "direct_channel"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type direct_channel with a nil direct_channel.")
}
// Try import line with direct_post type but nil direct_post.
line.Type = "direct_post"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type direct_post with a nil direct_post.")
}
// Try import line with scheme type but nil scheme.
line.Type = "scheme"
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type scheme with a nil scheme.")
}
}
func TestImportBulkImport(t *testing.T) {
th := Setup(t)
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCustomEmoji = true })
teamName := model.NewId()
channelName := model.NewId()
username := model.NewId()
username2 := model.NewId()
username3 := model.NewId()
emojiName := model.NewId()
testsDir, _ := fileutils.FindDir("tests")
testImage := filepath.Join(testsDir, "test.png")
teamTheme1 := `{\"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\"}`
teamTheme2 := `{\"awayIndicator\":\"#DBBD4E\",\"buttonBg\":\"#23A100\",\"buttonColor\":\"#EEEEEE\",\"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\":\"#222222\",\"sidebarTextHoverBg\":\"#e6f2fa\",\"sidebarUnreadText\":\"#444444\",\"type\":\"Mattermost\"}`
// Run bulk import with a valid 1 of everything.
data1 := `{"type": "version", "version": 1}
{"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}}
{"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}}
{"type": "user", "user": {"username": "` + username + `", "email": "` + username + `@example.com", "teams": [{"name": "` + teamName + `","theme": "` + teamTheme1 + `", "channels": [{"name": "` + channelName + `"}]}]}}
{"type": "user", "user": {"username": "` + username2 + `", "email": "` + username2 + `@example.com", "teams": [{"name": "` + teamName + `","theme": "` + teamTheme2 + `", "channels": [{"name": "` + channelName + `"}]}]}}
{"type": "user", "user": {"username": "` + username3 + `", "email": "` + username3 + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}], "delete_at": 123456789016}]}}
{"type": "post", "post": {"team": "` + teamName + `", "channel": "` + channelName + `", "user": "` + username + `", "message": "Hello World", "create_at": 123456789012, "attachments":[{"path": "` + testImage + `"}]}}
{"type": "post", "post": {"team": "` + teamName + `", "channel": "` + channelName + `", "user": "` + username3 + `", "message": "Hey Everyone!", "create_at": 123456789013, "attachments":[{"path": "` + testImage + `"}]}}
{"type": "direct_channel", "direct_channel": {"members": ["` + username + `", "` + username2 + `"]}}
{"type": "direct_channel", "direct_channel": {"members": ["` + username + `", "` + username2 + `", "` + username3 + `"]}}
{"type": "direct_post", "direct_post": {"channel_members": ["` + username + `", "` + username2 + `"], "user": "` + username + `", "message": "Hello Direct Channel", "create_at": 123456789014}}
{"type": "direct_post", "direct_post": {"channel_members": ["` + username + `", "` + username2 + `", "` + username3 + `"], "user": "` + username + `", "message": "Hello Group Channel", "create_at": 123456789015}}
{"type": "emoji", "emoji": {"name": "` + emojiName + `", "image": "` + testImage + `"}}`
if err, line := th.App.BulkImport(strings.NewReader(data1), false, 2); err != nil || line != 0 {
t.Fatalf("BulkImport should have succeeded: %v, %v", err.Error(), line)
}
// Run bulk import using a string that contains a line with invalid json.
data2 := `{"type": "version", "version": 1`
if err, line := th.App.BulkImport(strings.NewReader(data2), false, 2); err == nil || line != 1 {
t.Fatalf("Should have failed due to invalid JSON on line 1.")
}
// Run bulk import using valid JSON but missing version line at the start.
data3 := `{"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}}
{"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}}
{"type": "user", "user": {"username": "kufjgnkxkrhhfgbrip6qxkfsaa", "email": "kufjgnkxkrhhfgbrip6qxkfsaa@example.com"}}
{"type": "user", "user": {"username": "bwshaim6qnc2ne7oqkd5b2s2rq", "email": "bwshaim6qnc2ne7oqkd5b2s2rq@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}}`
if err, line := th.App.BulkImport(strings.NewReader(data3), false, 2); err == nil || line != 1 {
t.Fatalf("Should have failed due to missing version line on line 1.")
}
}
func TestImportProcessImportDataFileVersionLine(t *testing.T) {
data := LineImportData{
Type: "version",
Version: ptrInt(1),
}
if version, err := processImportDataFileVersionLine(data); err != nil || version != 1 {
t.Fatalf("Expected no error and version 1.")
}
data.Type = "NotVersion"
if _, err := processImportDataFileVersionLine(data); err == nil {
t.Fatalf("Expected error on invalid version line.")
}
data.Type = "version"
data.Version = nil
if _, err := processImportDataFileVersionLine(data); err == nil {
t.Fatalf("Expected error on invalid version line.")
}
}
func GetAttachments(userId string, th *TestHelper, t *testing.T) []*model.FileInfo {
if result := <-th.App.Srv.Store.FileInfo().GetForUser(userId); result.Err != nil {
t.Fatal(result.Err.Error())
} else {
return result.Data.([]*model.FileInfo)
}
return nil
}
func AssertFileIdsInPost(files []*model.FileInfo, th *TestHelper, t *testing.T) {
postId := files[0].PostId
assert.NotNil(t, postId)
if result := <-th.App.Srv.Store.Post().GetPostsByIds([]string{postId}); result.Err != nil {
t.Fatal(result.Err.Error())
} else {
posts := result.Data.([]*model.Post)
assert.Equal(t, len(posts), 1)
for _, file := range files {
assert.Contains(t, posts[0].FileIds, file.Id)
}
}
}