add support for exporting and importing props (#14034)
* add support for exporting and importing props * merge master * add export test for post props * add check if postData exists * add import tests for post props * fix ci bot issues Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * fix gofmt errors * remove test comment and add name instead * remove uneccessary changes Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com>
Этот коммит содержится в:
@@ -156,6 +156,7 @@ func ImportLineForPost(post *model.PostForExport) *LineImportData {
|
||||
Channel: &post.ChannelName,
|
||||
User: &post.Username,
|
||||
Message: &post.Message,
|
||||
Props: &post.Props,
|
||||
CreateAt: &post.CreateAt,
|
||||
},
|
||||
}
|
||||
@@ -172,6 +173,7 @@ func ImportLineForDirectPost(post *model.DirectPostForExport) *LineImportData {
|
||||
ChannelMembers: &channelMembers,
|
||||
User: &post.User,
|
||||
Message: &post.Message,
|
||||
Props: &post.Props,
|
||||
CreateAt: &post.CreateAt,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -446,6 +446,81 @@ func TestExportDMandGMPost(t *testing.T) {
|
||||
assert.ElementsMatch(t, dmMembers, *posts[3].ChannelMembers)
|
||||
}
|
||||
|
||||
func TestExportPostWithProps(t *testing.T) {
|
||||
th1 := Setup(t).InitBasic()
|
||||
|
||||
attachments := []*model.SlackAttachment{{Footer: "footer"}}
|
||||
|
||||
// DM Channel
|
||||
dmChannel := th1.CreateDmChannel(th1.BasicUser2)
|
||||
dmMembers := []string{th1.BasicUser.Username, th1.BasicUser2.Username}
|
||||
|
||||
user1 := th1.CreateUser()
|
||||
th1.LinkUserToTeam(user1, th1.BasicTeam)
|
||||
user2 := th1.CreateUser()
|
||||
th1.LinkUserToTeam(user2, th1.BasicTeam)
|
||||
|
||||
// GM Channel
|
||||
gmChannel := th1.CreateGroupChannel(user1, user2)
|
||||
gmMembers := []string{th1.BasicUser.Username, user1.Username, user2.Username}
|
||||
|
||||
// DM posts
|
||||
p1 := &model.Post{
|
||||
ChannelId: dmChannel.Id,
|
||||
Message: "aa" + model.NewId() + "a",
|
||||
Props: map[string]interface{}{
|
||||
"attachments": attachments,
|
||||
},
|
||||
UserId: th1.BasicUser.Id,
|
||||
}
|
||||
th1.App.CreatePost(p1, dmChannel, false)
|
||||
|
||||
p2 := &model.Post{
|
||||
ChannelId: gmChannel.Id,
|
||||
Message: "dd" + model.NewId() + "a",
|
||||
Props: map[string]interface{}{
|
||||
"attachments": attachments,
|
||||
},
|
||||
UserId: th1.BasicUser.Id,
|
||||
}
|
||||
th1.App.CreatePost(p2, gmChannel, false)
|
||||
|
||||
posts, err := th1.App.Srv().Store.Post().GetDirectPostParentsForExportAfter(1000, "0000000")
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, posts, 2)
|
||||
require.NotEmpty(t, posts[0].Props)
|
||||
require.NotEmpty(t, posts[1].Props)
|
||||
|
||||
var b bytes.Buffer
|
||||
err = th1.App.BulkExport(&b, "somefile", "somePath", "someDir")
|
||||
require.Nil(t, err)
|
||||
|
||||
th1.TearDown()
|
||||
|
||||
th2 := Setup(t)
|
||||
defer th2.TearDown()
|
||||
|
||||
posts, err = th2.App.Srv().Store.Post().GetDirectPostParentsForExportAfter(1000, "0000000")
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, posts, 0)
|
||||
|
||||
// import the exported posts
|
||||
err, i := th2.App.BulkImport(&b, false, 5)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, i)
|
||||
|
||||
posts, err = th2.App.Srv().Store.Post().GetDirectPostParentsForExportAfter(1000, "0000000")
|
||||
require.Nil(t, err)
|
||||
|
||||
// Adding some determinism so its possible to assert on slice index
|
||||
sort.Slice(posts, func(i, j int) bool { return posts[i].Message > posts[j].Message })
|
||||
assert.Len(t, posts, 2)
|
||||
assert.ElementsMatch(t, gmMembers, *posts[0].ChannelMembers)
|
||||
assert.ElementsMatch(t, dmMembers, *posts[1].ChannelMembers)
|
||||
assert.Contains(t, posts[0].Props["attachments"].([]interface{})[0], "footer")
|
||||
assert.Contains(t, posts[1].Props["attachments"].([]interface{})[0], "footer")
|
||||
}
|
||||
|
||||
func TestExportDMPostWithSelf(t *testing.T) {
|
||||
th1 := Setup(t).InitBasic()
|
||||
|
||||
|
||||
@@ -1111,6 +1111,10 @@ func (a *App) importMultiplePosts(data []*PostImportData, dryRun bool) *model.Ap
|
||||
post.CreateAt = *postData.CreateAt
|
||||
post.Hashtags, _ = model.ParseHashtags(post.Message)
|
||||
|
||||
if postData.Props != nil {
|
||||
post.Props = *postData.Props
|
||||
}
|
||||
|
||||
fileIds, err := a.uploadAttachments(postData.Attachments, post, team.Id, dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1382,6 +1386,10 @@ func (a *App) importMultipleDirectPosts(data []*DirectPostImportData, dryRun boo
|
||||
post.CreateAt = *postData.CreateAt
|
||||
post.Hashtags, _ = model.ParseHashtags(post.Message)
|
||||
|
||||
if postData.Props != nil {
|
||||
post.Props = *postData.Props
|
||||
}
|
||||
|
||||
fileIds, err := a.uploadAttachments(postData.Attachments, post, "noteam", dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -210,6 +210,20 @@ func TestImportBulkImport(t *testing.T) {
|
||||
require.NotNil(t, err, "Should have failed due to invalid type on line 2.")
|
||||
require.Equal(t, 2, line, "Should have failed due to invalid type on line 2.")
|
||||
})
|
||||
|
||||
t.Run("Posts with prop information", func(t *testing.T) {
|
||||
data6 := `{"type": "version", "version": 1}
|
||||
{"type": "team", "team": {"type": "O", "display_name": "lskmw2d7a5ao7ppwqh5ljchvr4", "name": "` + teamName + `"}}
|
||||
{"type": "channel", "channel": {"type": "O", "display_name": "xr6m6udffngark2uekvr3hoeny", "team": "` + teamName + `", "name": "` + channelName + `"}}
|
||||
{"type": "user", "user": {"username": "` + username + `", "email": "` + username + `@example.com", "teams": [{"name": "` + teamName + `","theme": "` + teamTheme1 + `", "channels": [{"name": "` + channelName + `"}]}]}}
|
||||
{"type": "post", "post": {"team": "` + teamName + `", "channel": "` + channelName + `", "user": "` + username + `", "message": "Hello World", "create_at": 123456789012, "attachments":[{"path": "` + testImage + `"}], "props":{"attachments":[{"id":0,"fallback":"[February 4th, 2020 2:46 PM] author: fallback","color":"D0D0D0","pretext":"","author_name":"author","author_link":"","title":"","title_link":"","text":"this post has props","fields":null,"image_url":"","thumb_url":"","footer":"Posted in #general","footer_icon":"","ts":"1580823992.000100"}]}}}
|
||||
{"type": "direct_channel", "direct_channel": {"members": ["` + username + `", "` + username + `"]}}
|
||||
{"type": "direct_post", "direct_post": {"channel_members": ["` + username + `", "` + username + `"], "user": "` + username + `", "message": "Hello Direct Channel to myself", "create_at": 123456789014, "props":{"attachments":[{"id":0,"fallback":"[February 4th, 2020 2:46 PM] author: fallback","color":"D0D0D0","pretext":"","author_name":"author","author_link":"","title":"","title_link":"","text":"this post has props","fields":null,"image_url":"","thumb_url":"","footer":"Posted in #general","footer_icon":"","ts":"1580823992.000100"}]}}}}`
|
||||
|
||||
err, line := th.App.BulkImport(strings.NewReader(data6), false, 2)
|
||||
require.Nil(t, err, "BulkImport should have succeeded")
|
||||
require.Equal(t, 0, line, "BulkImport line should be 0")
|
||||
})
|
||||
}
|
||||
|
||||
func TestImportProcessImportDataFileVersionLine(t *testing.T) {
|
||||
|
||||
@@ -131,8 +131,9 @@ type PostImportData struct {
|
||||
Channel *string `json:"channel"`
|
||||
User *string `json:"user"`
|
||||
|
||||
Message *string `json:"message"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
Message *string `json:"message"`
|
||||
Props *model.StringInterface `json:"props"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
|
||||
FlaggedBy *[]string `json:"flagged_by,omitempty"`
|
||||
Reactions *[]ReactionImportData `json:"reactions,omitempty"`
|
||||
@@ -151,8 +152,9 @@ type DirectPostImportData struct {
|
||||
ChannelMembers *[]string `json:"channel_members"`
|
||||
User *string `json:"user"`
|
||||
|
||||
Message *string `json:"message"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
Message *string `json:"message"`
|
||||
Props *model.StringInterface `json:"props"`
|
||||
CreateAt *int64 `json:"create_at"`
|
||||
|
||||
FlaggedBy *[]string `json:"flagged_by"`
|
||||
Reactions *[]ReactionImportData `json:"reactions"`
|
||||
|
||||
Ссылка в новой задаче
Block a user