From c8198fbefe30c7b9aae19b80e8869af393e6073d Mon Sep 17 00:00:00 2001 From: Yusuke Nemoto Date: Sat, 8 Jan 2022 13:07:07 +0900 Subject: [PATCH] Added support for exporting and importing the type and edit_at of a post (#18992) * feat: add Type/EditAt field to PostImportData * test: add tests * feat: add Type/EditAt field to ReplyImportData * chore: fix lint error * test: fix failed tests * test: refactoring * test: fix how to assertion * test: fix failed case which depends on accidental order of replies --- app/export_converters.go | 6 ++ app/import_functions.go | 18 ++++ app/import_functions_test.go | 199 ++++++++++++++++++++++++++++++++++- app/import_types.go | 6 ++ 4 files changed, 224 insertions(+), 5 deletions(-) diff --git a/app/export_converters.go b/app/export_converters.go index 027d453d9c..42fa164491 100644 --- a/app/export_converters.go +++ b/app/export_converters.go @@ -155,9 +155,11 @@ func ImportLineForPost(post *model.PostForExport) *LineImportData { Team: &post.TeamName, Channel: &post.ChannelName, User: &post.Username, + Type: &post.Type, Message: &post.Message, Props: &post.Props, CreateAt: &post.CreateAt, + EditAt: &post.EditAt, }, } } @@ -172,9 +174,11 @@ func ImportLineForDirectPost(post *model.DirectPostForExport) *LineImportData { DirectPost: &DirectPostImportData{ ChannelMembers: &channelMembers, User: &post.User, + Type: &post.Type, Message: &post.Message, Props: &post.Props, CreateAt: &post.CreateAt, + EditAt: &post.EditAt, }, } } @@ -182,8 +186,10 @@ func ImportLineForDirectPost(post *model.DirectPostForExport) *LineImportData { func ImportReplyFromPost(post *model.ReplyForExport) *ReplyImportData { return &ReplyImportData{ User: &post.Username, + Type: &post.Type, Message: &post.Message, CreateAt: &post.CreateAt, + EditAt: &post.EditAt, } } diff --git a/app/import_functions.go b/app/import_functions.go index 3dd67aeec7..ee684980f4 100644 --- a/app/import_functions.go +++ b/app/import_functions.go @@ -1118,6 +1118,12 @@ func (a *App) importReplies(c *request.Context, data []ReplyImportData, post *mo reply.RootId = post.Id reply.Message = *replyData.Message reply.CreateAt = *replyData.CreateAt + if replyData.Type != nil { + reply.Type = *replyData.Type + } + if replyData.EditAt != nil { + reply.EditAt = *replyData.EditAt + } fileIDs := a.uploadAttachments(c, replyData.Attachments, reply, teamID) for _, fileID := range reply.FileIds { @@ -1392,6 +1398,12 @@ func (a *App) importMultiplePostLines(c *request.Context, lines []LineImportWork post.CreateAt = *line.Post.CreateAt post.Hashtags, _ = model.ParseHashtags(post.Message) + if line.Post.Type != nil { + post.Type = *line.Post.Type + } + if line.Post.EditAt != nil { + post.EditAt = *line.Post.EditAt + } if line.Post.Props != nil { post.Props = *line.Post.Props } @@ -1694,6 +1706,12 @@ func (a *App) importMultipleDirectPostLines(c *request.Context, lines []LineImpo post.CreateAt = *line.DirectPost.CreateAt post.Hashtags, _ = model.ParseHashtags(post.Message) + if line.DirectPost.Type != nil { + post.Type = *line.DirectPost.Type + } + if line.DirectPost.EditAt != nil { + post.EditAt = *line.DirectPost.EditAt + } if line.DirectPost.Props != nil { post.Props = *line.DirectPost.Props } diff --git a/app/import_functions_test.go b/app/import_functions_test.go index 833fa844e8..948fe84e83 100644 --- a/app/import_functions_test.go +++ b/app/import_functions_test.go @@ -2408,6 +2408,46 @@ func TestImportimportMultiplePostLines(t *testing.T) { AssertAllPostsCount(t, th.App, initialPostCount, 11, team.Id) + // Create new reply with type and edit_at for existing post with replies. + + // Post with reply. + editedReplyPostTime := hashtagTime + 6 + editedReplyTime := hashtagTime + 7 + editedReplyEditTime := hashtagTime + 8 + + data = LineImportWorkerData{ + LineImportData{ + Post: &PostImportData{ + Team: &teamName, + Channel: &channelName, + User: &user2.Username, + Message: ptrStr("Message with reply"), + CreateAt: &editedReplyPostTime, + Replies: &[]ReplyImportData{{ + User: &username, + Type: ptrStr(model.PostTypeSystemGeneric), + Message: ptrStr("Message reply 3"), + CreateAt: &editedReplyTime, + EditAt: &editedReplyEditTime, + }}, + }, + }, + 1, + } + errLine, err = th.App.importMultiplePostLines(th.Context, []LineImportWorkerData{data}, false) + assert.Nil(t, err, "Expected success.") + assert.Equal(t, 0, errLine) + + AssertAllPostsCount(t, th.App, initialPostCount, 13, team.Id) + + // Check the reply values. + replies, nErr = th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, editedReplyTime) + assert.NoError(t, nErr, "Expected success.") + reply = replies[0] + importReply := (*data.Post.Replies)[0] + replyBool = reply.Type != *importReply.Type || reply.Message != *importReply.Message || reply.CreateAt != *importReply.CreateAt || reply.EditAt != *importReply.EditAt || reply.UserId != user.Id + require.False(t, replyBool, "Post properties not as expected") + // Create another Team. teamName2 := model.NewRandomTeamName() th.App.importTeam(th.Context, &TeamImportData{ @@ -2463,7 +2503,7 @@ func TestImportimportMultiplePostLines(t *testing.T) { // Posts should be added to the right team AssertAllPostsCount(t, th.App, initialPostCountForTeam2, 1, team2.Id) - AssertAllPostsCount(t, th.App, initialPostCount, 12, team.Id) + AssertAllPostsCount(t, th.App, initialPostCount, 14, team.Id) } func TestImportImportPost(t *testing.T) { @@ -2517,6 +2557,9 @@ func TestImportImportPost(t *testing.T) { hashtagTime := time + 2 replyPostTime := hashtagTime + 4 replyTime := hashtagTime + 5 + posttypeTime := hashtagTime + 6 + editatCreateTime := hashtagTime + 7 + editatEditTime := hashtagTime + 8 t.Run("Try adding an invalid post in dry run mode", func(t *testing.T) { data := LineImportWorkerData{ @@ -2958,6 +3001,70 @@ func TestImportImportPost(t *testing.T) { AssertAllPostsCount(t, th.App, initialPostCount, 11, team.Id) }) + + t.Run("Post with Type", func(t *testing.T) { + data := LineImportWorkerData{ + LineImportData{ + Post: &PostImportData{ + Team: &teamName, + Channel: &channelName, + User: &username, + Type: ptrStr(model.PostTypeSystemGeneric), + Message: ptrStr("Message with Type"), + CreateAt: &posttypeTime, + }, + }, + 1, + } + + errLine, err := th.App.importMultiplePostLines(th.Context, []LineImportWorkerData{data}, false) + require.Nil(t, err, "Expected success.") + require.Equal(t, 0, errLine) + + AssertAllPostsCount(t, th.App, initialPostCount, 12, team.Id) + + // Check the post values. + posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, posttypeTime) + require.NoError(t, nErr) + + require.Len(t, posts, 1, "Unexpected number of posts found.") + + post := posts[0] + postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id || post.Type != *data.Post.Type + require.False(t, postBool, "Post properties not as expected") + }) + + t.Run("Post with EditAt", func(t *testing.T) { + data := LineImportWorkerData{ + LineImportData{ + Post: &PostImportData{ + Team: &teamName, + Channel: &channelName, + User: &username, + Message: ptrStr("Message with Type"), + CreateAt: &editatCreateTime, + EditAt: &editatEditTime, + }, + }, + 1, + } + + errLine, err := th.App.importMultiplePostLines(th.Context, []LineImportWorkerData{data}, false) + require.Nil(t, err, "Expected success.") + require.Equal(t, 0, errLine) + + AssertAllPostsCount(t, th.App, initialPostCount, 13, team.Id) + + // Check the post values. + posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, editatCreateTime) + require.NoError(t, nErr) + + require.Len(t, posts, 1, "Unexpected number of posts found.") + + post := posts[0] + postBool := post.Message != *data.Post.Message || post.CreateAt != *data.Post.CreateAt || post.UserId != user.Id || post.EditAt != *data.Post.EditAt + require.False(t, postBool, "Post properties not as expected") + }) } func TestImportImportDirectChannel(t *testing.T) { @@ -3154,6 +3261,9 @@ func TestImportImportDirectPost(t *testing.T) { require.NoError(t, err) initialPostCount := result initialDate := model.GetMillis() + posttypeDate := initialDate + 3 + editatCreateDate := initialDate + 4 + editatEditDate := initialDate + 5 t.Run("Try adding an invalid post in dry run mode", func(t *testing.T) { data := LineImportWorkerData{ @@ -3375,6 +3485,7 @@ func TestImportImportDirectPost(t *testing.T) { errLine, err := th.App.importMultipleDirectPostLines(th.Context, []LineImportWorkerData{data}, false) require.Nil(t, err) require.Equal(t, 0, errLine) + AssertAllPostsCount(t, th.App, initialPostCount, 5, "") // Check the post values. posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt) @@ -3386,6 +3497,70 @@ func TestImportImportDirectPost(t *testing.T) { checkPreference(t, th.App, th.BasicUser2.Id, model.PreferenceCategoryFlaggedPost, post.Id, "true") }) + t.Run("Test with Type", func(t *testing.T) { + data := LineImportWorkerData{ + LineImportData{ + DirectPost: &DirectPostImportData{ + ChannelMembers: &[]string{ + th.BasicUser.Username, + th.BasicUser2.Username, + }, + User: ptrStr(th.BasicUser.Username), + Type: ptrStr(model.PostTypeSystemGeneric), + Message: ptrStr("Message with Type"), + CreateAt: ptrInt64(posttypeDate), + }, + }, + 1, + } + errLine, err := th.App.importMultipleDirectPostLines(th.Context, []LineImportWorkerData{data}, false) + require.Nil(t, err) + require.Equal(t, 0, errLine) + AssertAllPostsCount(t, th.App, initialPostCount, 6, "") + + posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt) + require.NoError(t, nErr) + require.Len(t, posts, 1) + + post := posts[0] + assert.Equal(t, post.Type, *data.DirectPost.Type) + assert.Equal(t, post.Message, *data.DirectPost.Message) + assert.Equal(t, post.CreateAt, *data.DirectPost.CreateAt) + assert.Equal(t, post.UserId, th.BasicUser.Id) + }) + + t.Run("Test with EditAt", func(t *testing.T) { + data := LineImportWorkerData{ + LineImportData{ + DirectPost: &DirectPostImportData{ + ChannelMembers: &[]string{ + th.BasicUser.Username, + th.BasicUser2.Username, + }, + User: ptrStr(th.BasicUser.Username), + Message: ptrStr("Message with EditAt"), + CreateAt: ptrInt64(editatCreateDate), + EditAt: ptrInt64(editatEditDate), + }, + }, + 1, + } + errLine, err := th.App.importMultipleDirectPostLines(th.Context, []LineImportWorkerData{data}, false) + require.Nil(t, err) + require.Equal(t, 0, errLine) + AssertAllPostsCount(t, th.App, initialPostCount, 7, "") + + posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(directChannel.Id, *data.DirectPost.CreateAt) + require.NoError(t, nErr) + require.Len(t, posts, 1) + + post := posts[0] + assert.Equal(t, post.Message, *data.DirectPost.Message) + assert.Equal(t, post.CreateAt, *data.DirectPost.CreateAt) + assert.Equal(t, post.EditAt, *data.DirectPost.EditAt) + assert.Equal(t, post.UserId, th.BasicUser.Id) + }) + // ------------------ Group Channel ------------------------- // Create the GROUP channel. @@ -3816,9 +3991,10 @@ func TestImportImportDirectPost(t *testing.T) { AssertAllPostsCount(t, th.App, initialPostCount, 10, "") }) - t.Run("Create new reply for existing post with replies", func(t *testing.T) { - replyPostTime := ptrInt64(initialDate + 25) - replyTime := ptrInt64(initialDate + 29) + t.Run("Post with reply having non-empty type and edit_at", func(t *testing.T) { + replyPostTime := ptrInt64(initialDate + 29) + replyTime := ptrInt64(initialDate + 30) + replyEditTime := ptrInt64(initialDate + 31) data := LineImportWorkerData{ LineImportData{ DirectPost: &DirectPostImportData{ @@ -3832,8 +4008,10 @@ func TestImportImportDirectPost(t *testing.T) { CreateAt: replyPostTime, Replies: &[]ReplyImportData{{ User: ptrStr(th.BasicUser.Username), + Type: ptrStr(model.PostTypeSystemGeneric), Message: ptrStr("Message reply 2"), CreateAt: replyTime, + EditAt: replyEditTime, }}, }, }, @@ -3843,7 +4021,18 @@ func TestImportImportDirectPost(t *testing.T) { require.Nil(t, err, "Expected success.") require.Equal(t, 0, errLine) - AssertAllPostsCount(t, th.App, initialPostCount, 11, "") + AssertAllPostsCount(t, th.App, initialPostCount, 12, "") + + // Check the reply values. + replies, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, *replyTime) + require.NoError(t, nErr) + + require.Len(t, replies, 1, "Unexpected number of posts found.") + + reply := replies[0] + importReply := (*data.DirectPost.Replies)[0] + replyBool := reply.Type != *importReply.Type || reply.Message != *importReply.Message || reply.CreateAt != *importReply.CreateAt || reply.EditAt != *importReply.EditAt || reply.UserId != th.BasicUser.Id + require.False(t, replyBool, "Post properties not as expected") }) } diff --git a/app/import_types.go b/app/import_types.go index 25b4c23c90..d7e4795570 100644 --- a/app/import_types.go +++ b/app/import_types.go @@ -124,8 +124,10 @@ type ReactionImportData struct { type ReplyImportData struct { User *string `json:"user"` + Type *string `json:"type"` Message *string `json:"message"` CreateAt *int64 `json:"create_at"` + EditAt *int64 `json:"edit_at"` FlaggedBy *[]string `json:"flagged_by,omitempty"` Reactions *[]ReactionImportData `json:"reactions,omitempty"` @@ -137,9 +139,11 @@ type PostImportData struct { Channel *string `json:"channel"` User *string `json:"user"` + Type *string `json:"type"` Message *string `json:"message"` Props *model.StringInterface `json:"props"` CreateAt *int64 `json:"create_at"` + EditAt *int64 `json:"edit_at"` FlaggedBy *[]string `json:"flagged_by,omitempty"` Reactions *[]ReactionImportData `json:"reactions,omitempty"` @@ -158,9 +162,11 @@ type DirectPostImportData struct { ChannelMembers *[]string `json:"channel_members"` User *string `json:"user"` + Type *string `json:"type"` Message *string `json:"message"` Props *model.StringInterface `json:"props"` CreateAt *int64 `json:"create_at"` + EditAt *int64 `json:"edit_at"` FlaggedBy *[]string `json:"flagged_by"` Reactions *[]ReactionImportData `json:"reactions"`