[XYZ-6] Add sampledata platform command (#8027)
* Add fake dependency * [XYZ-6] Add sampledata platform command * Creating EMOJI_NAME_MAX_LENGTH as a constant and using it where needed
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
0a9200c35d
Коммит
6990d052d5
236
app/import.go
236
app/import.go
@@ -9,6 +9,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -53,17 +54,18 @@ type ChannelImportData struct {
|
||||
}
|
||||
|
||||
type UserImportData struct {
|
||||
Username *string `json:"username"`
|
||||
Email *string `json:"email"`
|
||||
AuthService *string `json:"auth_service"`
|
||||
AuthData *string `json:"auth_data"`
|
||||
Password *string `json:"password"`
|
||||
Nickname *string `json:"nickname"`
|
||||
FirstName *string `json:"first_name"`
|
||||
LastName *string `json:"last_name"`
|
||||
Position *string `json:"position"`
|
||||
Roles *string `json:"roles"`
|
||||
Locale *string `json:"locale"`
|
||||
ProfileImage *string `json:"profile_image"`
|
||||
Username *string `json:"username"`
|
||||
Email *string `json:"email"`
|
||||
AuthService *string `json:"auth_service"`
|
||||
AuthData *string `json:"auth_data"`
|
||||
Password *string `json:"password"`
|
||||
Nickname *string `json:"nickname"`
|
||||
FirstName *string `json:"first_name"`
|
||||
LastName *string `json:"last_name"`
|
||||
Position *string `json:"position"`
|
||||
Roles *string `json:"roles"`
|
||||
Locale *string `json:"locale"`
|
||||
|
||||
Teams *[]UserTeamImportData `json:"teams"`
|
||||
|
||||
@@ -111,6 +113,22 @@ type UserChannelNotifyPropsImportData struct {
|
||||
MarkUnread *string `json:"mark_unread"`
|
||||
}
|
||||
|
||||
type ReactionImportData struct {
|
||||
User *string `json:"user"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
EmojiName *string `json:"emoji_name"`
|
||||
}
|
||||
|
||||
type ReplyImportData struct {
|
||||
User *string `json:"user"`
|
||||
|
||||
Message *string `json:"message"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
|
||||
FlaggedBy *[]string `json:"flagged_by"`
|
||||
Reactions *[]ReactionImportData `json:"reactions"`
|
||||
}
|
||||
|
||||
type PostImportData struct {
|
||||
Team *string `json:"team"`
|
||||
Channel *string `json:"channel"`
|
||||
@@ -119,7 +137,9 @@ type PostImportData struct {
|
||||
Message *string `json:"message"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
|
||||
FlaggedBy *[]string `json:"flagged_by"`
|
||||
FlaggedBy *[]string `json:"flagged_by"`
|
||||
Reactions *[]ReactionImportData `json:"reactions"`
|
||||
Replies *[]ReplyImportData `json:"replies"`
|
||||
}
|
||||
|
||||
type DirectChannelImportData struct {
|
||||
@@ -136,7 +156,9 @@ type DirectPostImportData struct {
|
||||
Message *string `json:"message"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
|
||||
FlaggedBy *[]string `json:"flagged_by"`
|
||||
FlaggedBy *[]string `json:"flagged_by"`
|
||||
Reactions *[]ReactionImportData `json:"reactions"`
|
||||
Replies *[]ReplyImportData `json:"replies"`
|
||||
}
|
||||
|
||||
type LineImportWorkerData struct {
|
||||
@@ -690,6 +712,16 @@ func (a *App) ImportUser(data *UserImportData, dryRun bool) *model.AppError {
|
||||
savedUser = user
|
||||
}
|
||||
|
||||
if data.ProfileImage != nil {
|
||||
file, err := os.Open(*data.ProfileImage)
|
||||
if err != nil {
|
||||
l4g.Error(utils.T("api.import.import_user.profile_image.error"), err)
|
||||
}
|
||||
if err := a.SetProfileImageFromFile(savedUser.Id, file); err != nil {
|
||||
l4g.Error(utils.T("api.import.import_user.profile_image.error"), err)
|
||||
}
|
||||
}
|
||||
|
||||
// Preferences.
|
||||
var preferences model.Preferences
|
||||
|
||||
@@ -869,6 +901,11 @@ func (a *App) ImportUserChannels(user *model.User, team *model.Team, teamMember
|
||||
}
|
||||
|
||||
func validateUserImportData(data *UserImportData) *model.AppError {
|
||||
if data.ProfileImage != nil {
|
||||
if _, err := os.Stat(*data.ProfileImage); os.IsNotExist(err) {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_user_import_data.profile_image.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if data.Username == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_user_import_data.username_missing.error", nil, "", http.StatusBadRequest)
|
||||
@@ -1019,6 +1056,79 @@ func validateUserChannelsImportData(data *[]UserChannelImportData) *model.AppErr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) ImportReaction(data *ReactionImportData, post *model.Post, dryRun bool) *model.AppError {
|
||||
if err := validateReactionImportData(data, post.CreateAt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-a.Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
|
||||
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, "", http.StatusBadRequest)
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
reaction := &model.Reaction{
|
||||
UserId: user.Id,
|
||||
PostId: post.Id,
|
||||
EmojiName: *data.EmojiName,
|
||||
CreateAt: *data.CreateAt,
|
||||
}
|
||||
if result := <-a.Srv.Store.Reaction().Save(reaction); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) ImportReply(data *ReplyImportData, post *model.Post, dryRun bool) *model.AppError {
|
||||
if err := validateReplyImportData(data, post.CreateAt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-a.Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
|
||||
return model.NewAppError("BulkImport", "app.import.import_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 replies []*model.Post
|
||||
if result := <-a.Srv.Store.Post().GetPostsCreatedAt(post.ChannelId, *data.CreateAt); result.Err != nil {
|
||||
return result.Err
|
||||
} else {
|
||||
replies = result.Data.([]*model.Post)
|
||||
}
|
||||
|
||||
var reply *model.Post
|
||||
for _, r := range replies {
|
||||
if r.Message == *data.Message {
|
||||
reply = r
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if reply == nil {
|
||||
reply = &model.Post{}
|
||||
}
|
||||
reply.UserId = user.Id
|
||||
reply.ChannelId = post.ChannelId
|
||||
reply.ParentId = post.Id
|
||||
reply.RootId = post.Id
|
||||
reply.Message = *data.Message
|
||||
reply.CreateAt = *data.CreateAt
|
||||
|
||||
if reply.Id == "" {
|
||||
if result := <-a.Srv.Store.Post().Save(reply); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
} else {
|
||||
if result := <-a.Srv.Store.Post().Overwrite(reply); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError {
|
||||
if err := validatePostImportData(data); err != nil {
|
||||
return err
|
||||
@@ -1114,6 +1224,66 @@ func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError {
|
||||
}
|
||||
}
|
||||
|
||||
if data.Reactions != nil {
|
||||
for _, reaction := range *data.Reactions {
|
||||
if err := a.ImportReaction(&reaction, post, dryRun); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if data.Replies != nil {
|
||||
for _, reply := range *data.Replies {
|
||||
if err := a.ImportReply(&reply, post, dryRun); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateReactionImportData(data *ReactionImportData, parentCreateAt int64) *model.AppError {
|
||||
if data.User == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reaction_import_data.user_missing.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if data.EmojiName == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reaction_import_data.emoji_name_missing.error", nil, "", http.StatusBadRequest)
|
||||
} else if utf8.RuneCountInString(*data.EmojiName) > model.EMOJI_NAME_MAX_LENGTH {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reaction_import_data.emoji_name_length.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if data.CreateAt == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reaction_import_data.create_at_missing.error", nil, "", http.StatusBadRequest)
|
||||
} else if *data.CreateAt == 0 {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reaction_import_data.create_at_zero.error", nil, "", http.StatusBadRequest)
|
||||
} else if *data.CreateAt < parentCreateAt {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reaction_import_data.create_at_before_parent.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateReplyImportData(data *ReplyImportData, parentCreateAt int64) *model.AppError {
|
||||
if data.User == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.user_missing.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if data.Message == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_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_reply_import_data.message_length.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if data.CreateAt == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.create_at_missing.error", nil, "", http.StatusBadRequest)
|
||||
} else if *data.CreateAt == 0 {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.create_at_zero.error", nil, "", http.StatusBadRequest)
|
||||
} else if *data.CreateAt < parentCreateAt {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.create_at_before_parent.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1142,6 +1312,18 @@ func validatePostImportData(data *PostImportData) *model.AppError {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_post_import_data.create_at_zero.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if data.Reactions != nil {
|
||||
for _, reaction := range *data.Reactions {
|
||||
validateReactionImportData(&reaction, *data.CreateAt)
|
||||
}
|
||||
}
|
||||
|
||||
if data.Replies != nil {
|
||||
for _, reply := range *data.Replies {
|
||||
validateReplyImportData(&reply, *data.CreateAt)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1365,6 +1547,22 @@ func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.A
|
||||
}
|
||||
}
|
||||
|
||||
if data.Reactions != nil {
|
||||
for _, reaction := range *data.Reactions {
|
||||
if err := a.ImportReaction(&reaction, post, dryRun); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if data.Replies != nil {
|
||||
for _, reply := range *data.Replies {
|
||||
if err := a.ImportReply(&reply, post, dryRun); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1412,6 +1610,18 @@ func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
|
||||
}
|
||||
}
|
||||
|
||||
if data.Reactions != nil {
|
||||
for _, reaction := range *data.Reactions {
|
||||
validateReactionImportData(&reaction, *data.CreateAt)
|
||||
}
|
||||
}
|
||||
|
||||
if data.Replies != nil {
|
||||
for _, reply := range *data.Replies {
|
||||
validateReplyImportData(&reply, *data.CreateAt)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/store"
|
||||
"github.com/mattermost/mattermost-server/utils"
|
||||
)
|
||||
|
||||
func ptrStr(s string) *string {
|
||||
@@ -325,6 +326,13 @@ func TestImportValidateUserImportData(t *testing.T) {
|
||||
|
||||
data.Username = ptrStr("bob")
|
||||
|
||||
// Unexisting Picture Image
|
||||
data.ProfileImage = ptrStr("not-existing-file")
|
||||
if err := validateUserImportData(&data); err == nil {
|
||||
t.Fatal("Validation should have failed due to not existing profile image file.")
|
||||
}
|
||||
data.ProfileImage = nil
|
||||
|
||||
// Invalid Emails
|
||||
data.Email = nil
|
||||
if err := validateUserImportData(&data); err == nil {
|
||||
@@ -360,17 +368,19 @@ func TestImportValidateUserImportData(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test a valid User with all fields populated.
|
||||
testsDir, _ := utils.FindDir("tests")
|
||||
data = UserImportData{
|
||||
Username: ptrStr("bob"),
|
||||
Email: ptrStr("bob@example.com"),
|
||||
AuthService: ptrStr("ldap"),
|
||||
AuthData: ptrStr("bob"),
|
||||
Nickname: ptrStr("BobNick"),
|
||||
FirstName: ptrStr("Bob"),
|
||||
LastName: ptrStr("Blob"),
|
||||
Position: ptrStr("The Boss"),
|
||||
Roles: ptrStr("system_user"),
|
||||
Locale: ptrStr("en"),
|
||||
ProfileImage: ptrStr(testsDir + "test.png"),
|
||||
Username: ptrStr("bob"),
|
||||
Email: ptrStr("bob@example.com"),
|
||||
AuthService: ptrStr("ldap"),
|
||||
AuthData: ptrStr("bob"),
|
||||
Nickname: ptrStr("BobNick"),
|
||||
FirstName: ptrStr("Bob"),
|
||||
LastName: ptrStr("Blob"),
|
||||
Position: ptrStr("The Boss"),
|
||||
Roles: ptrStr("system_user"),
|
||||
Locale: ptrStr("en"),
|
||||
}
|
||||
if err := validateUserImportData(&data); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
@@ -563,6 +573,140 @@ func TestImportValidateUserChannelsImportData(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportValidateReactionImportData(t *testing.T) {
|
||||
// Test with minimum required valid properties.
|
||||
parentCreateAt := model.GetMillis() - 100
|
||||
data := ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
}
|
||||
|
||||
// Test with missing required properties.
|
||||
data = ReactionImportData{
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
// Test with invalid emoji name.
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr(strings.Repeat("1234567890", 500)),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to too long emoji name.")
|
||||
}
|
||||
|
||||
// Test with invalid CreateAt
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(0),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to 0 create-at value.")
|
||||
}
|
||||
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(parentCreateAt - 100),
|
||||
}
|
||||
if err := validateReactionImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due parent with newer create-at value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportValidateReplyImportData(t *testing.T) {
|
||||
// Test with minimum required valid properties.
|
||||
parentCreateAt := model.GetMillis() - 100
|
||||
data := ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
}
|
||||
|
||||
// Test with missing required properties.
|
||||
data = ReplyImportData{
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
data = ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
data = ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
// Test with invalid message.
|
||||
data = ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr(strings.Repeat("1234567890", 500)),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to too long message.")
|
||||
}
|
||||
|
||||
// Test with invalid CreateAt
|
||||
data = ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(0),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due to 0 create-at value.")
|
||||
}
|
||||
|
||||
data = ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(parentCreateAt - 100),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
t.Fatal("Should have failed due parent with newer create-at value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportValidatePostImportData(t *testing.T) {
|
||||
|
||||
// Test with minimum required valid properties.
|
||||
@@ -653,12 +797,24 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test with valid all optional parameters.
|
||||
data = PostImportData{
|
||||
Team: ptrStr("teamname"),
|
||||
Channel: ptrStr("channelname"),
|
||||
reactions := []ReactionImportData{ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
replies := []ReplyImportData{ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
data = PostImportData{
|
||||
Team: ptrStr("teamname"),
|
||||
Channel: ptrStr("channelname"),
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
Reactions: &reactions,
|
||||
Replies: &replies,
|
||||
}
|
||||
if err := validatePostImportData(&data); err != nil {
|
||||
t.Fatal("Should have succeeded.")
|
||||
@@ -961,6 +1117,37 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
if err := validateDirectPostImportData(&data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test with valid all optional parameters.
|
||||
reactions := []ReactionImportData{ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
replies := []ReplyImportData{ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
data = DirectPostImportData{
|
||||
ChannelMembers: &[]string{
|
||||
member1,
|
||||
member2,
|
||||
},
|
||||
FlaggedBy: &[]string{
|
||||
member1,
|
||||
member2,
|
||||
},
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
Reactions: &reactions,
|
||||
Replies: &replies,
|
||||
}
|
||||
|
||||
if err := validateDirectPostImportData(&data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportImportTeam(t *testing.T) {
|
||||
@@ -1298,13 +1485,15 @@ func TestImportImportUser(t *testing.T) {
|
||||
|
||||
// Do a valid user in apply mode.
|
||||
username := model.NewId()
|
||||
testsDir, _ := utils.FindDir("tests")
|
||||
data = UserImportData{
|
||||
Username: &username,
|
||||
Email: ptrStr(model.NewId() + "@example.com"),
|
||||
Nickname: ptrStr(model.NewId()),
|
||||
FirstName: ptrStr(model.NewId()),
|
||||
LastName: ptrStr(model.NewId()),
|
||||
Position: ptrStr(model.NewId()),
|
||||
ProfileImage: ptrStr(testsDir + "test.png"),
|
||||
Username: &username,
|
||||
Email: ptrStr(model.NewId() + "@example.com"),
|
||||
Nickname: ptrStr(model.NewId()),
|
||||
FirstName: ptrStr(model.NewId()),
|
||||
LastName: ptrStr(model.NewId()),
|
||||
Position: ptrStr(model.NewId()),
|
||||
}
|
||||
if err := th.App.ImportUser(&data, false); err != nil {
|
||||
t.Fatalf("Should have succeeded to import valid user.")
|
||||
@@ -1354,6 +1543,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
|
||||
// Alter all the fields of that user.
|
||||
data.Email = ptrStr(model.NewId() + "@example.com")
|
||||
data.ProfileImage = ptrStr(testsDir + "testgif.gif")
|
||||
data.AuthService = ptrStr("ldap")
|
||||
data.AuthData = &username
|
||||
data.Nickname = ptrStr(model.NewId())
|
||||
@@ -2189,6 +2379,98 @@ func TestImportImportPost(t *testing.T) {
|
||||
checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
|
||||
checkPreference(t, th.App, user2.Id, model.PREFERENCE_CATEGORY_FLAGGED_POST, post.Id, "true")
|
||||
}
|
||||
|
||||
// Post with reaction.
|
||||
reactionPostTime := hashtagTime + 2
|
||||
reactionTime := hashtagTime + 3
|
||||
data = &PostImportData{
|
||||
Team: &teamName,
|
||||
Channel: &channelName,
|
||||
User: &username,
|
||||
Message: ptrStr("Message with reaction"),
|
||||
CreateAt: &reactionPostTime,
|
||||
Reactions: &[]ReactionImportData{{
|
||||
User: &user2.Username,
|
||||
EmojiName: ptrStr("+1"),
|
||||
CreateAt: &reactionTime,
|
||||
}},
|
||||
}
|
||||
if err := th.App.ImportPost(data, false); err != nil {
|
||||
t.Fatalf("Expected success.")
|
||||
}
|
||||
AssertAllPostsCount(t, th.App, initialPostCount, 6, team.Id)
|
||||
|
||||
// Check the post values.
|
||||
if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, reactionPostTime); result.Err != nil {
|
||||
t.Fatal(result.Err.Error())
|
||||
} else {
|
||||
posts := result.Data.([]*model.Post)
|
||||
if len(posts) != 1 {
|
||||
t.Fatal("Unexpected number of posts found.")
|
||||
}
|
||||
post := posts[0]
|
||||
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id || !post.HasReactions {
|
||||
t.Fatal("Post properties not as expected")
|
||||
}
|
||||
|
||||
if result := <-th.App.Srv.Store.Reaction().GetForPost(post.Id, false); result.Err != nil {
|
||||
t.Fatal("Can't get reaction")
|
||||
} else if len(result.Data.([]*model.Reaction)) != 1 {
|
||||
t.Fatal("Invalid number of reactions")
|
||||
}
|
||||
}
|
||||
|
||||
// Post with reply.
|
||||
replyPostTime := hashtagTime + 4
|
||||
replyTime := hashtagTime + 5
|
||||
data = &PostImportData{
|
||||
Team: &teamName,
|
||||
Channel: &channelName,
|
||||
User: &username,
|
||||
Message: ptrStr("Message with reply"),
|
||||
CreateAt: &replyPostTime,
|
||||
Replies: &[]ReplyImportData{{
|
||||
User: &user2.Username,
|
||||
Message: ptrStr("Message reply"),
|
||||
CreateAt: &replyTime,
|
||||
}},
|
||||
}
|
||||
if err := th.App.ImportPost(data, false); err != nil {
|
||||
t.Fatalf("Expected success.")
|
||||
}
|
||||
AssertAllPostsCount(t, th.App, initialPostCount, 8, team.Id)
|
||||
|
||||
// Check the post values.
|
||||
if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyPostTime); result.Err != nil {
|
||||
t.Fatal(result.Err.Error())
|
||||
} else {
|
||||
posts := result.Data.([]*model.Post)
|
||||
if len(posts) != 1 {
|
||||
t.Fatal("Unexpected number of posts found.")
|
||||
}
|
||||
post := posts[0]
|
||||
if post.Message != *data.Message || post.CreateAt != *data.CreateAt || post.UserId != user.Id {
|
||||
t.Fatal("Post properties not as expected")
|
||||
}
|
||||
|
||||
// Check the reply values.
|
||||
if result := <-th.App.Srv.Store.Post().GetPostsCreatedAt(channel.Id, replyTime); result.Err != nil {
|
||||
t.Fatal(result.Err.Error())
|
||||
} else {
|
||||
replies := result.Data.([]*model.Post)
|
||||
if len(replies) != 1 {
|
||||
t.Fatal("Unexpected number of posts found.")
|
||||
}
|
||||
reply := replies[0]
|
||||
if reply.Message != *(*data.Replies)[0].Message || reply.CreateAt != *(*data.Replies)[0].CreateAt || reply.UserId != user2.Id {
|
||||
t.Fatal("Post properties not as expected")
|
||||
}
|
||||
|
||||
if reply.RootId != post.Id {
|
||||
t.Fatal("Unexpected reply RootId")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportImportDirectChannel(t *testing.T) {
|
||||
|
||||
@@ -778,7 +778,10 @@ func (a *App) SetProfileImage(userId string, imageData *multipart.FileHeader) *m
|
||||
return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.open.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
defer file.Close()
|
||||
return a.SetProfileImageFromFile(userId, file)
|
||||
}
|
||||
|
||||
func (a *App) SetProfileImageFromFile(userId string, file multipart.File) *model.AppError {
|
||||
// Decode image config first to check dimensions before loading the whole thing into memory later on
|
||||
config, _, err := image.DecodeConfig(file)
|
||||
if err != nil {
|
||||
|
||||
Ссылка в новой задаче
Block a user