PLT-6937: Bulk Importing of Direct/Group channels and posts. (#6761)
* PLT-6937: Bulk Importing of Direct/Group channels and posts. * Show group/direct channels in sidebar.
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
fb2ef7708b
Коммит
37642a4f1e
@@ -160,6 +160,27 @@ func CreateChannel(channel *model.Channel, addMember bool) (*model.Channel, *mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) {
|
func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) {
|
||||||
|
if channel, err := createDirectChannel(userId, otherUserId); err != nil {
|
||||||
|
if err.Id == store.CHANNEL_EXISTS_ERROR {
|
||||||
|
return channel, nil
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WaitForChannelMembership(channel.Id, userId)
|
||||||
|
|
||||||
|
InvalidateCacheForUser(userId)
|
||||||
|
InvalidateCacheForUser(otherUserId)
|
||||||
|
|
||||||
|
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_DIRECT_ADDED, "", channel.Id, "", nil)
|
||||||
|
message.Add("teammate_id", otherUserId)
|
||||||
|
Publish(message)
|
||||||
|
|
||||||
|
return channel, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) {
|
||||||
uc1 := Srv.Store.User().Get(userId)
|
uc1 := Srv.Store.User().Get(userId)
|
||||||
uc2 := Srv.Store.User().Get(otherUserId)
|
uc2 := Srv.Store.User().Get(otherUserId)
|
||||||
|
|
||||||
@@ -173,22 +194,12 @@ func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *mo
|
|||||||
|
|
||||||
if result := <-Srv.Store.Channel().CreateDirectChannel(userId, otherUserId); result.Err != nil {
|
if result := <-Srv.Store.Channel().CreateDirectChannel(userId, otherUserId); result.Err != nil {
|
||||||
if result.Err.Id == store.CHANNEL_EXISTS_ERROR {
|
if result.Err.Id == store.CHANNEL_EXISTS_ERROR {
|
||||||
return result.Data.(*model.Channel), nil
|
return result.Data.(*model.Channel), result.Err
|
||||||
} else {
|
} else {
|
||||||
return nil, result.Err
|
return nil, result.Err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
channel := result.Data.(*model.Channel)
|
channel := result.Data.(*model.Channel)
|
||||||
|
|
||||||
WaitForChannelMembership(channel.Id, userId)
|
|
||||||
|
|
||||||
InvalidateCacheForUser(userId)
|
|
||||||
InvalidateCacheForUser(otherUserId)
|
|
||||||
|
|
||||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_DIRECT_ADDED, "", channel.Id, "", nil)
|
|
||||||
message.Add("teammate_id", otherUserId)
|
|
||||||
Publish(message)
|
|
||||||
|
|
||||||
return channel, nil
|
return channel, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,6 +230,30 @@ func WaitForChannelMembership(channelId string, userId string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) {
|
func CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) {
|
||||||
|
if channel, err := createGroupChannel(userIds, creatorId); err != nil {
|
||||||
|
if err.Id == store.CHANNEL_EXISTS_ERROR {
|
||||||
|
return channel, nil
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, userId := range userIds {
|
||||||
|
if userId == creatorId {
|
||||||
|
WaitForChannelMembership(channel.Id, creatorId)
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidateCacheForUser(userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_GROUP_ADDED, "", channel.Id, "", nil)
|
||||||
|
message.Add("teammate_ids", model.ArrayToJson(userIds))
|
||||||
|
Publish(message)
|
||||||
|
|
||||||
|
return channel, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) {
|
||||||
if len(userIds) > model.CHANNEL_GROUP_MAX_USERS || len(userIds) < model.CHANNEL_GROUP_MIN_USERS {
|
if len(userIds) > model.CHANNEL_GROUP_MAX_USERS || len(userIds) < model.CHANNEL_GROUP_MIN_USERS {
|
||||||
return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest)
|
return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
@@ -231,7 +266,7 @@ func CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(users) != len(userIds) {
|
if len(users) != len(userIds) {
|
||||||
return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIds), http.StatusBadRequest)
|
return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids=" + model.ArrayToJson(userIds), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
group := &model.Channel{
|
group := &model.Channel{
|
||||||
@@ -242,7 +277,7 @@ func CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *mo
|
|||||||
|
|
||||||
if result := <-Srv.Store.Channel().Save(group); result.Err != nil {
|
if result := <-Srv.Store.Channel().Save(group); result.Err != nil {
|
||||||
if result.Err.Id == store.CHANNEL_EXISTS_ERROR {
|
if result.Err.Id == store.CHANNEL_EXISTS_ERROR {
|
||||||
return result.Data.(*model.Channel), nil
|
return result.Data.(*model.Channel), result.Err
|
||||||
} else {
|
} else {
|
||||||
return nil, result.Err
|
return nil, result.Err
|
||||||
}
|
}
|
||||||
@@ -260,18 +295,8 @@ func CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *mo
|
|||||||
if result := <-Srv.Store.Channel().SaveMember(cm); result.Err != nil {
|
if result := <-Srv.Store.Channel().SaveMember(cm); result.Err != nil {
|
||||||
return nil, result.Err
|
return nil, result.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Id == creatorId {
|
|
||||||
WaitForChannelMembership(group.Id, creatorId)
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidateCacheForUser(user.Id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_GROUP_ADDED, "", group.Id, "", nil)
|
|
||||||
message.Add("teammate_ids", model.ArrayToJson(userIds))
|
|
||||||
Publish(message)
|
|
||||||
|
|
||||||
return channel, nil
|
return channel, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
240
app/import.go
240
app/import.go
@@ -17,17 +17,20 @@ import (
|
|||||||
l4g "github.com/alecthomas/log4go"
|
l4g "github.com/alecthomas/log4go"
|
||||||
"github.com/mattermost/platform/model"
|
"github.com/mattermost/platform/model"
|
||||||
"github.com/mattermost/platform/utils"
|
"github.com/mattermost/platform/utils"
|
||||||
|
"github.com/mattermost/platform/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Import Data Models
|
// Import Data Models
|
||||||
|
|
||||||
type LineImportData struct {
|
type LineImportData struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Team *TeamImportData `json:"team"`
|
Team *TeamImportData `json:"team"`
|
||||||
Channel *ChannelImportData `json:"channel"`
|
Channel *ChannelImportData `json:"channel"`
|
||||||
User *UserImportData `json:"user"`
|
User *UserImportData `json:"user"`
|
||||||
Post *PostImportData `json:"post"`
|
Post *PostImportData `json:"post"`
|
||||||
Version *int `json:"version"`
|
DirectChannel *DirectChannelImportData `json:"direct_channel"`
|
||||||
|
DirectPost *DirectPostImportData `json:"direct_post"`
|
||||||
|
Version *int `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TeamImportData struct {
|
type TeamImportData struct {
|
||||||
@@ -97,6 +100,20 @@ type PostImportData struct {
|
|||||||
CreateAt *int64 `json:"create_at"`
|
CreateAt *int64 `json:"create_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DirectChannelImportData struct {
|
||||||
|
Members *[]string `json:"members"`
|
||||||
|
|
||||||
|
Header *string `json:"header"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DirectPostImportData struct {
|
||||||
|
ChannelMembers *[]string `json:"channel_members"`
|
||||||
|
User *string `json:"user"`
|
||||||
|
|
||||||
|
Message *string `json:"message"`
|
||||||
|
CreateAt *int64 `json:"create_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type LineImportWorkerData struct {
|
type LineImportWorkerData struct {
|
||||||
LineImportData
|
LineImportData
|
||||||
LineNumber int
|
LineNumber int
|
||||||
@@ -233,6 +250,18 @@ func ImportLine(line LineImportData, dryRun bool) *model.AppError {
|
|||||||
} else {
|
} else {
|
||||||
return ImportPost(line.Post, dryRun)
|
return ImportPost(line.Post, dryRun)
|
||||||
}
|
}
|
||||||
|
case line.Type == "direct_channel":
|
||||||
|
if line.DirectChannel == nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_line.null_direct_channel.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
return ImportDirectChannel(line.DirectChannel, dryRun)
|
||||||
|
}
|
||||||
|
case line.Type == "direct_post":
|
||||||
|
if line.DirectPost == nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_line.null_direct_post.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
return ImportDirectPost(line.DirectPost, dryRun)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return model.NewLocAppError("BulkImport", "app.import.import_line.unknown_line_type.error", map[string]interface{}{"Type": line.Type}, "")
|
return model.NewLocAppError("BulkImport", "app.import.import_line.unknown_line_type.error", map[string]interface{}{"Type": line.Type}, "")
|
||||||
}
|
}
|
||||||
@@ -945,6 +974,205 @@ func validatePostImportData(data *PostImportData) *model.AppError {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ImportDirectChannel(data *DirectChannelImportData, dryRun bool) *model.AppError {
|
||||||
|
if err := validateDirectChannelImportData(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a Dry Run, do not continue any further.
|
||||||
|
if dryRun {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var userIds []string
|
||||||
|
for _, username := range *data.Members {
|
||||||
|
if result := <-Srv.Store.User().GetByUsername(username); result.Err == nil {
|
||||||
|
user := result.Data.(*model.User)
|
||||||
|
userIds = append(userIds, user.Id)
|
||||||
|
} else {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_channel.member_not_found.error", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel *model.Channel
|
||||||
|
|
||||||
|
if len(userIds) == 2 {
|
||||||
|
ch, err := createDirectChannel(userIds[0], userIds[1])
|
||||||
|
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
channel = ch
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ch, err := createGroupChannel(userIds, userIds[0])
|
||||||
|
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
channel = ch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, userId := range userIds {
|
||||||
|
preferences := model.Preferences{
|
||||||
|
model.Preference{
|
||||||
|
UserId: userId,
|
||||||
|
Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW,
|
||||||
|
Name: channel.Id,
|
||||||
|
Value: "true",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil {
|
||||||
|
result.Err.StatusCode = http.StatusBadRequest
|
||||||
|
return result.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Header != nil {
|
||||||
|
channel.Header = *data.Header
|
||||||
|
if result := <-Srv.Store.Channel().Update(channel); result.Err != nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_channel.update_header_failed.error", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDirectChannelImportData(data *DirectChannelImportData) *model.AppError {
|
||||||
|
if data.Members == nil {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.members_required.error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*data.Members) != 2 {
|
||||||
|
if len(*data.Members) < model.CHANNEL_GROUP_MIN_USERS {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.members_too_few.error", nil, "")
|
||||||
|
} else if len(*data.Members) > model.CHANNEL_GROUP_MAX_USERS {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.members_too_many.error", nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Header != nil && utf8.RuneCountInString(*data.Header) > model.CHANNEL_HEADER_MAX_RUNES {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_channel_import_data.header_length.error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.AppError {
|
||||||
|
if err := validateDirectPostImportData(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a Dry Run, do not continue any further.
|
||||||
|
if dryRun {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var userIds []string
|
||||||
|
for _, username := range *data.ChannelMembers {
|
||||||
|
if result := <-Srv.Store.User().GetByUsername(username); result.Err == nil {
|
||||||
|
user := result.Data.(*model.User)
|
||||||
|
userIds = append(userIds, user.Id)
|
||||||
|
} else {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_post.channel_member_not_found.error", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel *model.Channel
|
||||||
|
if len(userIds) == 2 {
|
||||||
|
ch, err := createDirectChannel(userIds[0], userIds[1])
|
||||||
|
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
channel = ch
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ch, err := createGroupChannel(userIds, userIds[0])
|
||||||
|
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
channel = ch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var user *model.User
|
||||||
|
if result := <-Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.import_direct_post.user_not_found.error", map[string]interface{}{"Username": *data.User}, "", http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
user = result.Data.(*model.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this post already exists.
|
||||||
|
var posts []*model.Post
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(channel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
return result.Err
|
||||||
|
} else {
|
||||||
|
posts = result.Data.([]*model.Post)
|
||||||
|
}
|
||||||
|
|
||||||
|
var post *model.Post
|
||||||
|
for _, p := range posts {
|
||||||
|
if p.Message == *data.Message {
|
||||||
|
post = p
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if post == nil {
|
||||||
|
post = &model.Post{}
|
||||||
|
}
|
||||||
|
|
||||||
|
post.ChannelId = channel.Id
|
||||||
|
post.Message = *data.Message
|
||||||
|
post.UserId = user.Id
|
||||||
|
post.CreateAt = *data.CreateAt
|
||||||
|
|
||||||
|
post.Hashtags, _ = model.ParseHashtags(post.Message)
|
||||||
|
|
||||||
|
if post.Id == "" {
|
||||||
|
if result := <-Srv.Store.Post().Save(post); result.Err != nil {
|
||||||
|
return result.Err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if result := <-Srv.Store.Post().Overwrite(post); result.Err != nil {
|
||||||
|
return result.Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
|
||||||
|
if data.ChannelMembers == nil {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_required.error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*data.ChannelMembers) != 2 {
|
||||||
|
if len(*data.ChannelMembers) < model.CHANNEL_GROUP_MIN_USERS {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_too_few.error", nil, "")
|
||||||
|
} else if len(*data.ChannelMembers) > model.CHANNEL_GROUP_MAX_USERS {
|
||||||
|
return model.NewLocAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_too_many.error", nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.User == nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.user_missing.error", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Message == nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.message_missing.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else if utf8.RuneCountInString(*data.Message) > model.POST_MESSAGE_MAX_RUNES {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.message_length.error", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.CreateAt == nil {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.create_at_missing.error", nil, "", http.StatusBadRequest)
|
||||||
|
} else if *data.CreateAt == 0 {
|
||||||
|
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.create_at_zero.error", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// -- Old SlackImport Functions --
|
// -- Old SlackImport Functions --
|
||||||
// Import functions are sutible for entering posts and users into the database without
|
// Import functions are sutible for entering posts and users into the database without
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mattermost/platform/model"
|
|
||||||
"github.com/mattermost/platform/utils"
|
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/platform/model"
|
||||||
|
"github.com/mattermost/platform/store"
|
||||||
|
"github.com/mattermost/platform/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ptrStr(s string) *string {
|
func ptrStr(s string) *string {
|
||||||
@@ -571,6 +573,234 @@ func TestImportValidatePostImportData(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImportValidateDirectChannelImportData(t *testing.T) {
|
||||||
|
|
||||||
|
// Test with valid number of members for direct message.
|
||||||
|
data := DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := validateDirectChannelImportData(&data); err != nil {
|
||||||
|
t.Fatal("Validation failed but should have been valid.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with valid number of members for group message.
|
||||||
|
data = DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := validateDirectChannelImportData(&data); err != nil {
|
||||||
|
t.Fatal("Validation failed but should have been valid.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with all the combinations of optional parameters.
|
||||||
|
data = DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
Header: ptrStr("Channel Header Here"),
|
||||||
|
}
|
||||||
|
if err := validateDirectChannelImportData(&data); err != nil {
|
||||||
|
t.Fatal("Should have succeeded with valid optional properties.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with invalid Header.
|
||||||
|
data.Header = ptrStr(strings.Repeat("abcdefghij ", 103))
|
||||||
|
if err := validateDirectChannelImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to too long header.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with different combinations of invalid member counts.
|
||||||
|
data = DirectChannelImportData{
|
||||||
|
Members: &[]string{},
|
||||||
|
}
|
||||||
|
if err := validateDirectChannelImportData(&data); err == nil {
|
||||||
|
t.Fatal("Validation should have failed due to invalid number of members.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := validateDirectChannelImportData(&data); err == nil {
|
||||||
|
t.Fatal("Validation should have failed due to invalid number of members.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := validateDirectChannelImportData(&data); err == nil {
|
||||||
|
t.Fatal("Validation should have failed due to invalid number of members.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||||
|
|
||||||
|
// Test with minimum required valid properties.
|
||||||
|
data := DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err != nil {
|
||||||
|
t.Fatal("Validation failed but should have been valid.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with missing required properties.
|
||||||
|
data = DirectPostImportData{
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to missing required property.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to missing required property.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to missing required property.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to missing required property.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with invalid numbers of channel members.
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to unsuitable number of members.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to unsuitable number of members.")
|
||||||
|
}
|
||||||
|
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to unsuitable number of members.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with group message number of members.
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err != nil {
|
||||||
|
t.Fatal("Validation failed but should have been valid.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with invalid message.
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr(strings.Repeat("1234567890", 500)),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to too long message.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with invalid CreateAt
|
||||||
|
data = DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr("username"),
|
||||||
|
Message: ptrStr("message"),
|
||||||
|
CreateAt: ptrInt64(0),
|
||||||
|
}
|
||||||
|
if err := validateDirectPostImportData(&data); err == nil {
|
||||||
|
t.Fatal("Should have failed due to 0 create-at value.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestImportImportTeam(t *testing.T) {
|
func TestImportImportTeam(t *testing.T) {
|
||||||
_ = Setup()
|
_ = Setup()
|
||||||
|
|
||||||
@@ -1719,6 +1949,529 @@ func TestImportImportPost(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImportImportDirectChannel(t *testing.T) {
|
||||||
|
th := Setup().InitBasic()
|
||||||
|
|
||||||
|
// Check how many channels are in the database.
|
||||||
|
var directChannelCount int64
|
||||||
|
if r := <-Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_DIRECT); r.Err == nil {
|
||||||
|
directChannelCount = r.Data.(int64)
|
||||||
|
} else {
|
||||||
|
t.Fatalf("Failed to get direct channel count.")
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupChannelCount int64
|
||||||
|
if r := <-Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_GROUP); r.Err == nil {
|
||||||
|
groupChannelCount = r.Data.(int64)
|
||||||
|
} else {
|
||||||
|
t.Fatalf("Failed to get group channel count.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do an invalid channel in dry-run mode.
|
||||||
|
data := DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
Header: ptrStr("Channel Header"),
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, true); err == nil {
|
||||||
|
t.Fatalf("Expected error due to invalid name.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Do a valid DIRECT channel with a nonexistent member in dry-run mode.
|
||||||
|
data.Members = &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, true); err != nil {
|
||||||
|
t.Fatalf("Expected success as cannot validate existance of channel members in dry run mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Do a valid GROUP channel with a nonexistent member in dry-run mode.
|
||||||
|
data.Members = &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
model.NewId(),
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, true); err != nil {
|
||||||
|
t.Fatalf("Expected success as cannot validate existance of channel members in dry run mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Do an invalid channel in apply mode.
|
||||||
|
data.Members = &[]string{
|
||||||
|
model.NewId(),
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, false); err == nil {
|
||||||
|
t.Fatalf("Expected error due to invalid member (apply mode).")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Do a valid DIRECT channel.
|
||||||
|
data.Members = &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that one more DIRECT channel is in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Do the same DIRECT channel again.
|
||||||
|
if err := ImportDirectChannel(&data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Update the channel's HEADER
|
||||||
|
data.Header = ptrStr("New Channel Header 2")
|
||||||
|
if err := ImportDirectChannel(&data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Get the channel to check that the header was updated.
|
||||||
|
if channel, err := createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err == nil || err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
|
||||||
|
} else {
|
||||||
|
if channel.Header != *data.Header {
|
||||||
|
t.Fatal("Channel header has not been updated successfully.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a GROUP channel with an extra invalid member.
|
||||||
|
user3 := th.CreateUser()
|
||||||
|
data.Members = &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
model.NewId(),
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, false); err == nil {
|
||||||
|
t.Fatalf("Should have failed due to invalid member in list.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount)
|
||||||
|
|
||||||
|
// Do a valid GROUP channel.
|
||||||
|
data.Members = &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that one more GROUP channel is in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount+1)
|
||||||
|
|
||||||
|
// Do the same DIRECT channel again.
|
||||||
|
if err := ImportDirectChannel(&data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount+1)
|
||||||
|
|
||||||
|
// Update the channel's HEADER
|
||||||
|
data.Header = ptrStr("New Channel Header 3")
|
||||||
|
if err := ImportDirectChannel(&data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no more channels are in the DB.
|
||||||
|
AssertChannelCount(t, model.CHANNEL_DIRECT, directChannelCount+1)
|
||||||
|
AssertChannelCount(t, model.CHANNEL_GROUP, groupChannelCount+1)
|
||||||
|
|
||||||
|
// Get the channel to check that the header was updated.
|
||||||
|
userIds := []string{
|
||||||
|
th.BasicUser.Id,
|
||||||
|
th.BasicUser2.Id,
|
||||||
|
user3.Id,
|
||||||
|
}
|
||||||
|
if channel, err := createGroupChannel(userIds, th.BasicUser.Id); err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
|
||||||
|
} else {
|
||||||
|
if channel.Header != *data.Header {
|
||||||
|
t.Fatal("Channel header has not been updated successfully.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AssertChannelCount(t *testing.T, channelType string, expectedCount int64) {
|
||||||
|
if r := <-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 TestImportImportDirectPost(t *testing.T) {
|
||||||
|
th := Setup().InitBasic()
|
||||||
|
|
||||||
|
// Create the DIRECT channel.
|
||||||
|
channelData := DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&channelData, false); err != nil {
|
||||||
|
t.Fatalf("Expected success: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the channel.
|
||||||
|
var directChannel *model.Channel
|
||||||
|
if channel, err := createDirectChannel(th.BasicUser.Id, th.BasicUser2.Id); err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
|
||||||
|
} else {
|
||||||
|
directChannel = channel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the number of posts in the system.
|
||||||
|
var initialPostCount int64
|
||||||
|
if result := <-Srv.Store.Post().AnalyticsPostCount("", false, false); result.Err != nil {
|
||||||
|
t.Fatal(result.Err)
|
||||||
|
} else {
|
||||||
|
initialPostCount = result.Data.(int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try adding an invalid post in dry run mode.
|
||||||
|
data := &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, true); err == nil {
|
||||||
|
t.Fatalf("Expected error.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 0, "")
|
||||||
|
|
||||||
|
// Try adding a valid post in dry run mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
Message: ptrStr("Message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, true); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 0, "")
|
||||||
|
|
||||||
|
// Try adding an invalid post in apply mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
Message: ptrStr("Message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, false); err == nil {
|
||||||
|
t.Fatalf("Expected error.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 0, "")
|
||||||
|
|
||||||
|
// Try adding a valid post in apply mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
Message: ptrStr("Message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success: %v", err.Error())
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 1, "")
|
||||||
|
|
||||||
|
// Check the post values.
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
t.Fatal(result.Err.Error())
|
||||||
|
} else {
|
||||||
|
posts := result.Data.([]*model.Post)
|
||||||
|
if len(posts) != 1 {
|
||||||
|
t.Fatal("Unexpected number of posts found.")
|
||||||
|
}
|
||||||
|
post := posts[0]
|
||||||
|
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
|
||||||
|
t.Fatal("Post properties not as expected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import the post again.
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 1, "")
|
||||||
|
|
||||||
|
// Check the post values.
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
t.Fatal(result.Err.Error())
|
||||||
|
} else {
|
||||||
|
posts := result.Data.([]*model.Post)
|
||||||
|
if len(posts) != 1 {
|
||||||
|
t.Fatal("Unexpected number of posts found.")
|
||||||
|
}
|
||||||
|
post := posts[0]
|
||||||
|
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
|
||||||
|
t.Fatal("Post properties not as expected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the post with a different time.
|
||||||
|
data.CreateAt = ptrInt64(*data.CreateAt + 1)
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 2, "")
|
||||||
|
|
||||||
|
// Save the post with a different message.
|
||||||
|
data.Message = ptrStr("Message 2")
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 3, "")
|
||||||
|
|
||||||
|
// Test with hashtags
|
||||||
|
data.Message = ptrStr("Message 2 #hashtagmashupcity")
|
||||||
|
data.CreateAt = ptrInt64(*data.CreateAt + 1)
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 4, "")
|
||||||
|
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(directChannel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
t.Fatal(result.Err.Error())
|
||||||
|
} else {
|
||||||
|
posts := result.Data.([]*model.Post)
|
||||||
|
if len(posts) != 1 {
|
||||||
|
t.Fatal("Unexpected number of posts found.")
|
||||||
|
}
|
||||||
|
post := posts[0]
|
||||||
|
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
|
||||||
|
t.Fatal("Post properties not as expected")
|
||||||
|
}
|
||||||
|
if post.Hashtags != "#hashtagmashupcity" {
|
||||||
|
t.Fatalf("Hashtags not as expected: %s", post.Hashtags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------ Group Channel -------------------------
|
||||||
|
|
||||||
|
// Create the GROUP channel.
|
||||||
|
user3 := th.CreateUser()
|
||||||
|
channelData = DirectChannelImportData{
|
||||||
|
Members: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := ImportDirectChannel(&channelData, false); err != nil {
|
||||||
|
t.Fatalf("Expected success: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the channel.
|
||||||
|
var groupChannel *model.Channel
|
||||||
|
userIds := []string{
|
||||||
|
th.BasicUser.Id,
|
||||||
|
th.BasicUser2.Id,
|
||||||
|
user3.Id,
|
||||||
|
}
|
||||||
|
if channel, err := createGroupChannel(userIds, th.BasicUser.Id); err.Id != store.CHANNEL_EXISTS_ERROR {
|
||||||
|
t.Fatal("Should have got store.CHANNEL_EXISTS_ERROR")
|
||||||
|
} else {
|
||||||
|
groupChannel = channel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the number of posts in the system.
|
||||||
|
if result := <-Srv.Store.Post().AnalyticsPostCount("", false, false); result.Err != nil {
|
||||||
|
t.Fatal(result.Err)
|
||||||
|
} else {
|
||||||
|
initialPostCount = result.Data.(int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try adding an invalid post in dry run mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, true); err == nil {
|
||||||
|
t.Fatalf("Expected error.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 0, "")
|
||||||
|
|
||||||
|
// Try adding a valid post in dry run mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
Message: ptrStr("Message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, true); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 0, "")
|
||||||
|
|
||||||
|
// Try adding an invalid post in apply mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
model.NewId(),
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
Message: ptrStr("Message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, false); err == nil {
|
||||||
|
t.Fatalf("Expected error.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 0, "")
|
||||||
|
|
||||||
|
// Try adding a valid post in apply mode.
|
||||||
|
data = &DirectPostImportData{
|
||||||
|
ChannelMembers: &[]string{
|
||||||
|
th.BasicUser.Username,
|
||||||
|
th.BasicUser2.Username,
|
||||||
|
user3.Username,
|
||||||
|
},
|
||||||
|
User: ptrStr(th.BasicUser.Username),
|
||||||
|
Message: ptrStr("Message"),
|
||||||
|
CreateAt: ptrInt64(model.GetMillis()),
|
||||||
|
}
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success: %v", err.Error())
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 1, "")
|
||||||
|
|
||||||
|
// Check the post values.
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
t.Fatal(result.Err.Error())
|
||||||
|
} else {
|
||||||
|
posts := result.Data.([]*model.Post)
|
||||||
|
if len(posts) != 1 {
|
||||||
|
t.Fatal("Unexpected number of posts found.")
|
||||||
|
}
|
||||||
|
post := posts[0]
|
||||||
|
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
|
||||||
|
t.Fatal("Post properties not as expected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import the post again.
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 1, "")
|
||||||
|
|
||||||
|
// Check the post values.
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
t.Fatal(result.Err.Error())
|
||||||
|
} else {
|
||||||
|
posts := result.Data.([]*model.Post)
|
||||||
|
if len(posts) != 1 {
|
||||||
|
t.Fatal("Unexpected number of posts found.")
|
||||||
|
}
|
||||||
|
post := posts[0]
|
||||||
|
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
|
||||||
|
t.Fatal("Post properties not as expected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the post with a different time.
|
||||||
|
data.CreateAt = ptrInt64(*data.CreateAt + 1)
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 2, "")
|
||||||
|
|
||||||
|
// Save the post with a different message.
|
||||||
|
data.Message = ptrStr("Message 2")
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 3, "")
|
||||||
|
|
||||||
|
// Test with hashtags
|
||||||
|
data.Message = ptrStr("Message 2 #hashtagmashupcity")
|
||||||
|
data.CreateAt = ptrInt64(*data.CreateAt + 1)
|
||||||
|
if err := ImportDirectPost(data, false); err != nil {
|
||||||
|
t.Fatalf("Expected success.")
|
||||||
|
}
|
||||||
|
AssertAllPostsCount(t, initialPostCount, 4, "")
|
||||||
|
|
||||||
|
if result := <-Srv.Store.Post().GetPostsCreatedAt(groupChannel.Id, *data.CreateAt); result.Err != nil {
|
||||||
|
t.Fatal(result.Err.Error())
|
||||||
|
} else {
|
||||||
|
posts := result.Data.([]*model.Post)
|
||||||
|
if len(posts) != 1 {
|
||||||
|
t.Fatal("Unexpected number of posts found.")
|
||||||
|
}
|
||||||
|
post := posts[0]
|
||||||
|
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != th.BasicUser.Id {
|
||||||
|
t.Fatal("Post properties not as expected")
|
||||||
|
}
|
||||||
|
if post.Hashtags != "#hashtagmashupcity" {
|
||||||
|
t.Fatalf("Hashtags not as expected: %s", post.Hashtags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestImportImportLine(t *testing.T) {
|
func TestImportImportLine(t *testing.T) {
|
||||||
_ = Setup()
|
_ = Setup()
|
||||||
|
|
||||||
@@ -1754,6 +2507,18 @@ func TestImportImportLine(t *testing.T) {
|
|||||||
if err := ImportLine(line, false); err == nil {
|
if err := ImportLine(line, false); err == nil {
|
||||||
t.Fatalf("Expected an error when importing a line with type post with a nil post.")
|
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 := 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 := ImportLine(line, false); err == nil {
|
||||||
|
t.Fatalf("Expected an error when importing a line with type direct_post with a nil direct_post.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImportBulkImport(t *testing.T) {
|
func TestImportBulkImport(t *testing.T) {
|
||||||
@@ -1762,13 +2527,21 @@ func TestImportBulkImport(t *testing.T) {
|
|||||||
teamName := model.NewId()
|
teamName := model.NewId()
|
||||||
channelName := model.NewId()
|
channelName := model.NewId()
|
||||||
username := model.NewId()
|
username := model.NewId()
|
||||||
|
username2 := model.NewId()
|
||||||
|
username3 := model.NewId()
|
||||||
|
|
||||||
// Run bulk import with a valid 1 of everything.
|
// Run bulk import with a valid 1 of everything.
|
||||||
data1 := `{"type": "version", "version": 1}
|
data1 := `{"type": "version", "version": 1}
|
||||||
{"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}}
|
{"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}}
|
||||||
{"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}}
|
{"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}}
|
||||||
{"type": "user", "user": {"username": "` + username + `", "email": "` + username + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}}
|
{"type": "user", "user": {"username": "` + username + `", "email": "` + username + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}}
|
||||||
{"type": "post", "post": {"team": "` + teamName + `", "channel": "` + channelName + `", "user": "` + username + `", "message": "Hello World", "create_at": 123456789012}}`
|
{"type": "user", "user": {"username": "` + username2 + `", "email": "` + username2 + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}}
|
||||||
|
{"type": "user", "user": {"username": "` + username3 + `", "email": "` + username3 + `@example.com", "teams": [{"name": "` + teamName + `", "channels": [{"name": "` + channelName + `"}]}]}}
|
||||||
|
{"type": "post", "post": {"team": "` + teamName + `", "channel": "` + channelName + `", "user": "` + username + `", "message": "Hello World", "create_at": 123456789012}}
|
||||||
|
{"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": 123456789013}}
|
||||||
|
{"type": "direct_post", "direct_post": {"channel_members": ["` + username + `", "` + username2 + `", "` + username3 + `"], "user": "` + username + `", "message": "Hello Group Channel", "create_at": 123456789014}}`
|
||||||
|
|
||||||
if err, line := BulkImport(strings.NewReader(data1), false, 2); err != nil || line != 0 {
|
if err, line := BulkImport(strings.NewReader(data1), false, 2); err != nil || line != 0 {
|
||||||
t.Fatalf("BulkImport should have succeeded: %v, %v", err.Error(), line)
|
t.Fatalf("BulkImport should have succeeded: %v, %v", err.Error(), line)
|
||||||
|
|||||||
88
i18n/en.json
88
i18n/en.json
@@ -2967,10 +2967,50 @@
|
|||||||
"id": "app.import.import_channel.team_not_found.error",
|
"id": "app.import.import_channel.team_not_found.error",
|
||||||
"translation": "Error importing channel. Team with name \"{{.TeamName}}\" could not be found."
|
"translation": "Error importing channel. Team with name \"{{.TeamName}}\" could not be found."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_channel.member_not_found.error",
|
||||||
|
"translation": "Could not find channel member when importing direct channel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_channel.create_direct_channel.error",
|
||||||
|
"translation": "Failed to create direct channel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_channel.create_group_channel.error",
|
||||||
|
"translation": "Failed to create group channel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_channel.update_header_failed.error",
|
||||||
|
"translation": "Failed to update direct channel header"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_post.channel_member_not_found.error",
|
||||||
|
"translation": "Could not find channel member when importing direct channel post"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_channel.create_direct_channel.error",
|
||||||
|
"translation": "Failed to get direct channel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_channel.create_group_channel.error",
|
||||||
|
"translation": "Failed to get group channel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_direct_post.user_not_found.error",
|
||||||
|
"translation": "Post user does not exist"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "app.import.import_line.null_channel.error",
|
"id": "app.import.import_line.null_channel.error",
|
||||||
"translation": "Import data line has type \"channel\" but the channel object is null."
|
"translation": "Import data line has type \"channel\" but the channel object is null."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_line.null_direct_channel.error",
|
||||||
|
"translation": "Import data line has type \"direct_channel\" but the direct_channel object is null."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.import_line.null_direct_post.error",
|
||||||
|
"translation": "Import data line has type \"direct_post\" but the direct_post object is null."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "app.import.import_line.null_post.error",
|
"id": "app.import.import_line.null_post.error",
|
||||||
"translation": "Import data line has type \"post\" but the post object is null."
|
"translation": "Import data line has type \"post\" but the post object is null."
|
||||||
@@ -3043,6 +3083,54 @@
|
|||||||
"id": "app.import.validate_channel_import_data.type_missing.error",
|
"id": "app.import.validate_channel_import_data.type_missing.error",
|
||||||
"translation": "Missing required channel property: type."
|
"translation": "Missing required channel property: type."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_channel_import_data.members_required.error",
|
||||||
|
"translation": "Missing required direct channel property: members"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_channel_import_data.members_too_few.error",
|
||||||
|
"translation": "Direct channel members list contains too few items"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_channel_import_data.members_too_many.error",
|
||||||
|
"translation": "Direct channel members list contains too many items"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_channel_import_data.header_length.error",
|
||||||
|
"translation": "Direct channel header is too long"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.channel_members_required.error",
|
||||||
|
"translation": "Missing required direct post property: channel_members"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.channel_members_too_few.error",
|
||||||
|
"translation": "Direct post channel members list contains too few items"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.channel_members_too_many.error",
|
||||||
|
"translation": "Direct post channel members list contains too many items"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.user_missing.error",
|
||||||
|
"translation": "Missing required direct post property: user"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.message_missing.error",
|
||||||
|
"translation": "Missing required direct post property: message"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.message_length.error",
|
||||||
|
"translation": "Message is too long"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.create_at_missing.error",
|
||||||
|
"translation": "Missing required direct post property: create_at"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.import.validate_direct_post_import_data.create_at_zero.error",
|
||||||
|
"translation": "CreateAt must be greater than 0"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "app.import.validate_post_import_data.channel_missing.error",
|
"id": "app.import.validate_post_import_data.channel_missing.error",
|
||||||
"translation": "Missing required Post property: Channel."
|
"translation": "Missing required Post property: Channel."
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user