diff --git a/server/client/client.go b/server/client/client.go index bb53d999b..0879002fd 100644 --- a/server/client/client.go +++ b/server/client/client.go @@ -683,3 +683,42 @@ func (c *Client) GetTemplatesForTeam(teamID string) ([]*model.Board, *Response) return model.BoardsFromJSON(r.Body), BuildResponse(r) } + +func (c *Client) ExportBoardArchive(boardID string) ([]byte, *Response) { + r, err := c.DoAPIGet(c.GetBoardRoute(boardID)+"/archive/export", "") + if err != nil { + return nil, BuildErrorResponse(r, err) + } + defer closeBody(r) + + buf, err := ioutil.ReadAll(r.Body) + if err != nil { + return nil, BuildErrorResponse(r, err) + } + return buf, BuildResponse(r) +} + +func (c *Client) ImportArchive(teamID string, data io.Reader) *Response { + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile(api.UploadFormFileKey, "file") + if err != nil { + return &Response{Error: err} + } + if _, err = io.Copy(part, data); err != nil { + return &Response{Error: err} + } + writer.Close() + + opt := func(r *http.Request) { + r.Header.Add("Content-Type", writer.FormDataContentType()) + } + + r, err := c.doAPIRequestReader(http.MethodPost, c.APIURL+c.GetTeamRoute(teamID)+"/archive/import", body, "", opt) + if err != nil { + return BuildErrorResponse(r, err) + } + defer closeBody(r) + + return BuildResponse(r) +} diff --git a/server/integrationtests/clienttestlib.go b/server/integrationtests/clienttestlib.go index 4579ffde8..70306077e 100644 --- a/server/integrationtests/clienttestlib.go +++ b/server/integrationtests/clienttestlib.go @@ -268,7 +268,7 @@ func (th *TestHelper) InitBasic() *TestHelper { th.RegisterAndLogin(th.Client, user1Username, "user1@sample.com", password, "") // get token - team, resp := th.Client.GetTeam("0") + team, resp := th.Client.GetTeam(model.GlobalTeamID) th.CheckOK(resp) require.NotNil(th.T, team) require.NotNil(th.T, team.SignupToken) diff --git a/server/integrationtests/export_test.go b/server/integrationtests/export_test.go new file mode 100644 index 000000000..49b10d404 --- /dev/null +++ b/server/integrationtests/export_test.go @@ -0,0 +1,66 @@ +package integrationtests + +import ( + "bytes" + "testing" + + "github.com/mattermost/focalboard/server/model" + "github.com/mattermost/focalboard/server/utils" + "github.com/stretchr/testify/require" +) + +func TestExportBoard(t *testing.T) { + t.Run("export single board", func(t *testing.T) { + th := SetupTestHelper(t).InitBasic() + defer th.TearDown() + + board := &model.Board{ + ID: utils.NewID(utils.IDTypeBoard), + TeamID: "test-team", + Title: "Export Test Board", + CreatedBy: th.GetUser1().ID, + Type: model.BoardTypeOpen, + CreateAt: utils.GetMillis(), + UpdateAt: utils.GetMillis(), + } + + block := model.Block{ + ID: utils.NewID(utils.IDTypeCard), + ParentID: board.ID, + Type: model.TypeCard, + BoardID: board.ID, + Title: "Test card # for export", + CreatedBy: th.GetUser1().ID, + CreateAt: utils.GetMillis(), + UpdateAt: utils.GetMillis(), + } + + babs := &model.BoardsAndBlocks{ + Boards: []*model.Board{board}, + Blocks: []model.Block{block}, + } + + babs, resp := th.Client.CreateBoardsAndBlocks(babs) + th.CheckOK(resp) + + // export the board to an in-memory archive file + buf, resp := th.Client.ExportBoardArchive(babs.Boards[0].ID) + th.CheckOK(resp) + require.NotNil(t, buf) + + // import the archive file to team 0 + resp = th.Client.ImportArchive(model.GlobalTeamID, bytes.NewReader(buf)) + th.CheckOK(resp) + require.NoError(t, resp.Error) + + // check for test card + boardsImported, err := th.Server.App().GetBoardsForUserAndTeam(th.GetUser1().ID, model.GlobalTeamID) + require.NoError(t, err) + require.Len(t, boardsImported, 1) + boardImported := boardsImported[0] + blocksImported, err := th.Server.App().GetBlocksForBoard(boardImported.ID) + require.NoError(t, err) + require.Len(t, blocksImported, 1) + require.Equal(t, block.Title, blocksImported[0].Title) + }) +}