Mono repo -> Master (#22553)
Combines the following repositories into one: https://github.com/mattermost/mattermost-server https://github.com/mattermost/mattermost-webapp https://github.com/mattermost/focalboard https://github.com/mattermost/mattermost-plugin-playbooks
Этот коммит содержится в:
397
server/boards/integrationtests/blocks_test.go
Обычный файл
397
server/boards/integrationtests/blocks_test.go
Обычный файл
@@ -0,0 +1,397 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetBlocks(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard("team-id", model.BoardTypeOpen)
|
||||
|
||||
initialID1 := utils.NewID(utils.IDTypeBlock)
|
||||
initialID2 := utils.NewID(utils.IDTypeBlock)
|
||||
newBlocks := []*model.Block{
|
||||
{
|
||||
ID: initialID1,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
},
|
||||
{
|
||||
ID: initialID2,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
},
|
||||
}
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, newBlocks, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 2)
|
||||
blockID1 := newBlocks[0].ID
|
||||
blockID2 := newBlocks[1].ID
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 2)
|
||||
|
||||
blockIDs := make([]string, len(blocks))
|
||||
for i, b := range blocks {
|
||||
blockIDs[i] = b.ID
|
||||
}
|
||||
require.Contains(t, blockIDs, blockID1)
|
||||
require.Contains(t, blockIDs, blockID2)
|
||||
}
|
||||
|
||||
func TestPostBlock(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard("team-id", model.BoardTypeOpen)
|
||||
|
||||
var blockID1 string
|
||||
var blockID2 string
|
||||
var blockID3 string
|
||||
|
||||
t.Run("Create a single block", func(t *testing.T) {
|
||||
initialID1 := utils.NewID(utils.IDTypeBlock)
|
||||
block := &model.Block{
|
||||
ID: initialID1,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
Title: "New title",
|
||||
}
|
||||
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, []*model.Block{block}, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 1)
|
||||
blockID1 = newBlocks[0].ID
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 1)
|
||||
|
||||
blockIDs := make([]string, len(blocks))
|
||||
for i, b := range blocks {
|
||||
blockIDs[i] = b.ID
|
||||
}
|
||||
require.Contains(t, blockIDs, blockID1)
|
||||
})
|
||||
|
||||
t.Run("Create a couple of blocks in the same call", func(t *testing.T) {
|
||||
initialID2 := utils.NewID(utils.IDTypeBlock)
|
||||
initialID3 := utils.NewID(utils.IDTypeBlock)
|
||||
newBlocks := []*model.Block{
|
||||
{
|
||||
ID: initialID2,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
},
|
||||
{
|
||||
ID: initialID3,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
},
|
||||
}
|
||||
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, newBlocks, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 2)
|
||||
blockID2 = newBlocks[0].ID
|
||||
blockID3 = newBlocks[1].ID
|
||||
require.NotEqual(t, initialID2, blockID2)
|
||||
require.NotEqual(t, initialID3, blockID3)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 3)
|
||||
|
||||
blockIDs := make([]string, len(blocks))
|
||||
for i, b := range blocks {
|
||||
blockIDs[i] = b.ID
|
||||
}
|
||||
require.Contains(t, blockIDs, blockID1)
|
||||
require.Contains(t, blockIDs, blockID2)
|
||||
require.Contains(t, blockIDs, blockID3)
|
||||
})
|
||||
|
||||
t.Run("Update a block should not be possible through the insert endpoint", func(t *testing.T) {
|
||||
block := &model.Block{
|
||||
ID: blockID1,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 20,
|
||||
Type: model.TypeCard,
|
||||
Title: "Updated title",
|
||||
}
|
||||
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, []*model.Block{block}, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 1)
|
||||
blockID4 := newBlocks[0].ID
|
||||
require.NotEqual(t, blockID1, blockID4)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 4)
|
||||
|
||||
var block4 *model.Block
|
||||
for _, b := range blocks {
|
||||
if b.ID == blockID4 {
|
||||
block4 = b
|
||||
}
|
||||
}
|
||||
require.NotNil(t, block4)
|
||||
require.Equal(t, "Updated title", block4.Title)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatchBlock(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
initialID := utils.NewID(utils.IDTypeBlock)
|
||||
|
||||
board := th.CreateBoard("team-id", model.BoardTypeOpen)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
block := &model.Block{
|
||||
ID: initialID,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
Title: "New title",
|
||||
Fields: map[string]interface{}{"test": "test value", "test2": "test value 2"},
|
||||
}
|
||||
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, []*model.Block{block}, false)
|
||||
th.CheckOK(resp)
|
||||
require.Len(t, newBlocks, 1)
|
||||
blockID := newBlocks[0].ID
|
||||
|
||||
t.Run("Patch a block basic field", func(t *testing.T) {
|
||||
newTitle := "Updated title"
|
||||
blockPatch := &model.BlockPatch{
|
||||
Title: &newTitle,
|
||||
}
|
||||
|
||||
_, resp := th.Client.PatchBlock(board.ID, blockID, blockPatch, false)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 1)
|
||||
|
||||
var updatedBlock *model.Block
|
||||
for _, b := range blocks {
|
||||
if b.ID == blockID {
|
||||
updatedBlock = b
|
||||
}
|
||||
}
|
||||
require.NotNil(t, updatedBlock)
|
||||
require.Equal(t, "Updated title", updatedBlock.Title)
|
||||
})
|
||||
|
||||
t.Run("Patch a block custom fields", func(t *testing.T) {
|
||||
blockPatch := &model.BlockPatch{
|
||||
UpdatedFields: map[string]interface{}{
|
||||
"test": "new test value",
|
||||
"test3": "new field",
|
||||
},
|
||||
}
|
||||
|
||||
_, resp := th.Client.PatchBlock(board.ID, blockID, blockPatch, false)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 1)
|
||||
|
||||
var updatedBlock *model.Block
|
||||
for _, b := range blocks {
|
||||
if b.ID == blockID {
|
||||
updatedBlock = b
|
||||
}
|
||||
}
|
||||
require.NotNil(t, updatedBlock)
|
||||
require.Equal(t, "new test value", updatedBlock.Fields["test"])
|
||||
require.Equal(t, "new field", updatedBlock.Fields["test3"])
|
||||
})
|
||||
|
||||
t.Run("Patch a block to remove custom fields", func(t *testing.T) {
|
||||
blockPatch := &model.BlockPatch{
|
||||
DeletedFields: []string{"test", "test3", "test100"},
|
||||
}
|
||||
|
||||
_, resp := th.Client.PatchBlock(board.ID, blockID, blockPatch, false)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 1)
|
||||
|
||||
var updatedBlock *model.Block
|
||||
for _, b := range blocks {
|
||||
if b.ID == blockID {
|
||||
updatedBlock = b
|
||||
}
|
||||
}
|
||||
require.NotNil(t, updatedBlock)
|
||||
require.Equal(t, nil, updatedBlock.Fields["test"])
|
||||
require.Equal(t, "test value 2", updatedBlock.Fields["test2"])
|
||||
require.Equal(t, nil, updatedBlock.Fields["test3"])
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteBlock(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard("team-id", model.BoardTypeOpen)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
var blockID string
|
||||
t.Run("Create a block", func(t *testing.T) {
|
||||
initialID := utils.NewID(utils.IDTypeBlock)
|
||||
block := &model.Block{
|
||||
ID: initialID,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
Title: "New title",
|
||||
}
|
||||
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, []*model.Block{block}, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 1)
|
||||
require.NotZero(t, newBlocks[0].ID)
|
||||
require.NotEqual(t, initialID, newBlocks[0].ID)
|
||||
blockID = newBlocks[0].ID
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, 1)
|
||||
|
||||
blockIDs := make([]string, len(blocks))
|
||||
for i, b := range blocks {
|
||||
blockIDs[i] = b.ID
|
||||
}
|
||||
require.Contains(t, blockIDs, blockID)
|
||||
})
|
||||
|
||||
t.Run("Delete a block", func(t *testing.T) {
|
||||
// this avoids triggering uniqueness constraint of
|
||||
// id,insert_at on block history
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
_, resp := th.Client.DeleteBlock(board.ID, blockID, false)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Empty(t, blocks)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUndeleteBlock(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard("team-id", model.BoardTypeOpen)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
initialCount := len(blocks)
|
||||
|
||||
var blockID string
|
||||
t.Run("Create a block", func(t *testing.T) {
|
||||
initialID := utils.NewID(utils.IDTypeBoard)
|
||||
block := &model.Block{
|
||||
ID: initialID,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeBoard,
|
||||
Title: "New title",
|
||||
}
|
||||
|
||||
newBlocks, resp := th.Client.InsertBlocks(board.ID, []*model.Block{block}, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 1)
|
||||
require.NotZero(t, newBlocks[0].ID)
|
||||
require.NotEqual(t, initialID, newBlocks[0].ID)
|
||||
blockID = newBlocks[0].ID
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, initialCount+1)
|
||||
|
||||
blockIDs := make([]string, len(blocks))
|
||||
for i, b := range blocks {
|
||||
blockIDs[i] = b.ID
|
||||
}
|
||||
require.Contains(t, blockIDs, blockID)
|
||||
})
|
||||
|
||||
t.Run("Delete a block", func(t *testing.T) {
|
||||
// this avoids triggering uniqueness constraint of
|
||||
// id,insert_at on block history
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
_, resp := th.Client.DeleteBlock(board.ID, blockID, false)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, initialCount)
|
||||
})
|
||||
|
||||
t.Run("Undelete a block", func(t *testing.T) {
|
||||
// this avoids triggering uniqueness constraint of
|
||||
// id,insert_at on block history
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
_, resp := th.Client.UndeleteBlock(board.ID, blockID)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, initialCount+1)
|
||||
})
|
||||
|
||||
t.Run("Try to undelete a block without permissions", func(t *testing.T) {
|
||||
// this avoids triggering uniqueness constraint of
|
||||
// id,insert_at on block history
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
_, resp := th.Client.DeleteBlock(board.ID, blockID, false)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
_, resp = th.Client2.UndeleteBlock(board.ID, blockID)
|
||||
th.CheckForbidden(resp)
|
||||
|
||||
blocks, resp := th.Client.GetBlocksForBoard(board.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, blocks, initialCount)
|
||||
})
|
||||
}
|
||||
2247
server/boards/integrationtests/board_test.go
Обычный файл
2247
server/boards/integrationtests/board_test.go
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
825
server/boards/integrationtests/boards_and_blocks_test.go
Обычный файл
825
server/boards/integrationtests/boards_and_blocks_test.go
Обычный файл
@@ -0,0 +1,825 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCreateBoardsAndBlocks(t *testing.T) {
|
||||
teamID := testTeamID
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{},
|
||||
Blocks: []*model.Block{},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("invalid boards and blocks", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("no boards", func(t *testing.T) {
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{},
|
||||
Blocks: []*model.Block{
|
||||
{ID: "block-id", BoardID: "board-id", Type: model.TypeCard},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("no blocks", func(t *testing.T) {
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{
|
||||
{ID: "board-id", TeamID: teamID, Type: model.BoardTypePrivate},
|
||||
},
|
||||
Blocks: []*model.Block{},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("blocks from nonexistent boards", func(t *testing.T) {
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{
|
||||
{ID: "board-id", TeamID: teamID, Type: model.BoardTypePrivate},
|
||||
},
|
||||
Blocks: []*model.Block{
|
||||
{ID: "block-id", BoardID: "nonexistent-board-id", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("boards with no IDs", func(t *testing.T) {
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{
|
||||
{ID: "board-id", TeamID: teamID, Type: model.BoardTypePrivate},
|
||||
{TeamID: teamID, Type: model.BoardTypePrivate},
|
||||
},
|
||||
Blocks: []*model.Block{
|
||||
{ID: "block-id", BoardID: "board-id", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("boards from different teams", func(t *testing.T) {
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{
|
||||
{ID: "board-id-1", TeamID: "team-id-1", Type: model.BoardTypePrivate},
|
||||
{ID: "board-id-2", TeamID: "team-id-2", Type: model.BoardTypePrivate},
|
||||
},
|
||||
Blocks: []*model.Block{
|
||||
{ID: "block-id", BoardID: "board-id-1", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("creating boards and blocks", func(t *testing.T) {
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{
|
||||
{ID: "board-id-1", Title: "public board", TeamID: teamID, Type: model.BoardTypeOpen},
|
||||
{ID: "board-id-2", Title: "private board", TeamID: teamID, Type: model.BoardTypePrivate},
|
||||
},
|
||||
Blocks: []*model.Block{
|
||||
{ID: "block-id-1", Title: "block 1", BoardID: "board-id-1", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
{ID: "block-id-2", Title: "block 2", BoardID: "board-id-2", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.CreateBoardsAndBlocks(newBab)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, bab)
|
||||
|
||||
require.Len(t, bab.Boards, 2)
|
||||
require.Len(t, bab.Blocks, 2)
|
||||
|
||||
// board 1 should have been created with a new ID, and its
|
||||
// block should be there too
|
||||
boardsTermPublic, resp := th.Client.SearchBoardsForTeam(teamID, "public")
|
||||
th.CheckOK(resp)
|
||||
require.Len(t, boardsTermPublic, 1)
|
||||
board1 := boardsTermPublic[0]
|
||||
require.Equal(t, "public board", board1.Title)
|
||||
require.Equal(t, model.BoardTypeOpen, board1.Type)
|
||||
require.NotEqual(t, "board-id-1", board1.ID)
|
||||
blocks1, err := th.Server.App().GetBlocksForBoard(board1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, blocks1, 1)
|
||||
require.Equal(t, "block 1", blocks1[0].Title)
|
||||
|
||||
// board 1 should have been created with a new ID, and its
|
||||
// block should be there too
|
||||
boardsTermPrivate, resp := th.Client.SearchBoardsForTeam(teamID, "private")
|
||||
th.CheckOK(resp)
|
||||
require.Len(t, boardsTermPrivate, 1)
|
||||
board2 := boardsTermPrivate[0]
|
||||
require.Equal(t, "private board", board2.Title)
|
||||
require.Equal(t, model.BoardTypePrivate, board2.Type)
|
||||
require.NotEqual(t, "board-id-2", board2.ID)
|
||||
blocks2, err := th.Server.App().GetBlocksForBoard(board2.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, blocks2, 1)
|
||||
require.Equal(t, "block 2", blocks2[0].Title)
|
||||
|
||||
// user should be an admin of both newly created boards
|
||||
user1 := th.GetUser1()
|
||||
members1, err := th.Server.App().GetMembersForBoard(board1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, members1, 1)
|
||||
require.Equal(t, user1.ID, members1[0].UserID)
|
||||
members2, err := th.Server.App().GetMembersForBoard(board2.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, members2, 1)
|
||||
require.Equal(t, user1.ID, members2[0].UserID)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatchBoardsAndBlocks(t *testing.T) {
|
||||
teamID := "team-id"
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
pbab := &model.PatchBoardsAndBlocks{}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("invalid patch boards and blocks", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
userID := th.GetUser1().ID
|
||||
initialTitle := "initial title 1"
|
||||
newTitle := "new title 1"
|
||||
|
||||
newBoard1 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
newBoard2 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
newBlock1 := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board1.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock1, userID))
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
newBlock2 := &model.Block{
|
||||
ID: "block-id-2",
|
||||
BoardID: board2.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock2, userID))
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
t.Run("no board IDs", func(t *testing.T) {
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("missmatch board IDs and patches", func(t *testing.T) {
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("no block IDs", func(t *testing.T) {
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("missmatch block IDs and patches", func(t *testing.T) {
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("block that doesn't belong to any board", func(t *testing.T) {
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("if the user doesn't have permissions for one of the boards, nothing should be updated", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
userID := th.GetUser1().ID
|
||||
initialTitle := "initial title 2"
|
||||
newTitle := "new title 2"
|
||||
|
||||
newBoard1 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
newBoard2 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, userID, false)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
newBlock1 := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board1.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock1, userID))
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
newBlock2 := &model.Block{
|
||||
ID: "block-id-2",
|
||||
BoardID: board2.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock2, userID))
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckForbidden(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("boards belonging to different teams should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
userID := th.GetUser1().ID
|
||||
initialTitle := "initial title 3"
|
||||
newTitle := "new title 3"
|
||||
|
||||
newBoard1 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
newBoard2 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: "different-team-id",
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
newBlock1 := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board1.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock1, userID))
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
newBlock2 := &model.Block{
|
||||
ID: "block-id-2",
|
||||
BoardID: board2.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock2, userID))
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, "board-id-2"},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("patches should be rejected if one is invalid", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
userID := th.GetUser1().ID
|
||||
initialTitle := "initial title 4"
|
||||
newTitle := "new title 4"
|
||||
|
||||
newBoard1 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
newBoard2 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, userID, false)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
newBlock1 := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board1.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock1, userID))
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
newBlock2 := &model.Block{
|
||||
ID: "block-id-2",
|
||||
BoardID: board2.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock2, userID))
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
var invalidPatchType model.BoardType = "invalid"
|
||||
invalidPatch := &model.BoardPatch{Type: &invalidPatchType}
|
||||
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
invalidPatch,
|
||||
},
|
||||
BlockIDs: []string{block1.ID, "board-id-2"},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("patches should be rejected if there is a block that doesn't belong to the boards being patched", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
userID := th.GetUser1().ID
|
||||
initialTitle := "initial title"
|
||||
newTitle := "new patched title"
|
||||
|
||||
newBoard1 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
newBoard2 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
newBlock1 := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board1.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock1, userID))
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
newBlock2 := &model.Block{
|
||||
ID: "block-id-2",
|
||||
BoardID: board2.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock2, userID))
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bab)
|
||||
})
|
||||
|
||||
t.Run("patches should be applied if they're valid and they're related", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
userID := th.GetUser1().ID
|
||||
initialTitle := "initial title"
|
||||
newTitle := "new other title"
|
||||
|
||||
newBoard1 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
newBoard2 := &model.Board{
|
||||
Title: initialTitle,
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, userID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
newBlock1 := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board1.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock1, userID))
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
newBlock2 := &model.Block{
|
||||
ID: "block-id-2",
|
||||
BoardID: board2.ID,
|
||||
Title: initialTitle,
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock2, userID))
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
pbab := &model.PatchBoardsAndBlocks{
|
||||
BoardIDs: []string{board1.ID, board2.ID},
|
||||
BoardPatches: []*model.BoardPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
BlockIDs: []string{block1.ID, block2.ID},
|
||||
BlockPatches: []*model.BlockPatch{
|
||||
{Title: &newTitle},
|
||||
{Title: &newTitle},
|
||||
},
|
||||
}
|
||||
|
||||
bab, resp := th.Client.PatchBoardsAndBlocks(pbab)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, bab)
|
||||
require.Len(t, bab.Boards, 2)
|
||||
require.Len(t, bab.Blocks, 2)
|
||||
|
||||
// ensure that the entities have been updated
|
||||
rBoard1, err := th.Server.App().GetBoard(board1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newTitle, rBoard1.Title)
|
||||
rBlock1, err := th.Server.App().GetBlockByID(block1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newTitle, rBlock1.Title)
|
||||
|
||||
rBoard2, err := th.Server.App().GetBoard(board2.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newTitle, rBoard2.Title)
|
||||
rBlock2, err := th.Server.App().GetBlockByID(block2.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newTitle, rBlock2.Title)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteBoardsAndBlocks(t *testing.T) {
|
||||
teamID := "team-id"
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
dbab := &model.DeleteBoardsAndBlocks{}
|
||||
|
||||
success, resp := th.Client.DeleteBoardsAndBlocks(dbab)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.False(t, success)
|
||||
})
|
||||
|
||||
t.Run("invalid delete boards and blocks", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
// a board and a block are required for the permission checks
|
||||
newBoard := &model.Board{
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
board, err := th.Server.App().CreateBoard(newBoard, th.GetUser1().ID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board)
|
||||
|
||||
newBlock := &model.Block{
|
||||
ID: "block-id-1",
|
||||
BoardID: board.ID,
|
||||
Title: "title",
|
||||
}
|
||||
require.NoError(t, th.Server.App().InsertBlock(newBlock, th.GetUser1().ID))
|
||||
block, err := th.Server.App().GetBlockByID(newBlock.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block)
|
||||
|
||||
t.Run("no boards", func(t *testing.T) {
|
||||
dbab := &model.DeleteBoardsAndBlocks{
|
||||
Blocks: []string{block.ID},
|
||||
}
|
||||
|
||||
success, resp := th.Client.DeleteBoardsAndBlocks(dbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.False(t, success)
|
||||
})
|
||||
|
||||
t.Run("boards from different teams", func(t *testing.T) {
|
||||
newOtherTeamsBoard := &model.Board{
|
||||
TeamID: "another-team-id",
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
otherTeamsBoard, err := th.Server.App().CreateBoard(newOtherTeamsBoard, th.GetUser1().ID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board)
|
||||
|
||||
dbab := &model.DeleteBoardsAndBlocks{
|
||||
Boards: []string{board.ID, otherTeamsBoard.ID},
|
||||
Blocks: []string{"block-id-1"},
|
||||
}
|
||||
|
||||
success, resp := th.Client.DeleteBoardsAndBlocks(dbab)
|
||||
th.CheckBadRequest(resp)
|
||||
require.False(t, success)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("if the user has no permissions to one of the boards, nothing should be deleted", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
// the user is an admin of the first board
|
||||
newBoard1 := &model.Board{
|
||||
Type: model.BoardTypeOpen,
|
||||
TeamID: "team_id_1",
|
||||
}
|
||||
board1, err := th.Server.App().CreateBoard(newBoard1, th.GetUser1().ID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
|
||||
// but not of the second
|
||||
newBoard2 := &model.Board{
|
||||
Type: model.BoardTypeOpen,
|
||||
TeamID: "team_id_1",
|
||||
}
|
||||
board2, err := th.Server.App().CreateBoard(newBoard2, th.GetUser1().ID, false)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
|
||||
dbab := &model.DeleteBoardsAndBlocks{
|
||||
Boards: []string{board1.ID, board2.ID},
|
||||
Blocks: []string{"block-id-1"},
|
||||
}
|
||||
|
||||
success, resp := th.Client.DeleteBoardsAndBlocks(dbab)
|
||||
th.CheckForbidden(resp)
|
||||
require.False(t, success)
|
||||
})
|
||||
|
||||
t.Run("all boards and blocks should be deleted if the request is correct", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
newBab := &model.BoardsAndBlocks{
|
||||
Boards: []*model.Board{
|
||||
{ID: "board-id-1", Title: "public board", TeamID: teamID, Type: model.BoardTypeOpen},
|
||||
{ID: "board-id-2", Title: "private board", TeamID: teamID, Type: model.BoardTypePrivate},
|
||||
},
|
||||
Blocks: []*model.Block{
|
||||
{ID: "block-id-1", Title: "block 1", BoardID: "board-id-1", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
{ID: "block-id-2", Title: "block 2", BoardID: "board-id-2", Type: model.TypeCard, CreateAt: 1, UpdateAt: 1},
|
||||
},
|
||||
}
|
||||
|
||||
bab, err := th.Server.App().CreateBoardsAndBlocks(newBab, th.GetUser1().ID, true)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, bab.Boards, 2)
|
||||
require.Len(t, bab.Blocks, 2)
|
||||
|
||||
// ensure that the entities have been successfully created
|
||||
board1, err := th.Server.App().GetBoard("board-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board1)
|
||||
block1, err := th.Server.App().GetBlockByID("block-id-1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block1)
|
||||
|
||||
board2, err := th.Server.App().GetBoard("board-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board2)
|
||||
block2, err := th.Server.App().GetBlockByID("block-id-2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, block2)
|
||||
|
||||
// call the API to delete boards and blocks
|
||||
dbab := &model.DeleteBoardsAndBlocks{
|
||||
Boards: []string{"board-id-1", "board-id-2"},
|
||||
Blocks: []string{"block-id-1", "block-id-2"},
|
||||
}
|
||||
|
||||
success, resp := th.Client.DeleteBoardsAndBlocks(dbab)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, success)
|
||||
|
||||
// ensure that the entities have been successfully deleted
|
||||
board1, err = th.Server.App().GetBoard("board-id-1")
|
||||
require.Error(t, err)
|
||||
require.True(t, model.IsErrNotFound(err))
|
||||
require.Nil(t, board1)
|
||||
block1, err = th.Server.App().GetBlockByID("block-id-1")
|
||||
require.Error(t, err)
|
||||
require.True(t, model.IsErrNotFound(err))
|
||||
require.Nil(t, block1)
|
||||
|
||||
board2, err = th.Server.App().GetBoard("board-id-2")
|
||||
require.Error(t, err)
|
||||
require.True(t, model.IsErrNotFound(err))
|
||||
require.Nil(t, board2)
|
||||
block2, err = th.Server.App().GetBlockByID("block-id-2")
|
||||
require.Error(t, err)
|
||||
require.True(t, model.IsErrNotFound(err))
|
||||
require.Nil(t, block2)
|
||||
})
|
||||
}
|
||||
127
server/boards/integrationtests/boardsapp_test.go
Обычный файл
127
server/boards/integrationtests/boardsapp_test.go
Обычный файл
@@ -0,0 +1,127 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/server"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
)
|
||||
|
||||
func TestSetConfiguration(t *testing.T) {
|
||||
boolTrue := true
|
||||
stringRef := ""
|
||||
|
||||
baseFeatureFlags := &model.FeatureFlags{}
|
||||
basePluginSettings := &model.PluginSettings{
|
||||
Directory: &stringRef,
|
||||
}
|
||||
driverName := "testDriver"
|
||||
dataSource := "testDirectory"
|
||||
baseSQLSettings := &model.SqlSettings{
|
||||
DriverName: &driverName,
|
||||
DataSource: &dataSource,
|
||||
}
|
||||
|
||||
directory := "testDirectory"
|
||||
baseFileSettings := &model.FileSettings{
|
||||
DriverName: &driverName,
|
||||
Directory: &directory,
|
||||
MaxFileSize: model.NewInt64(1024 * 1024),
|
||||
}
|
||||
|
||||
days := 365
|
||||
baseDataRetentionSettings := &model.DataRetentionSettings{
|
||||
BoardsRetentionDays: &days,
|
||||
}
|
||||
usernameRef := "username"
|
||||
baseTeamSettings := &model.TeamSettings{
|
||||
TeammateNameDisplay: &usernameRef,
|
||||
}
|
||||
|
||||
falseRef := false
|
||||
basePrivacySettings := &model.PrivacySettings{
|
||||
ShowEmailAddress: &falseRef,
|
||||
ShowFullName: &falseRef,
|
||||
}
|
||||
|
||||
baseConfig := &model.Config{
|
||||
FeatureFlags: baseFeatureFlags,
|
||||
PluginSettings: *basePluginSettings,
|
||||
SqlSettings: *baseSQLSettings,
|
||||
FileSettings: *baseFileSettings,
|
||||
DataRetentionSettings: *baseDataRetentionSettings,
|
||||
TeamSettings: *baseTeamSettings,
|
||||
PrivacySettings: *basePrivacySettings,
|
||||
}
|
||||
|
||||
t.Run("test enable telemetry", func(t *testing.T) {
|
||||
logSettings := &model.LogSettings{
|
||||
EnableDiagnostics: &boolTrue,
|
||||
}
|
||||
mmConfig := baseConfig
|
||||
mmConfig.LogSettings = *logSettings
|
||||
|
||||
config := server.CreateBoardsConfig(*mmConfig, "", "testId")
|
||||
assert.Equal(t, true, config.Telemetry)
|
||||
assert.Equal(t, "testId", config.TelemetryID)
|
||||
})
|
||||
|
||||
t.Run("test enable shared boards", func(t *testing.T) {
|
||||
mmConfig := baseConfig
|
||||
mmConfig.PluginSettings.Plugins = make(map[string]map[string]interface{})
|
||||
mmConfig.PluginSettings.Plugins[server.PluginName] = make(map[string]interface{})
|
||||
mmConfig.PluginSettings.Plugins[server.PluginName][server.SharedBoardsName] = true
|
||||
config := server.CreateBoardsConfig(*mmConfig, "", "")
|
||||
assert.Equal(t, true, config.EnablePublicSharedBoards)
|
||||
})
|
||||
|
||||
t.Run("test boards feature flags", func(t *testing.T) {
|
||||
featureFlags := &model.FeatureFlags{
|
||||
TestFeature: "test",
|
||||
TestBoolFeature: boolTrue,
|
||||
BoardsFeatureFlags: "hello_world-myTest",
|
||||
}
|
||||
|
||||
mmConfig := baseConfig
|
||||
mmConfig.FeatureFlags = featureFlags
|
||||
|
||||
config := server.CreateBoardsConfig(*mmConfig, "", "")
|
||||
assert.Equal(t, "true", config.FeatureFlags["TestBoolFeature"])
|
||||
assert.Equal(t, "test", config.FeatureFlags["TestFeature"])
|
||||
|
||||
assert.Equal(t, "true", config.FeatureFlags["hello_world"])
|
||||
assert.Equal(t, "true", config.FeatureFlags["myTest"])
|
||||
})
|
||||
}
|
||||
|
||||
func TestServeHTTP(t *testing.T) {
|
||||
th := SetupTestHelperPluginMode(t)
|
||||
defer th.TearDown()
|
||||
|
||||
b := server.NewBoardsServiceForTest(th.Server, &FakePluginAdapter{}, nil, mlog.CreateConsoleTestLogger(true, mlog.LvlError))
|
||||
|
||||
assert := assert.New(t)
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||
|
||||
b.ServeHTTP(nil, w, r)
|
||||
|
||||
result := w.Result()
|
||||
assert.NotNil(result)
|
||||
defer result.Body.Close()
|
||||
bodyBytes, err := io.ReadAll(result.Body)
|
||||
assert.Nil(err)
|
||||
bodyString := string(bodyBytes)
|
||||
|
||||
assert.Equal("Hello", bodyString)
|
||||
}
|
||||
291
server/boards/integrationtests/cards_test.go
Обычный файл
291
server/boards/integrationtests/cards_test.go
Обычный файл
@@ -0,0 +1,291 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
)
|
||||
|
||||
func TestCreateCard(t *testing.T) {
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
th.Logout(th.Client)
|
||||
|
||||
card := &model.Card{
|
||||
Title: "basic card",
|
||||
}
|
||||
cardNew, resp := th.Client.CreateCard(board.ID, card, false)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, cardNew)
|
||||
})
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
contentOrder := []string{utils.NewID(utils.IDTypeBlock), utils.NewID(utils.IDTypeBlock), utils.NewID(utils.IDTypeBlock)}
|
||||
|
||||
card := &model.Card{
|
||||
Title: "test card 1",
|
||||
Icon: "😱",
|
||||
ContentOrder: contentOrder,
|
||||
}
|
||||
|
||||
cardNew, resp := th.Client.CreateCard(board.ID, card, false)
|
||||
require.NoError(t, resp.Error)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, cardNew)
|
||||
|
||||
require.Equal(t, board.ID, cardNew.BoardID)
|
||||
require.Equal(t, "test card 1", cardNew.Title)
|
||||
require.Equal(t, "😱", cardNew.Icon)
|
||||
require.Equal(t, contentOrder, cardNew.ContentOrder)
|
||||
})
|
||||
|
||||
t.Run("invalid card", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
|
||||
card := &model.Card{
|
||||
Title: "too many emoji's",
|
||||
Icon: "😱😱😱😱",
|
||||
}
|
||||
|
||||
cardNew, resp := th.Client.CreateCard(board.ID, card, false)
|
||||
require.Error(t, resp.Error)
|
||||
require.Nil(t, cardNew)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCards(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
userID := th.GetUser1().ID
|
||||
|
||||
const cardCount = 25
|
||||
|
||||
// make some cards with content
|
||||
for i := 0; i < cardCount; i++ {
|
||||
card := &model.Card{
|
||||
BoardID: board.ID,
|
||||
CreatedBy: userID,
|
||||
ModifiedBy: userID,
|
||||
Title: fmt.Sprintf("%d", i),
|
||||
}
|
||||
cardNew, resp := th.Client.CreateCard(board.ID, card, true)
|
||||
th.CheckOK(resp)
|
||||
|
||||
blocks := make([]*model.Block, 0, 3)
|
||||
for j := 0; j < 3; j++ {
|
||||
now := model.GetMillis()
|
||||
block := &model.Block{
|
||||
ID: utils.NewID(utils.IDTypeBlock),
|
||||
ParentID: cardNew.ID,
|
||||
CreatedBy: userID,
|
||||
ModifiedBy: userID,
|
||||
CreateAt: now,
|
||||
UpdateAt: now,
|
||||
Schema: 1,
|
||||
Type: model.TypeText,
|
||||
Title: fmt.Sprintf("text %d for card %d", j, i),
|
||||
BoardID: board.ID,
|
||||
}
|
||||
blocks = append(blocks, block)
|
||||
}
|
||||
_, resp = th.Client.InsertBlocks(board.ID, blocks, true)
|
||||
th.CheckOK(resp)
|
||||
}
|
||||
|
||||
t.Run("fetch all cards", func(t *testing.T) {
|
||||
cards, resp := th.Client.GetCards(board.ID, 0, -1)
|
||||
th.CheckOK(resp)
|
||||
assert.Len(t, cards, cardCount)
|
||||
})
|
||||
|
||||
t.Run("fetch with pagination", func(t *testing.T) {
|
||||
cardNums := make(map[int]struct{})
|
||||
|
||||
// return first 10
|
||||
cards, resp := th.Client.GetCards(board.ID, 0, 10)
|
||||
th.CheckOK(resp)
|
||||
assert.Len(t, cards, 10)
|
||||
for _, card := range cards {
|
||||
cardNum, err := strconv.Atoi(card.Title)
|
||||
require.NoError(t, err)
|
||||
cardNums[cardNum] = struct{}{}
|
||||
}
|
||||
|
||||
// return second 10
|
||||
cards, resp = th.Client.GetCards(board.ID, 1, 10)
|
||||
th.CheckOK(resp)
|
||||
assert.Len(t, cards, 10)
|
||||
for _, card := range cards {
|
||||
cardNum, err := strconv.Atoi(card.Title)
|
||||
require.NoError(t, err)
|
||||
cardNums[cardNum] = struct{}{}
|
||||
}
|
||||
|
||||
// return remaining 5
|
||||
cards, resp = th.Client.GetCards(board.ID, 2, 10)
|
||||
th.CheckOK(resp)
|
||||
assert.Len(t, cards, 5)
|
||||
for _, card := range cards {
|
||||
cardNum, err := strconv.Atoi(card.Title)
|
||||
require.NoError(t, err)
|
||||
cardNums[cardNum] = struct{}{}
|
||||
}
|
||||
|
||||
// make sure all card numbers were returned
|
||||
assert.Len(t, cardNums, cardCount)
|
||||
for i := 0; i < cardCount; i++ {
|
||||
_, ok := cardNums[i]
|
||||
assert.True(t, ok)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th.Logout(th.Client)
|
||||
|
||||
cards, resp := th.Client.GetCards(board.ID, 0, 10)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, cards)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatchCard(t *testing.T) {
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
_, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 1)
|
||||
card := cards[0]
|
||||
|
||||
th.Logout(th.Client)
|
||||
|
||||
newTitle := "another title"
|
||||
patch := &model.CardPatch{
|
||||
Title: &newTitle,
|
||||
}
|
||||
|
||||
patchedCard, resp := th.Client.PatchCard(card.ID, patch, false)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, patchedCard)
|
||||
})
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 1)
|
||||
card := cards[0]
|
||||
|
||||
// Patch the card
|
||||
newTitle := "another title"
|
||||
newIcon := "🐿"
|
||||
newContentOrder := reverse(card.ContentOrder)
|
||||
updatedProps := modifyCardProps(card.Properties)
|
||||
patch := &model.CardPatch{
|
||||
Title: &newTitle,
|
||||
Icon: &newIcon,
|
||||
ContentOrder: &newContentOrder,
|
||||
UpdatedProperties: updatedProps,
|
||||
}
|
||||
|
||||
patchedCard, resp := th.Client.PatchCard(card.ID, patch, false)
|
||||
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, patchedCard)
|
||||
require.Equal(t, board.ID, patchedCard.BoardID)
|
||||
require.Equal(t, newTitle, patchedCard.Title)
|
||||
require.Equal(t, newIcon, patchedCard.Icon)
|
||||
require.NotEqual(t, card.ContentOrder, patchedCard.ContentOrder)
|
||||
require.ElementsMatch(t, card.ContentOrder, patchedCard.ContentOrder)
|
||||
require.EqualValues(t, updatedProps, patchedCard.Properties)
|
||||
})
|
||||
|
||||
t.Run("invalid card patch", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
_, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 1)
|
||||
card := cards[0]
|
||||
|
||||
// Bad patch (too many emoji)
|
||||
newIcon := "🐿🐿🐿"
|
||||
patch := &model.CardPatch{
|
||||
Icon: &newIcon,
|
||||
}
|
||||
|
||||
cardNew, resp := th.Client.PatchCard(card.ID, patch, false)
|
||||
require.Error(t, resp.Error)
|
||||
require.Nil(t, cardNew)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCard(t *testing.T) {
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
_, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 1)
|
||||
card := cards[0]
|
||||
|
||||
th.Logout(th.Client)
|
||||
|
||||
cardFetched, resp := th.Client.GetCard(card.ID)
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, cardFetched)
|
||||
})
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
board, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 1)
|
||||
card := cards[0]
|
||||
|
||||
cardFetched, resp := th.Client.GetCard(card.ID)
|
||||
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, cardFetched)
|
||||
require.Equal(t, board.ID, cardFetched.BoardID)
|
||||
require.Equal(t, card.Title, cardFetched.Title)
|
||||
require.Equal(t, card.Icon, cardFetched.Icon)
|
||||
require.Equal(t, card.ContentOrder, cardFetched.ContentOrder)
|
||||
require.EqualValues(t, card.Properties, cardFetched.Properties)
|
||||
})
|
||||
}
|
||||
|
||||
// Helpers.
|
||||
func reverse(src []string) []string {
|
||||
out := make([]string, 0, len(src))
|
||||
for i := len(src) - 1; i >= 0; i-- {
|
||||
out = append(out, src[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func modifyCardProps(m map[string]any) map[string]any {
|
||||
out := make(map[string]any)
|
||||
for k := range m {
|
||||
out[k] = utils.NewID(utils.IDTypeBlock)
|
||||
}
|
||||
return out
|
||||
}
|
||||
551
server/boards/integrationtests/clienttestlib.go
Обычный файл
551
server/boards/integrationtests/clienttestlib.go
Обычный файл
@@ -0,0 +1,551 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/client"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/server"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/auth"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/config"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/permissions/localpermissions"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/permissions/mmpermissions"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/store"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/store/sqlstore"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
user1Username = "user1"
|
||||
user2Username = "user2"
|
||||
password = "Pa$$word"
|
||||
testTeamID = "team-id"
|
||||
)
|
||||
|
||||
const (
|
||||
userAnon string = "anon"
|
||||
userNoTeamMember string = "no-team-member"
|
||||
userTeamMember string = "team-member"
|
||||
userViewer string = "viewer"
|
||||
userCommenter string = "commenter"
|
||||
userEditor string = "editor"
|
||||
userAdmin string = "admin"
|
||||
userGuest string = "guest"
|
||||
)
|
||||
|
||||
var (
|
||||
userAnonID = userAnon
|
||||
userNoTeamMemberID = userNoTeamMember
|
||||
userTeamMemberID = userTeamMember
|
||||
userViewerID = userViewer
|
||||
userCommenterID = userCommenter
|
||||
userEditorID = userEditor
|
||||
userAdminID = userAdmin
|
||||
userGuestID = userGuest
|
||||
)
|
||||
|
||||
type LicenseType int
|
||||
|
||||
const (
|
||||
LicenseNone LicenseType = iota // 0
|
||||
LicenseProfessional // 1
|
||||
LicenseEnterprise // 2
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
T *testing.T
|
||||
Server *server.Server
|
||||
Client *client.Client
|
||||
Client2 *client.Client
|
||||
|
||||
origEnvUnitTesting string
|
||||
}
|
||||
|
||||
type FakePermissionPluginAPI struct{}
|
||||
|
||||
func (*FakePermissionPluginAPI) HasPermissionTo(userID string, permission *mm_model.Permission) bool {
|
||||
return userID == userAdmin
|
||||
}
|
||||
|
||||
func (*FakePermissionPluginAPI) HasPermissionToTeam(userID string, teamID string, permission *mm_model.Permission) bool {
|
||||
if permission.Id == model.PermissionManageTeam.Id {
|
||||
return false
|
||||
}
|
||||
if userID == userNoTeamMember {
|
||||
return false
|
||||
}
|
||||
if teamID == "empty-team" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*FakePermissionPluginAPI) HasPermissionToChannel(userID string, channelID string, permission *mm_model.Permission) bool {
|
||||
return channelID == "valid-channel-id" || channelID == "valid-channel-id-2"
|
||||
}
|
||||
|
||||
func GetTestConfig(t *testing.T) *config.Configuration {
|
||||
driver := os.Getenv("MM_SQLSETTINGS_DRIVERNAME")
|
||||
if driver == "" {
|
||||
driver = model.PostgresDBType
|
||||
}
|
||||
|
||||
storeType := sqlstore.NewStoreType(driver, driver, true)
|
||||
storeType.Store.Shutdown()
|
||||
storeType.Logger.Shutdown()
|
||||
|
||||
logging := `
|
||||
{
|
||||
"testing": {
|
||||
"type": "console",
|
||||
"options": {
|
||||
"out": "stdout"
|
||||
},
|
||||
"format": "plain",
|
||||
"format_options": {
|
||||
"delim": " "
|
||||
},
|
||||
"levels": [
|
||||
{"id": 5, "name": "debug"},
|
||||
{"id": 4, "name": "info"},
|
||||
{"id": 3, "name": "warn"},
|
||||
{"id": 2, "name": "error", "stacktrace": true},
|
||||
{"id": 1, "name": "fatal", "stacktrace": true},
|
||||
{"id": 0, "name": "panic", "stacktrace": true}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
return &config.Configuration{
|
||||
ServerRoot: "http://localhost:8888",
|
||||
Port: 8888,
|
||||
DBType: driver,
|
||||
DBConfigString: storeType.ConnString,
|
||||
DBTablePrefix: "test_",
|
||||
WebPath: "./pack",
|
||||
FilesDriver: "local",
|
||||
FilesPath: "./files",
|
||||
LoggingCfgJSON: logging,
|
||||
SessionExpireTime: int64(30 * time.Second),
|
||||
AuthMode: "native",
|
||||
}
|
||||
}
|
||||
|
||||
func newTestServer(t *testing.T, singleUserToken string) *server.Server {
|
||||
return newTestServerWithLicense(t, singleUserToken, LicenseNone)
|
||||
}
|
||||
|
||||
func newTestServerWithLicense(t *testing.T, singleUserToken string, licenseType LicenseType) *server.Server {
|
||||
cfg := GetTestConfig(t)
|
||||
|
||||
logger, _ := mlog.NewLogger()
|
||||
err := logger.Configure("", cfg.LoggingCfgJSON, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
singleUser := singleUserToken != ""
|
||||
innerStore, err := server.NewStore(cfg, singleUser, logger)
|
||||
require.NoError(t, err)
|
||||
|
||||
var db store.Store
|
||||
|
||||
switch licenseType {
|
||||
case LicenseProfessional:
|
||||
db = NewTestProfessionalStore(innerStore)
|
||||
case LicenseEnterprise:
|
||||
db = NewTestEnterpriseStore(innerStore)
|
||||
case LicenseNone:
|
||||
fallthrough
|
||||
default:
|
||||
db = innerStore
|
||||
}
|
||||
|
||||
permissionsService := localpermissions.New(db, logger)
|
||||
|
||||
params := server.Params{
|
||||
Cfg: cfg,
|
||||
SingleUserToken: singleUserToken,
|
||||
DBStore: db,
|
||||
Logger: logger,
|
||||
PermissionsService: permissionsService,
|
||||
}
|
||||
|
||||
srv, err := server.New(params)
|
||||
require.NoError(t, err)
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
func NewTestServerPluginMode(t *testing.T) *server.Server {
|
||||
cfg := GetTestConfig(t)
|
||||
|
||||
cfg.AuthMode = "mattermost"
|
||||
cfg.EnablePublicSharedBoards = true
|
||||
|
||||
logger, _ := mlog.NewLogger()
|
||||
if err := logger.Configure("", cfg.LoggingCfgJSON, nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
innerStore, err := server.NewStore(cfg, false, logger)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
db := NewPluginTestStore(innerStore)
|
||||
|
||||
permissionsService := mmpermissions.New(db, &FakePermissionPluginAPI{}, logger)
|
||||
|
||||
params := server.Params{
|
||||
Cfg: cfg,
|
||||
DBStore: db,
|
||||
Logger: logger,
|
||||
PermissionsService: permissionsService,
|
||||
}
|
||||
|
||||
srv, err := server.New(params)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
func newTestServerLocalMode(t *testing.T) *server.Server {
|
||||
cfg := GetTestConfig(t)
|
||||
cfg.EnablePublicSharedBoards = true
|
||||
|
||||
logger, _ := mlog.NewLogger()
|
||||
err := logger.Configure("", cfg.LoggingCfgJSON, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
db, err := server.NewStore(cfg, false, logger)
|
||||
require.NoError(t, err)
|
||||
|
||||
permissionsService := localpermissions.New(db, logger)
|
||||
|
||||
params := server.Params{
|
||||
Cfg: cfg,
|
||||
DBStore: db,
|
||||
Logger: logger,
|
||||
PermissionsService: permissionsService,
|
||||
}
|
||||
|
||||
srv, err := server.New(params)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Reduce password has strength for unit tests to dramatically speed up account creation and login
|
||||
auth.PasswordHashStrength = 4
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
func SetupTestHelperWithToken(t *testing.T) *TestHelper {
|
||||
origUnitTesting := os.Getenv("FOCALBOARD_UNIT_TESTING")
|
||||
os.Setenv("FOCALBOARD_UNIT_TESTING", "1")
|
||||
|
||||
sessionToken := "TESTTOKEN"
|
||||
|
||||
th := &TestHelper{
|
||||
T: t,
|
||||
origEnvUnitTesting: origUnitTesting,
|
||||
}
|
||||
|
||||
th.Server = newTestServer(t, sessionToken)
|
||||
th.Client = client.NewClient(th.Server.Config().ServerRoot, sessionToken)
|
||||
th.Client2 = client.NewClient(th.Server.Config().ServerRoot, sessionToken)
|
||||
return th
|
||||
}
|
||||
|
||||
func SetupTestHelper(t *testing.T) *TestHelper {
|
||||
return SetupTestHelperWithLicense(t, LicenseNone)
|
||||
}
|
||||
|
||||
func SetupTestHelperPluginMode(t *testing.T) *TestHelper {
|
||||
origUnitTesting := os.Getenv("FOCALBOARD_UNIT_TESTING")
|
||||
os.Setenv("FOCALBOARD_UNIT_TESTING", "1")
|
||||
|
||||
th := &TestHelper{
|
||||
T: t,
|
||||
origEnvUnitTesting: origUnitTesting,
|
||||
}
|
||||
|
||||
th.Server = NewTestServerPluginMode(t)
|
||||
th.Start()
|
||||
return th
|
||||
}
|
||||
|
||||
func SetupTestHelperLocalMode(t *testing.T) *TestHelper {
|
||||
origUnitTesting := os.Getenv("FOCALBOARD_UNIT_TESTING")
|
||||
os.Setenv("FOCALBOARD_UNIT_TESTING", "1")
|
||||
|
||||
th := &TestHelper{
|
||||
T: t,
|
||||
origEnvUnitTesting: origUnitTesting,
|
||||
}
|
||||
|
||||
th.Server = newTestServerLocalMode(t)
|
||||
th.Start()
|
||||
return th
|
||||
}
|
||||
|
||||
func SetupTestHelperWithLicense(t *testing.T, licenseType LicenseType) *TestHelper {
|
||||
origUnitTesting := os.Getenv("FOCALBOARD_UNIT_TESTING")
|
||||
os.Setenv("FOCALBOARD_UNIT_TESTING", "1")
|
||||
|
||||
th := &TestHelper{
|
||||
T: t,
|
||||
origEnvUnitTesting: origUnitTesting,
|
||||
}
|
||||
|
||||
th.Server = newTestServerWithLicense(t, "", licenseType)
|
||||
th.Client = client.NewClient(th.Server.Config().ServerRoot, "")
|
||||
th.Client2 = client.NewClient(th.Server.Config().ServerRoot, "")
|
||||
return th
|
||||
}
|
||||
|
||||
// Start starts the test server and ensures that it's correctly
|
||||
// responding to requests before returning.
|
||||
func (th *TestHelper) Start() *TestHelper {
|
||||
go func() {
|
||||
if err := th.Server.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
URL := th.Server.Config().ServerRoot
|
||||
th.Server.Logger().Info("Polling server", mlog.String("url", URL))
|
||||
resp, err := http.Get(URL) //nolint:gosec
|
||||
if err != nil {
|
||||
th.Server.Logger().Error("Polling failed", mlog.Err(err))
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
// Currently returns 404
|
||||
// if resp.StatusCode != http.StatusOK {
|
||||
// th.Server.Logger().Error("Not OK", mlog.Int("statusCode", resp.StatusCode))
|
||||
// continue
|
||||
// }
|
||||
|
||||
// Reached this point: server is up and running!
|
||||
th.Server.Logger().Info("Server ping OK", mlog.Int("statusCode", resp.StatusCode))
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return th
|
||||
}
|
||||
|
||||
// InitBasic starts the test server and initializes the clients of the
|
||||
// helper, registering them and logging them into the system.
|
||||
func (th *TestHelper) InitBasic() *TestHelper {
|
||||
// Reduce password has strength for unit tests to dramatically speed up account creation and login
|
||||
auth.PasswordHashStrength = 4
|
||||
|
||||
th.Start()
|
||||
|
||||
// user1
|
||||
th.RegisterAndLogin(th.Client, user1Username, "user1@sample.com", password, "")
|
||||
|
||||
// get token
|
||||
team, resp := th.Client.GetTeam(model.GlobalTeamID)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(th.T, team)
|
||||
require.NotNil(th.T, team.SignupToken)
|
||||
|
||||
// user2
|
||||
th.RegisterAndLogin(th.Client2, user2Username, "user2@sample.com", password, team.SignupToken)
|
||||
|
||||
return th
|
||||
}
|
||||
|
||||
var ErrRegisterFail = errors.New("register failed")
|
||||
|
||||
func (th *TestHelper) TearDown() {
|
||||
os.Setenv("FOCALBOARD_UNIT_TESTING", th.origEnvUnitTesting)
|
||||
|
||||
logger := th.Server.Logger()
|
||||
|
||||
if l, ok := logger.(*mlog.Logger); ok {
|
||||
defer func() { _ = l.Shutdown() }()
|
||||
}
|
||||
|
||||
err := th.Server.Shutdown()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
os.RemoveAll(th.Server.Config().FilesPath)
|
||||
|
||||
if err := os.Remove(th.Server.Config().DBConfigString); err == nil {
|
||||
logger.Debug("Removed test database", mlog.String("file", th.Server.Config().DBConfigString))
|
||||
}
|
||||
}
|
||||
|
||||
func (th *TestHelper) RegisterAndLogin(client *client.Client, username, email, password, token string) {
|
||||
req := &model.RegisterRequest{
|
||||
Username: username,
|
||||
Email: email,
|
||||
Password: password,
|
||||
Token: token,
|
||||
}
|
||||
|
||||
success, resp := th.Client.Register(req)
|
||||
th.CheckOK(resp)
|
||||
require.True(th.T, success)
|
||||
|
||||
th.Login(client, username, password)
|
||||
}
|
||||
|
||||
func (th *TestHelper) Login(client *client.Client, username, password string) {
|
||||
req := &model.LoginRequest{
|
||||
Type: "normal",
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
data, resp := client.Login(req)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(th.T, data)
|
||||
}
|
||||
|
||||
func (th *TestHelper) Login1() {
|
||||
th.Login(th.Client, user1Username, password)
|
||||
}
|
||||
|
||||
func (th *TestHelper) Login2() {
|
||||
th.Login(th.Client2, user2Username, password)
|
||||
}
|
||||
|
||||
func (th *TestHelper) Logout(client *client.Client) {
|
||||
client.Token = ""
|
||||
}
|
||||
|
||||
func (th *TestHelper) Me(client *client.Client) *model.User {
|
||||
user, resp := client.GetMe()
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(th.T, user)
|
||||
return user
|
||||
}
|
||||
|
||||
func (th *TestHelper) CreateBoard(teamID string, boardType model.BoardType) *model.Board {
|
||||
newBoard := &model.Board{
|
||||
TeamID: teamID,
|
||||
Type: boardType,
|
||||
}
|
||||
board, resp := th.Client.CreateBoard(newBoard)
|
||||
th.CheckOK(resp)
|
||||
return board
|
||||
}
|
||||
|
||||
func (th *TestHelper) CreateBoards(teamID string, boardType model.BoardType, count int) []*model.Board {
|
||||
boards := make([]*model.Board, 0, count)
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
board := th.CreateBoard(teamID, boardType)
|
||||
boards = append(boards, board)
|
||||
}
|
||||
return boards
|
||||
}
|
||||
|
||||
func (th *TestHelper) CreateCategory(category model.Category) *model.Category {
|
||||
cat, resp := th.Client.CreateCategory(category)
|
||||
th.CheckOK(resp)
|
||||
return cat
|
||||
}
|
||||
|
||||
func (th *TestHelper) UpdateCategoryBoard(teamID, categoryID, boardID string) {
|
||||
response := th.Client.UpdateCategoryBoard(teamID, categoryID, boardID)
|
||||
th.CheckOK(response)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CreateBoardAndCards(teamdID string, boardType model.BoardType, numCards int) (*model.Board, []*model.Card) {
|
||||
board := th.CreateBoard(teamdID, boardType)
|
||||
cards := make([]*model.Card, 0, numCards)
|
||||
for i := 0; i < numCards; i++ {
|
||||
card := &model.Card{
|
||||
Title: fmt.Sprintf("test card %d", i+1),
|
||||
ContentOrder: []string{utils.NewID(utils.IDTypeBlock), utils.NewID(utils.IDTypeBlock), utils.NewID(utils.IDTypeBlock)},
|
||||
Icon: "😱",
|
||||
Properties: th.MakeCardProps(5),
|
||||
}
|
||||
newCard, resp := th.Client.CreateCard(board.ID, card, true)
|
||||
th.CheckOK(resp)
|
||||
cards = append(cards, newCard)
|
||||
}
|
||||
return board, cards
|
||||
}
|
||||
|
||||
func (th *TestHelper) MakeCardProps(count int) map[string]any {
|
||||
props := make(map[string]any)
|
||||
for i := 0; i < count; i++ {
|
||||
props[utils.NewID(utils.IDTypeBlock)] = utils.NewID(utils.IDTypeBlock)
|
||||
}
|
||||
return props
|
||||
}
|
||||
|
||||
func (th *TestHelper) GetUserCategoryBoards(teamID string) []model.CategoryBoards {
|
||||
categoryBoards, response := th.Client.GetUserCategoryBoards(teamID)
|
||||
th.CheckOK(response)
|
||||
return categoryBoards
|
||||
}
|
||||
|
||||
func (th *TestHelper) DeleteCategory(teamID, categoryID string) {
|
||||
response := th.Client.DeleteCategory(teamID, categoryID)
|
||||
th.CheckOK(response)
|
||||
}
|
||||
|
||||
func (th *TestHelper) GetUser1() *model.User {
|
||||
return th.Me(th.Client)
|
||||
}
|
||||
|
||||
func (th *TestHelper) GetUser2() *model.User {
|
||||
return th.Me(th.Client2)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckOK(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusOK, r.StatusCode)
|
||||
require.NoError(th.T, r.Error)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckBadRequest(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusBadRequest, r.StatusCode)
|
||||
require.Error(th.T, r.Error)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckNotFound(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusNotFound, r.StatusCode)
|
||||
require.Error(th.T, r.Error)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckUnauthorized(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusUnauthorized, r.StatusCode)
|
||||
require.Error(th.T, r.Error)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckForbidden(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusForbidden, r.StatusCode)
|
||||
require.Error(th.T, r.Error)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckRequestEntityTooLarge(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusRequestEntityTooLarge, r.StatusCode)
|
||||
require.Error(th.T, r.Error)
|
||||
}
|
||||
|
||||
func (th *TestHelper) CheckNotImplemented(r *client.Response) {
|
||||
require.Equal(th.T, http.StatusNotImplemented, r.StatusCode)
|
||||
require.Error(th.T, r.Error)
|
||||
}
|
||||
364
server/boards/integrationtests/compliance_test.go
Обычный файл
364
server/boards/integrationtests/compliance_test.go
Обычный файл
@@ -0,0 +1,364 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
OneHour int64 = 360000
|
||||
OneDay int64 = OneHour * 24
|
||||
OneYear int64 = OneDay * 365
|
||||
)
|
||||
|
||||
func setupTestHelperForCompliance(t *testing.T, complianceLicense bool) (*TestHelper, Clients) {
|
||||
os.Setenv("FOCALBOARD_UNIT_TESTING_COMPLIANCE", strconv.FormatBool(complianceLicense))
|
||||
|
||||
th := SetupTestHelperPluginMode(t)
|
||||
clients := setupClients(th)
|
||||
|
||||
th.Client = clients.TeamMember
|
||||
th.Client2 = clients.TeamMember
|
||||
|
||||
return th, clients
|
||||
}
|
||||
|
||||
func TestGetBoardsForCompliance(t *testing.T) {
|
||||
t.Run("missing Features.Compliance license should fail", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, false)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bcr, resp := clients.Admin.GetBoardsForCompliance(testTeamID, 0, 0)
|
||||
|
||||
th.CheckNotImplemented(resp)
|
||||
require.Nil(t, bcr)
|
||||
})
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
th.Logout(th.Client)
|
||||
|
||||
bcr, resp := clients.Anon.GetBoardsForCompliance(testTeamID, 0, 0)
|
||||
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bcr)
|
||||
})
|
||||
|
||||
t.Run("a user without manage_system permission should be rejected", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bcr, resp := clients.TeamMember.GetBoardsForCompliance(testTeamID, 0, 0)
|
||||
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bcr)
|
||||
})
|
||||
|
||||
t.Run("good call", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 10
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
bcr, resp := clients.Admin.GetBoardsForCompliance(testTeamID, 0, 0)
|
||||
th.CheckOK(resp)
|
||||
require.False(t, bcr.HasNext)
|
||||
require.Len(t, bcr.Results, count)
|
||||
})
|
||||
|
||||
t.Run("pagination", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 20
|
||||
const perPage = 3
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
boards := make([]*model.Board, 0, count)
|
||||
page := 0
|
||||
for {
|
||||
bcr, resp := clients.Admin.GetBoardsForCompliance(testTeamID, page, perPage)
|
||||
page++
|
||||
th.CheckOK(resp)
|
||||
boards = append(boards, bcr.Results...)
|
||||
if !bcr.HasNext {
|
||||
break
|
||||
}
|
||||
}
|
||||
require.Len(t, boards, count)
|
||||
require.Equal(t, int(math.Floor((count/perPage)+1)), page)
|
||||
})
|
||||
|
||||
t.Run("invalid teamID", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bcr, resp := clients.Admin.GetBoardsForCompliance(utils.NewID(utils.IDTypeTeam), 0, 0)
|
||||
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bcr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBoardsComplianceHistory(t *testing.T) {
|
||||
t.Run("missing Features.Compliance license should fail", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, false)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.Admin.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, 0, 0)
|
||||
|
||||
th.CheckNotImplemented(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
th.Logout(th.Client)
|
||||
|
||||
bchr, resp := clients.Anon.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, 0, 0)
|
||||
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("a user without manage_system permission should be rejected", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.TeamMember.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, 0, 0)
|
||||
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("good call, exclude deleted", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 10
|
||||
boards := th.CreateBoards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
deleted, resp := th.Client.DeleteBoard(boards[0].ID)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
deleted, resp = th.Client.DeleteBoard(boards[1].ID)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
bchr, resp := clients.Admin.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, false, testTeamID, 0, 0)
|
||||
th.CheckOK(resp)
|
||||
require.False(t, bchr.HasNext)
|
||||
require.Len(t, bchr.Results, count-2) // two boards deleted
|
||||
})
|
||||
|
||||
t.Run("good call, include deleted", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 10
|
||||
boards := th.CreateBoards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
deleted, resp := th.Client.DeleteBoard(boards[0].ID)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
deleted, resp = th.Client.DeleteBoard(boards[1].ID)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
bchr, resp := clients.Admin.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, 0, 0)
|
||||
th.CheckOK(resp)
|
||||
require.False(t, bchr.HasNext)
|
||||
require.Len(t, bchr.Results, count+2) // both deleted boards have 2 history records each
|
||||
})
|
||||
|
||||
t.Run("pagination", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 20
|
||||
const perPage = 3
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
boardHistory := make([]*model.BoardHistory, 0, count)
|
||||
page := 0
|
||||
for {
|
||||
bchr, resp := clients.Admin.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, page, perPage)
|
||||
page++
|
||||
th.CheckOK(resp)
|
||||
boardHistory = append(boardHistory, bchr.Results...)
|
||||
if !bchr.HasNext {
|
||||
break
|
||||
}
|
||||
}
|
||||
require.Len(t, boardHistory, count)
|
||||
require.Equal(t, int(math.Floor((count/perPage)+1)), page)
|
||||
})
|
||||
|
||||
t.Run("invalid teamID", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_ = th.CreateBoards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.Admin.GetBoardsComplianceHistory(utils.GetMillis()-OneDay, true, utils.NewID(utils.IDTypeTeam), 0, 0)
|
||||
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetBlocksComplianceHistory(t *testing.T) {
|
||||
t.Run("missing Features.Compliance license should fail", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, false)
|
||||
defer th.TearDown()
|
||||
|
||||
board, _ := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.Admin.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, board.ID, 0, 0)
|
||||
|
||||
th.CheckNotImplemented(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
board, _ := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.Anon.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, board.ID, 0, 0)
|
||||
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("a user without manage_system permission should be rejected", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
board, _ := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.TeamMember.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, board.ID, 0, 0)
|
||||
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("good call, exclude deleted", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 10
|
||||
board, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
deleted, resp := th.Client.DeleteBlock(board.ID, cards[0].ID, true)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
deleted, resp = th.Client.DeleteBlock(board.ID, cards[1].ID, true)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
bchr, resp := clients.Admin.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, false, testTeamID, board.ID, 0, 0)
|
||||
th.CheckOK(resp)
|
||||
require.False(t, bchr.HasNext)
|
||||
require.Len(t, bchr.Results, count-2) // 2 blocks deleted
|
||||
})
|
||||
|
||||
t.Run("good call, include deleted", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 10
|
||||
board, cards := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
deleted, resp := th.Client.DeleteBlock(board.ID, cards[0].ID, true)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
deleted, resp = th.Client.DeleteBlock(board.ID, cards[1].ID, true)
|
||||
th.CheckOK(resp)
|
||||
require.True(t, deleted)
|
||||
|
||||
bchr, resp := clients.Admin.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, board.ID, 0, 0)
|
||||
th.CheckOK(resp)
|
||||
require.False(t, bchr.HasNext)
|
||||
require.Len(t, bchr.Results, count+2) // both deleted boards have 2 history records each
|
||||
})
|
||||
|
||||
t.Run("pagination", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
const count = 20
|
||||
const perPage = 3
|
||||
board, _ := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, count)
|
||||
|
||||
blockHistory := make([]*model.BlockHistory, 0, count)
|
||||
page := 0
|
||||
for {
|
||||
bchr, resp := clients.Admin.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, board.ID, page, perPage)
|
||||
page++
|
||||
th.CheckOK(resp)
|
||||
blockHistory = append(blockHistory, bchr.Results...)
|
||||
if !bchr.HasNext {
|
||||
break
|
||||
}
|
||||
}
|
||||
require.Len(t, blockHistory, count)
|
||||
require.Equal(t, int(math.Floor((count/perPage)+1)), page)
|
||||
})
|
||||
|
||||
t.Run("invalid teamID", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
board, _ := th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.Admin.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, utils.NewID(utils.IDTypeTeam), board.ID, 0, 0)
|
||||
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
|
||||
t.Run("invalid boardID", func(t *testing.T) {
|
||||
th, clients := setupTestHelperForCompliance(t, true)
|
||||
defer th.TearDown()
|
||||
|
||||
_, _ = th.CreateBoardAndCards(testTeamID, model.BoardTypeOpen, 2)
|
||||
|
||||
bchr, resp := clients.Admin.GetBlocksComplianceHistory(utils.GetMillis()-OneDay, true, testTeamID, utils.NewID(utils.IDTypeBoard), 0, 0)
|
||||
|
||||
th.CheckBadRequest(resp)
|
||||
require.Nil(t, bchr)
|
||||
})
|
||||
}
|
||||
102
server/boards/integrationtests/configuration_test.go
Обычный файл
102
server/boards/integrationtests/configuration_test.go
Обычный файл
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/server"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/ws"
|
||||
|
||||
mockservicesapi "github.com/mattermost/mattermost-server/v6/server/boards/model/mocks"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfigurationNullConfiguration(t *testing.T) {
|
||||
th := SetupTestHelperPluginMode(t)
|
||||
defer th.TearDown()
|
||||
|
||||
logger := mlog.CreateConsoleTestLogger(true, mlog.LvlError)
|
||||
boardsApp := server.NewBoardsServiceForTest(th.Server, &FakePluginAdapter{}, nil, logger)
|
||||
|
||||
assert.NotNil(t, boardsApp.Config())
|
||||
}
|
||||
|
||||
func TestOnConfigurationChange(t *testing.T) {
|
||||
stringRef := ""
|
||||
|
||||
basePlugins := make(map[string]map[string]interface{})
|
||||
basePlugins[server.PluginName] = make(map[string]interface{})
|
||||
basePlugins[server.PluginName][server.SharedBoardsName] = true
|
||||
|
||||
baseFeatureFlags := &mm_model.FeatureFlags{
|
||||
BoardsFeatureFlags: "Feature1-Feature2",
|
||||
}
|
||||
basePluginSettings := &mm_model.PluginSettings{
|
||||
Directory: &stringRef,
|
||||
Plugins: basePlugins,
|
||||
}
|
||||
intRef := 365
|
||||
baseDataRetentionSettings := &mm_model.DataRetentionSettings{
|
||||
BoardsRetentionDays: &intRef,
|
||||
}
|
||||
usernameRef := "username"
|
||||
baseTeamSettings := &mm_model.TeamSettings{
|
||||
TeammateNameDisplay: &usernameRef,
|
||||
}
|
||||
|
||||
falseRef := false
|
||||
basePrivacySettings := &mm_model.PrivacySettings{
|
||||
ShowEmailAddress: &falseRef,
|
||||
ShowFullName: &falseRef,
|
||||
}
|
||||
|
||||
baseConfig := &mm_model.Config{
|
||||
FeatureFlags: baseFeatureFlags,
|
||||
PluginSettings: *basePluginSettings,
|
||||
DataRetentionSettings: *baseDataRetentionSettings,
|
||||
TeamSettings: *baseTeamSettings,
|
||||
PrivacySettings: *basePrivacySettings,
|
||||
}
|
||||
|
||||
t.Run("Test Load Plugin Success", func(t *testing.T) {
|
||||
th := SetupTestHelperPluginMode(t)
|
||||
defer th.TearDown()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
api := mockservicesapi.NewMockServicesAPI(ctrl)
|
||||
api.EXPECT().GetConfig().Return(baseConfig)
|
||||
|
||||
b := server.NewBoardsServiceForTest(th.Server, &FakePluginAdapter{}, api, mlog.CreateConsoleTestLogger(true, mlog.LvlError))
|
||||
|
||||
err := b.OnConfigurationChange()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, count)
|
||||
|
||||
// make sure both App and Server got updated
|
||||
assert.True(t, b.Config().EnablePublicSharedBoards)
|
||||
assert.True(t, b.ClientConfig().EnablePublicSharedBoards)
|
||||
|
||||
assert.Equal(t, "true", b.Config().FeatureFlags["Feature1"])
|
||||
assert.Equal(t, "true", b.Config().FeatureFlags["Feature2"])
|
||||
assert.Equal(t, "", b.Config().FeatureFlags["Feature3"])
|
||||
})
|
||||
}
|
||||
|
||||
var count = 0
|
||||
|
||||
type FakePluginAdapter struct {
|
||||
ws.PluginAdapter
|
||||
}
|
||||
|
||||
func (c *FakePluginAdapter) BroadcastConfigChange(clientConfig model.ClientConfig) {
|
||||
count++
|
||||
}
|
||||
185
server/boards/integrationtests/content_blocks_test.go
Обычный файл
185
server/boards/integrationtests/content_blocks_test.go
Обычный файл
@@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMoveContentBlock(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
board := th.CreateBoard("team-id", model.BoardTypeOpen)
|
||||
|
||||
cardID1 := utils.NewID(utils.IDTypeBlock)
|
||||
cardID2 := utils.NewID(utils.IDTypeBlock)
|
||||
contentBlockID1 := utils.NewID(utils.IDTypeBlock)
|
||||
contentBlockID2 := utils.NewID(utils.IDTypeBlock)
|
||||
contentBlockID3 := utils.NewID(utils.IDTypeBlock)
|
||||
contentBlockID4 := utils.NewID(utils.IDTypeBlock)
|
||||
contentBlockID5 := utils.NewID(utils.IDTypeBlock)
|
||||
contentBlockID6 := utils.NewID(utils.IDTypeBlock)
|
||||
|
||||
card1 := &model.Block{
|
||||
ID: cardID1,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
Fields: map[string]interface{}{
|
||||
"contentOrder": []string{contentBlockID1, contentBlockID2, contentBlockID3},
|
||||
},
|
||||
}
|
||||
card2 := &model.Block{
|
||||
ID: cardID2,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
Fields: map[string]interface{}{
|
||||
"contentOrder": []string{contentBlockID4, contentBlockID5, contentBlockID6},
|
||||
},
|
||||
}
|
||||
|
||||
contentBlock1 := &model.Block{
|
||||
ID: contentBlockID1,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
ParentID: cardID1,
|
||||
}
|
||||
contentBlock2 := &model.Block{
|
||||
ID: contentBlockID2,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
ParentID: cardID1,
|
||||
}
|
||||
contentBlock3 := &model.Block{
|
||||
ID: contentBlockID3,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
ParentID: cardID1,
|
||||
}
|
||||
contentBlock4 := &model.Block{
|
||||
ID: contentBlockID4,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
ParentID: cardID2,
|
||||
}
|
||||
contentBlock5 := &model.Block{
|
||||
ID: contentBlockID5,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
ParentID: cardID2,
|
||||
}
|
||||
contentBlock6 := &model.Block{
|
||||
ID: contentBlockID6,
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
ParentID: cardID2,
|
||||
}
|
||||
|
||||
newBlocks := []*model.Block{
|
||||
contentBlock1,
|
||||
contentBlock2,
|
||||
contentBlock3,
|
||||
contentBlock4,
|
||||
contentBlock5,
|
||||
contentBlock6,
|
||||
card1,
|
||||
card2,
|
||||
}
|
||||
createdBlocks, resp := th.Client.InsertBlocks(board.ID, newBlocks, false)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, newBlocks, 8)
|
||||
|
||||
contentBlock1.ID = createdBlocks[0].ID
|
||||
contentBlock2.ID = createdBlocks[1].ID
|
||||
contentBlock3.ID = createdBlocks[2].ID
|
||||
contentBlock4.ID = createdBlocks[3].ID
|
||||
contentBlock5.ID = createdBlocks[4].ID
|
||||
contentBlock6.ID = createdBlocks[5].ID
|
||||
card1.ID = createdBlocks[6].ID
|
||||
card2.ID = createdBlocks[7].ID
|
||||
|
||||
ttCases := []struct {
|
||||
name string
|
||||
srcBlockID string
|
||||
dstBlockID string
|
||||
where string
|
||||
userID string
|
||||
errorMessage string
|
||||
expectedContentOrder []interface{}
|
||||
}{
|
||||
{
|
||||
name: "not matching parents",
|
||||
srcBlockID: contentBlock1.ID,
|
||||
dstBlockID: contentBlock4.ID,
|
||||
where: "after",
|
||||
userID: "user-id",
|
||||
errorMessage: fmt.Sprintf("payload: {\"error\":\"not matching parent %s and %s\",\"errorCode\":400}", card1.ID, card2.ID),
|
||||
expectedContentOrder: []interface{}{contentBlock1.ID, contentBlock2.ID, contentBlock3.ID},
|
||||
},
|
||||
{
|
||||
name: "valid request with not real change",
|
||||
srcBlockID: contentBlock2.ID,
|
||||
dstBlockID: contentBlock1.ID,
|
||||
where: "after",
|
||||
userID: "user-id",
|
||||
errorMessage: "",
|
||||
expectedContentOrder: []interface{}{contentBlock1.ID, contentBlock2.ID, contentBlock3.ID},
|
||||
},
|
||||
{
|
||||
name: "valid request changing order with before",
|
||||
srcBlockID: contentBlock2.ID,
|
||||
dstBlockID: contentBlock1.ID,
|
||||
where: "before",
|
||||
userID: "user-id",
|
||||
errorMessage: "",
|
||||
expectedContentOrder: []interface{}{contentBlock2.ID, contentBlock1.ID, contentBlock3.ID},
|
||||
},
|
||||
{
|
||||
name: "valid request changing order with after",
|
||||
srcBlockID: contentBlock1.ID,
|
||||
dstBlockID: contentBlock2.ID,
|
||||
where: "after",
|
||||
userID: "user-id",
|
||||
errorMessage: "",
|
||||
expectedContentOrder: []interface{}{contentBlock2.ID, contentBlock1.ID, contentBlock3.ID},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range ttCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, resp := th.Client.MoveContentBlock(tc.srcBlockID, tc.dstBlockID, tc.where, tc.userID)
|
||||
if tc.errorMessage == "" {
|
||||
require.NoError(t, resp.Error)
|
||||
} else {
|
||||
require.EqualError(t, resp.Error, tc.errorMessage)
|
||||
}
|
||||
|
||||
parent, err := th.Server.App().GetBlockByID(card1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, parent.Fields["contentOrder"], tc.expectedContentOrder)
|
||||
})
|
||||
}
|
||||
}
|
||||
70
server/boards/integrationtests/export_test.go
Обычный файл
70
server/boards/integrationtests/export_test.go
Обычный файл
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
)
|
||||
|
||||
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, true)
|
||||
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)
|
||||
})
|
||||
}
|
||||
91
server/boards/integrationtests/file_test.go
Обычный файл
91
server/boards/integrationtests/file_test.go
Обычный файл
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUploadFile(t *testing.T) {
|
||||
const (
|
||||
testTeamID = "team-id"
|
||||
)
|
||||
|
||||
t.Run("a non authenticated user should be rejected", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
th.Logout(th.Client)
|
||||
|
||||
file, resp := th.Client.TeamUploadFile(testTeamID, "test-board-id", bytes.NewBuffer([]byte("test")))
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, file)
|
||||
})
|
||||
|
||||
t.Run("upload a file to an existing team and board without permissions", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
file, resp := th.Client.TeamUploadFile(testTeamID, "not-valid-board", bytes.NewBuffer([]byte("test")))
|
||||
th.CheckForbidden(resp)
|
||||
require.Nil(t, file)
|
||||
})
|
||||
|
||||
t.Run("upload a file to an existing team and board with permissions", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
testBoard := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
file, resp := th.Client.TeamUploadFile(testTeamID, testBoard.ID, bytes.NewBuffer([]byte("test")))
|
||||
th.CheckOK(resp)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, file)
|
||||
require.NotNil(t, file.FileID)
|
||||
})
|
||||
|
||||
t.Run("upload a file to an existing team and board with permissions but reaching the MaxFileLimit", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
testBoard := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
|
||||
config := th.Server.App().GetConfig()
|
||||
config.MaxFileSize = 1
|
||||
th.Server.App().SetConfig(config)
|
||||
|
||||
file, resp := th.Client.TeamUploadFile(testTeamID, testBoard.ID, bytes.NewBuffer([]byte("test")))
|
||||
th.CheckRequestEntityTooLarge(resp)
|
||||
require.Nil(t, file)
|
||||
|
||||
config.MaxFileSize = 100000
|
||||
th.Server.App().SetConfig(config)
|
||||
|
||||
file, resp = th.Client.TeamUploadFile(testTeamID, testBoard.ID, bytes.NewBuffer([]byte("test")))
|
||||
th.CheckOK(resp)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, file)
|
||||
require.NotNil(t, file.FileID)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFileInfo(t *testing.T) {
|
||||
const (
|
||||
testTeamID = "team-id"
|
||||
)
|
||||
|
||||
t.Run("Retrieving file info", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
testBoard := th.CreateBoard(testTeamID, model.BoardTypeOpen)
|
||||
|
||||
fileInfo, resp := th.Client.TeamUploadFileInfo(testTeamID, testBoard.ID, "test")
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, fileInfo)
|
||||
require.NotNil(t, fileInfo.Id)
|
||||
})
|
||||
}
|
||||
3926
server/boards/integrationtests/permissions_test.go
Обычный файл
3926
server/boards/integrationtests/permissions_test.go
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
324
server/boards/integrationtests/pluginteststore.go
Обычный файл
324
server/boards/integrationtests/pluginteststore.go
Обычный файл
@@ -0,0 +1,324 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/store"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
var errTestStore = errors.New("plugin test store error")
|
||||
|
||||
type PluginTestStore struct {
|
||||
store.Store
|
||||
users map[string]*model.User
|
||||
testTeam *model.Team
|
||||
otherTeam *model.Team
|
||||
emptyTeam *model.Team
|
||||
baseTeam *model.Team
|
||||
}
|
||||
|
||||
func NewPluginTestStore(innerStore store.Store) *PluginTestStore {
|
||||
return &PluginTestStore{
|
||||
Store: innerStore,
|
||||
users: map[string]*model.User{
|
||||
"no-team-member": {
|
||||
ID: "no-team-member",
|
||||
Username: "no-team-member",
|
||||
Email: "no-team-member@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
},
|
||||
"team-member": {
|
||||
ID: "team-member",
|
||||
Username: "team-member",
|
||||
Email: "team-member@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
},
|
||||
"viewer": {
|
||||
ID: "viewer",
|
||||
Username: "viewer",
|
||||
Email: "viewer@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
},
|
||||
"commenter": {
|
||||
ID: "commenter",
|
||||
Username: "commenter",
|
||||
Email: "commenter@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
},
|
||||
"editor": {
|
||||
ID: "editor",
|
||||
Username: "editor",
|
||||
Email: "editor@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
},
|
||||
"admin": {
|
||||
ID: "admin",
|
||||
Username: "admin",
|
||||
Email: "admin@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
},
|
||||
"guest": {
|
||||
ID: "guest",
|
||||
Username: "guest",
|
||||
Email: "guest@sample.com",
|
||||
CreateAt: model.GetMillis(),
|
||||
UpdateAt: model.GetMillis(),
|
||||
IsGuest: true,
|
||||
},
|
||||
},
|
||||
testTeam: &model.Team{ID: "test-team", Title: "Test Team"},
|
||||
otherTeam: &model.Team{ID: "other-team", Title: "Other Team"},
|
||||
emptyTeam: &model.Team{ID: "empty-team", Title: "Empty Team"},
|
||||
baseTeam: &model.Team{ID: "0", Title: "Base Team"},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetTeam(id string) (*model.Team, error) {
|
||||
switch id {
|
||||
case "0":
|
||||
return s.baseTeam, nil
|
||||
case "other-team":
|
||||
return s.otherTeam, nil
|
||||
case "test-team", testTeamID:
|
||||
return s.testTeam, nil
|
||||
case "empty-team":
|
||||
return s.emptyTeam, nil
|
||||
}
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetTeamsForUser(userID string) ([]*model.Team, error) {
|
||||
switch userID {
|
||||
case "no-team-member":
|
||||
return []*model.Team{}, nil
|
||||
case "team-member":
|
||||
return []*model.Team{s.testTeam, s.otherTeam}, nil
|
||||
case "viewer":
|
||||
return []*model.Team{s.testTeam, s.otherTeam}, nil
|
||||
case "commenter":
|
||||
return []*model.Team{s.testTeam, s.otherTeam}, nil
|
||||
case "editor":
|
||||
return []*model.Team{s.testTeam, s.otherTeam}, nil
|
||||
case "admin":
|
||||
return []*model.Team{s.testTeam, s.otherTeam}, nil
|
||||
case "guest":
|
||||
return []*model.Team{s.testTeam}, nil
|
||||
}
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetUserByID(userID string) (*model.User, error) {
|
||||
user := s.users[userID]
|
||||
if user == nil {
|
||||
return nil, errTestStore
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetUserByEmail(email string) (*model.User, error) {
|
||||
for _, user := range s.users {
|
||||
if user.Email == email {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetUserByUsername(username string) (*model.User, error) {
|
||||
for _, user := range s.users {
|
||||
if user.Username == username {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetUserPreferences(userID string) (mm_model.Preferences, error) {
|
||||
if userID == userTeamMember {
|
||||
return mm_model.Preferences{{
|
||||
UserId: userTeamMember,
|
||||
Category: "focalboard",
|
||||
Name: "test",
|
||||
Value: "test",
|
||||
}}, nil
|
||||
}
|
||||
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetUsersByTeam(teamID string, asGuestID string, showEmail, showName bool) ([]*model.User, error) {
|
||||
if asGuestID == "guest" {
|
||||
return []*model.User{
|
||||
s.users["viewer"],
|
||||
s.users["commenter"],
|
||||
s.users["editor"],
|
||||
s.users["admin"],
|
||||
s.users["guest"],
|
||||
}, nil
|
||||
}
|
||||
|
||||
switch {
|
||||
case teamID == s.testTeam.ID:
|
||||
return []*model.User{
|
||||
s.users["team-member"],
|
||||
s.users["viewer"],
|
||||
s.users["commenter"],
|
||||
s.users["editor"],
|
||||
s.users["admin"],
|
||||
s.users["guest"],
|
||||
}, nil
|
||||
case teamID == s.otherTeam.ID:
|
||||
return []*model.User{
|
||||
s.users["team-member"],
|
||||
s.users["viewer"],
|
||||
s.users["commenter"],
|
||||
s.users["editor"],
|
||||
s.users["admin"],
|
||||
}, nil
|
||||
case teamID == s.emptyTeam.ID:
|
||||
return []*model.User{}, nil
|
||||
}
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) SearchUsersByTeam(teamID string, searchQuery string, asGuestID string, excludeBots bool, showEmail, showName bool) ([]*model.User, error) {
|
||||
users := []*model.User{}
|
||||
teamUsers, err := s.GetUsersByTeam(teamID, asGuestID, showEmail, showName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, user := range teamUsers {
|
||||
if excludeBots && user.IsBot {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(user.Username, searchQuery) {
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) CanSeeUser(seerID string, seenID string) (bool, error) {
|
||||
user, err := s.GetUserByID(seerID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !user.IsGuest {
|
||||
return true, nil
|
||||
}
|
||||
seerMembers, err := s.GetMembersForUser(seerID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
seenMembers, err := s.GetMembersForUser(seenID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, seerMember := range seerMembers {
|
||||
for _, seenMember := range seenMembers {
|
||||
if seerMember.BoardID == seenMember.BoardID {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) SearchUserChannels(teamID, userID, query string) ([]*mm_model.Channel, error) {
|
||||
return []*mm_model.Channel{
|
||||
{
|
||||
TeamId: teamID,
|
||||
Id: "valid-channel-id",
|
||||
DisplayName: "Valid Channel",
|
||||
Name: "valid-channel",
|
||||
},
|
||||
{
|
||||
TeamId: teamID,
|
||||
Id: "valid-channel-id-2",
|
||||
DisplayName: "Valid Channel 2",
|
||||
Name: "valid-channel-2",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetChannel(teamID, channel string) (*mm_model.Channel, error) {
|
||||
if channel == "valid-channel-id" {
|
||||
return &mm_model.Channel{
|
||||
TeamId: teamID,
|
||||
Id: "valid-channel-id",
|
||||
DisplayName: "Valid Channel",
|
||||
Name: "valid-channel",
|
||||
}, nil
|
||||
} else if channel == "valid-channel-id-2" {
|
||||
return &mm_model.Channel{
|
||||
TeamId: teamID,
|
||||
Id: "valid-channel-id-2",
|
||||
DisplayName: "Valid Channel 2",
|
||||
Name: "valid-channel-2",
|
||||
}, nil
|
||||
}
|
||||
return nil, errTestStore
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) SearchBoardsForUser(term string, field model.BoardSearchField, userID string, includePublicBoards bool) ([]*model.Board, error) {
|
||||
boards, err := s.Store.SearchBoardsForUser(term, field, userID, includePublicBoards)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
teams, err := s.GetTeamsForUser(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resultBoards := []*model.Board{}
|
||||
for _, board := range boards {
|
||||
for _, team := range teams {
|
||||
if team.ID == board.TeamID {
|
||||
resultBoards = append(resultBoards, board)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultBoards, nil
|
||||
}
|
||||
|
||||
func (s *PluginTestStore) GetLicense() *mm_model.License {
|
||||
license := s.Store.GetLicense()
|
||||
|
||||
if license == nil {
|
||||
license = &mm_model.License{
|
||||
Id: mm_model.NewId(),
|
||||
StartsAt: mm_model.GetMillis() - 2629746000, // 1 month
|
||||
ExpiresAt: mm_model.GetMillis() + 2629746000, //
|
||||
IssuedAt: mm_model.GetMillis() - 2629746000,
|
||||
Features: &mm_model.Features{},
|
||||
}
|
||||
license.Features.SetDefaults()
|
||||
}
|
||||
|
||||
complianceLicense := os.Getenv("FOCALBOARD_UNIT_TESTING_COMPLIANCE")
|
||||
if complianceLicense != "" {
|
||||
if val, err := strconv.ParseBool(complianceLicense); err == nil {
|
||||
license.Features.Compliance = mm_model.NewBool(val)
|
||||
}
|
||||
}
|
||||
|
||||
return license
|
||||
}
|
||||
98
server/boards/integrationtests/sharing_test.go
Обычный файл
98
server/boards/integrationtests/sharing_test.go
Обычный файл
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
)
|
||||
|
||||
func TestSharing(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
var boardID string
|
||||
token := utils.NewID(utils.IDTypeToken)
|
||||
|
||||
t.Run("an unauthenticated client should not be able to get a sharing", func(t *testing.T) {
|
||||
th.Logout(th.Client)
|
||||
|
||||
sharing, resp := th.Client.GetSharing("board-id")
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, sharing)
|
||||
})
|
||||
|
||||
t.Run("Check no initial sharing", func(t *testing.T) {
|
||||
th.Login1()
|
||||
|
||||
teamID := "0"
|
||||
newBoard := &model.Board{
|
||||
TeamID: teamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
}
|
||||
|
||||
board, err := th.Server.App().CreateBoard(newBoard, th.GetUser1().ID, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, board)
|
||||
boardID = board.ID
|
||||
|
||||
s, err := th.Server.App().GetSharing(boardID)
|
||||
require.Error(t, err)
|
||||
require.True(t, model.IsErrNotFound(err))
|
||||
require.Nil(t, s)
|
||||
|
||||
sharing, resp := th.Client.GetSharing(boardID)
|
||||
th.CheckNotFound(resp)
|
||||
require.Nil(t, sharing)
|
||||
})
|
||||
|
||||
t.Run("POST sharing, config = false", func(t *testing.T) {
|
||||
sharing := model.Sharing{
|
||||
ID: boardID,
|
||||
Token: token,
|
||||
Enabled: true,
|
||||
UpdateAt: 1,
|
||||
}
|
||||
|
||||
// it will fail with default config
|
||||
success, resp := th.Client.PostSharing(&sharing)
|
||||
require.False(t, success)
|
||||
require.Error(t, resp.Error)
|
||||
|
||||
t.Run("GET sharing", func(t *testing.T) {
|
||||
sharing, resp := th.Client.GetSharing(boardID)
|
||||
// Expect empty sharing object
|
||||
th.CheckNotFound(resp)
|
||||
require.Nil(t, sharing)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("POST sharing, config = true", func(t *testing.T) {
|
||||
th.Server.Config().EnablePublicSharedBoards = true
|
||||
sharing := model.Sharing{
|
||||
ID: boardID,
|
||||
Token: token,
|
||||
Enabled: true,
|
||||
UpdateAt: 1,
|
||||
}
|
||||
|
||||
// it will succeed with updated config
|
||||
success, resp := th.Client.PostSharing(&sharing)
|
||||
require.True(t, success)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
t.Run("GET sharing", func(t *testing.T) {
|
||||
sharing, resp := th.Client.GetSharing(boardID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, sharing)
|
||||
require.Equal(t, sharing.ID, boardID)
|
||||
require.True(t, sharing.Enabled)
|
||||
require.Equal(t, sharing.Token, token)
|
||||
})
|
||||
})
|
||||
}
|
||||
102
server/boards/integrationtests/sidebar_test.go
Обычный файл
102
server/boards/integrationtests/sidebar_test.go
Обычный файл
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
)
|
||||
|
||||
func TestSidebar(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
// we'll create a new board.
|
||||
// The board should end up in a default "Boards" category
|
||||
board := th.CreateBoard("team-id", "O")
|
||||
|
||||
categoryBoards := th.GetUserCategoryBoards("team-id")
|
||||
require.Equal(t, 1, len(categoryBoards))
|
||||
require.Equal(t, "Boards", categoryBoards[0].Name)
|
||||
require.Equal(t, 1, len(categoryBoards[0].BoardMetadata))
|
||||
require.Equal(t, board.ID, categoryBoards[0].BoardMetadata[0].BoardID)
|
||||
|
||||
// create a new category, a new board
|
||||
// and move that board into the new category
|
||||
board2 := th.CreateBoard("team-id", "O")
|
||||
category := th.CreateCategory(model.Category{
|
||||
Name: "Category 2",
|
||||
TeamID: "team-id",
|
||||
UserID: "single-user",
|
||||
})
|
||||
th.UpdateCategoryBoard("team-id", category.ID, board2.ID)
|
||||
|
||||
categoryBoards = th.GetUserCategoryBoards("team-id")
|
||||
// now there should be two categories - boards and the one
|
||||
// we created just now
|
||||
require.Equal(t, 2, len(categoryBoards))
|
||||
|
||||
// the newly created category should be the first one array
|
||||
// as new categories end up on top in LHS
|
||||
require.Equal(t, "Category 2", categoryBoards[0].Name)
|
||||
require.Equal(t, 1, len(categoryBoards[0].BoardMetadata))
|
||||
require.Equal(t, board2.ID, categoryBoards[0].BoardMetadata[0].BoardID)
|
||||
|
||||
// now we'll delete the custom category we created, "Category 2"
|
||||
// and all it's boards should get moved to the Boards category
|
||||
th.DeleteCategory("team-id", category.ID)
|
||||
categoryBoards = th.GetUserCategoryBoards("team-id")
|
||||
require.Equal(t, 1, len(categoryBoards))
|
||||
require.Equal(t, "Boards", categoryBoards[0].Name)
|
||||
require.Equal(t, 2, len(categoryBoards[0].BoardMetadata))
|
||||
require.Contains(t, categoryBoards[0].BoardMetadata, model.CategoryBoardMetadata{BoardID: board.ID, Hidden: false})
|
||||
require.Contains(t, categoryBoards[0].BoardMetadata, model.CategoryBoardMetadata{BoardID: board2.ID, Hidden: false})
|
||||
}
|
||||
|
||||
func TestHideUnhideBoard(t *testing.T) {
|
||||
th := SetupTestHelperWithToken(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
// we'll create a new board.
|
||||
// The board should end up in a default "Boards" category
|
||||
th.CreateBoard("team-id", "O")
|
||||
|
||||
// the created board should not be hidden
|
||||
categoryBoards := th.GetUserCategoryBoards("team-id")
|
||||
require.Equal(t, 1, len(categoryBoards))
|
||||
require.Equal(t, "Boards", categoryBoards[0].Name)
|
||||
require.Equal(t, 1, len(categoryBoards[0].BoardMetadata))
|
||||
require.False(t, categoryBoards[0].BoardMetadata[0].Hidden)
|
||||
|
||||
// now we'll hide the board
|
||||
response := th.Client.HideBoard("team-id", categoryBoards[0].ID, categoryBoards[0].BoardMetadata[0].BoardID)
|
||||
th.CheckOK(response)
|
||||
|
||||
// verifying if the board has been marked as hidden
|
||||
categoryBoards = th.GetUserCategoryBoards("team-id")
|
||||
require.True(t, categoryBoards[0].BoardMetadata[0].Hidden)
|
||||
|
||||
// trying to hide the already hidden board.This should have no effect
|
||||
response = th.Client.HideBoard("team-id", categoryBoards[0].ID, categoryBoards[0].BoardMetadata[0].BoardID)
|
||||
th.CheckOK(response)
|
||||
categoryBoards = th.GetUserCategoryBoards("team-id")
|
||||
require.True(t, categoryBoards[0].BoardMetadata[0].Hidden)
|
||||
|
||||
// now we'll unhide the board
|
||||
response = th.Client.UnhideBoard("team-id", categoryBoards[0].ID, categoryBoards[0].BoardMetadata[0].BoardID)
|
||||
th.CheckOK(response)
|
||||
|
||||
// verifying
|
||||
categoryBoards = th.GetUserCategoryBoards("team-id")
|
||||
require.False(t, categoryBoards[0].BoardMetadata[0].Hidden)
|
||||
|
||||
// trying to unhide the already visible board.This should have no effect
|
||||
response = th.Client.UnhideBoard("team-id", categoryBoards[0].ID, categoryBoards[0].BoardMetadata[0].BoardID)
|
||||
th.CheckOK(response)
|
||||
categoryBoards = th.GetUserCategoryBoards("team-id")
|
||||
require.False(t, categoryBoards[0].BoardMetadata[0].Hidden)
|
||||
}
|
||||
59
server/boards/integrationtests/statistics_test.go
Обычный файл
59
server/boards/integrationtests/statistics_test.go
Обычный файл
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/client"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
)
|
||||
|
||||
func TestStatisticsLocalMode(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("an unauthenticated client should not be able to get statistics", func(t *testing.T) {
|
||||
th.Logout(th.Client)
|
||||
|
||||
stats, resp := th.Client.GetStatistics()
|
||||
th.CheckUnauthorized(resp)
|
||||
require.Nil(t, stats)
|
||||
})
|
||||
|
||||
t.Run("Check authenticated user, not admin", func(t *testing.T) {
|
||||
th.Login1()
|
||||
|
||||
stats, resp := th.Client.GetStatistics()
|
||||
th.CheckNotImplemented(resp)
|
||||
require.Nil(t, stats)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatisticsPluginMode(t *testing.T) {
|
||||
th := SetupTestHelperPluginMode(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Permissions are tested in permissions_test.go
|
||||
// This tests the functionality.
|
||||
t.Run("Check authenticated user, admin", func(t *testing.T) {
|
||||
th.Client = client.NewClient(th.Server.Config().ServerRoot, "")
|
||||
th.Client.HTTPHeader["Mattermost-User-Id"] = userAdmin
|
||||
|
||||
stats, resp := th.Client.GetStatistics()
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, stats)
|
||||
|
||||
numberCards := 2
|
||||
th.CreateBoardAndCards("testTeam", model.BoardTypeOpen, numberCards)
|
||||
|
||||
stats, resp = th.Client.GetStatistics()
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, stats)
|
||||
require.Equal(t, 1, stats.Boards)
|
||||
require.Equal(t, numberCards, stats.Cards)
|
||||
})
|
||||
}
|
||||
156
server/boards/integrationtests/subscriptions_test.go
Обычный файл
156
server/boards/integrationtests/subscriptions_test.go
Обычный файл
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/client"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
)
|
||||
|
||||
func createTestSubscriptions(client *client.Client, num int) ([]*model.Subscription, string, error) {
|
||||
newSubs := make([]*model.Subscription, 0, num)
|
||||
|
||||
user, resp := client.GetMe()
|
||||
if resp.Error != nil {
|
||||
return nil, "", fmt.Errorf("cannot get current user: %w", resp.Error)
|
||||
}
|
||||
|
||||
board := &model.Board{
|
||||
TeamID: "0",
|
||||
Type: model.BoardTypeOpen,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
}
|
||||
board, resp = client.CreateBoard(board)
|
||||
if resp.Error != nil {
|
||||
return nil, "", fmt.Errorf("cannot insert test board block: %w", resp.Error)
|
||||
}
|
||||
|
||||
for n := 0; n < num; n++ {
|
||||
newBlock := &model.Block{
|
||||
ID: utils.NewID(utils.IDTypeCard),
|
||||
BoardID: board.ID,
|
||||
CreateAt: 1,
|
||||
UpdateAt: 1,
|
||||
Type: model.TypeCard,
|
||||
}
|
||||
|
||||
newBlocks, resp := client.InsertBlocks(board.ID, []*model.Block{newBlock}, false)
|
||||
if resp.Error != nil {
|
||||
return nil, "", fmt.Errorf("cannot insert test card block: %w", resp.Error)
|
||||
}
|
||||
newBlock = newBlocks[0]
|
||||
|
||||
sub := &model.Subscription{
|
||||
BlockType: newBlock.Type,
|
||||
BlockID: newBlock.ID,
|
||||
SubscriberType: model.SubTypeUser,
|
||||
SubscriberID: user.ID,
|
||||
}
|
||||
|
||||
subNew, resp := client.CreateSubscription(sub)
|
||||
if resp.Error != nil {
|
||||
return nil, "", resp.Error
|
||||
}
|
||||
newSubs = append(newSubs, subNew)
|
||||
}
|
||||
return newSubs, user.ID, nil
|
||||
}
|
||||
|
||||
func TestCreateSubscription(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("Create valid subscription", func(t *testing.T) {
|
||||
subs, userID, err := createTestSubscriptions(th.Client, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, subs, 5)
|
||||
|
||||
// fetch the newly created subscriptions and compare
|
||||
subsFound, resp := th.Client.GetSubscriptions(userID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, subsFound, 5)
|
||||
assert.ElementsMatch(t, subs, subsFound)
|
||||
})
|
||||
|
||||
t.Run("Create invalid subscription", func(t *testing.T) {
|
||||
user, resp := th.Client.GetMe()
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
sub := &model.Subscription{
|
||||
SubscriberID: user.ID,
|
||||
}
|
||||
_, resp = th.Client.CreateSubscription(sub)
|
||||
require.Error(t, resp.Error)
|
||||
})
|
||||
|
||||
t.Run("Create subscription for another user", func(t *testing.T) {
|
||||
sub := &model.Subscription{
|
||||
SubscriberID: utils.NewID(utils.IDTypeUser),
|
||||
}
|
||||
_, resp := th.Client.CreateSubscription(sub)
|
||||
require.Error(t, resp.Error)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetSubscriptions(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("Get subscriptions for user", func(t *testing.T) {
|
||||
mySubs, user1ID, err := createTestSubscriptions(th.Client, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, mySubs, 5)
|
||||
|
||||
// create more subscriptions with different user
|
||||
otherSubs, _, err := createTestSubscriptions(th.Client2, 10)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, otherSubs, 10)
|
||||
|
||||
// fetch the newly created subscriptions for current user, making sure only
|
||||
// the ones created for the current user are returned.
|
||||
subsFound, resp := th.Client.GetSubscriptions(user1ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, subsFound, 5)
|
||||
assert.ElementsMatch(t, mySubs, subsFound)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteSubscription(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("Delete valid subscription", func(t *testing.T) {
|
||||
subs, userID, err := createTestSubscriptions(th.Client, 3)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, subs, 3)
|
||||
|
||||
resp := th.Client.DeleteSubscription(subs[1].BlockID, userID)
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
// fetch the subscriptions and ensure the list is correct
|
||||
subsFound, resp := th.Client.GetSubscriptions(userID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.Len(t, subsFound, 2)
|
||||
|
||||
assert.Contains(t, subsFound, subs[0])
|
||||
assert.Contains(t, subsFound, subs[2])
|
||||
assert.NotContains(t, subsFound, subs[1])
|
||||
})
|
||||
|
||||
t.Run("Delete invalid subscription", func(t *testing.T) {
|
||||
user, resp := th.Client.GetMe()
|
||||
require.NoError(t, resp.Error)
|
||||
|
||||
resp = th.Client.DeleteSubscription("bogus", user.ID)
|
||||
require.Error(t, resp.Error)
|
||||
})
|
||||
}
|
||||
113
server/boards/integrationtests/teststore.go
Обычный файл
113
server/boards/integrationtests/teststore.go
Обычный файл
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/services/store"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type TestStore struct {
|
||||
store.Store
|
||||
license *mm_model.License
|
||||
}
|
||||
|
||||
func NewTestEnterpriseStore(store store.Store) *TestStore {
|
||||
usersValue := 10000
|
||||
trueValue := true
|
||||
falseValue := false
|
||||
license := &mm_model.License{
|
||||
Features: &mm_model.Features{
|
||||
Users: &usersValue,
|
||||
LDAP: &trueValue,
|
||||
LDAPGroups: &trueValue,
|
||||
MFA: &trueValue,
|
||||
GoogleOAuth: &trueValue,
|
||||
Office365OAuth: &trueValue,
|
||||
OpenId: &trueValue,
|
||||
Compliance: &trueValue,
|
||||
Cluster: &trueValue,
|
||||
Metrics: &trueValue,
|
||||
MHPNS: &trueValue,
|
||||
SAML: &trueValue,
|
||||
Elasticsearch: &trueValue,
|
||||
Announcement: &trueValue,
|
||||
ThemeManagement: &trueValue,
|
||||
EmailNotificationContents: &trueValue,
|
||||
DataRetention: &trueValue,
|
||||
MessageExport: &trueValue,
|
||||
CustomPermissionsSchemes: &trueValue,
|
||||
CustomTermsOfService: &trueValue,
|
||||
GuestAccounts: &trueValue,
|
||||
GuestAccountsPermissions: &trueValue,
|
||||
IDLoadedPushNotifications: &trueValue,
|
||||
LockTeammateNameDisplay: &trueValue,
|
||||
EnterprisePlugins: &trueValue,
|
||||
AdvancedLogging: &trueValue,
|
||||
Cloud: &falseValue,
|
||||
SharedChannels: &trueValue,
|
||||
RemoteClusterService: &trueValue,
|
||||
FutureFeatures: &trueValue,
|
||||
},
|
||||
}
|
||||
|
||||
testStore := &TestStore{
|
||||
Store: store,
|
||||
license: license,
|
||||
}
|
||||
|
||||
return testStore
|
||||
}
|
||||
|
||||
func NewTestProfessionalStore(store store.Store) *TestStore {
|
||||
usersValue := 10000
|
||||
trueValue := true
|
||||
falseValue := false
|
||||
license := &mm_model.License{
|
||||
Features: &mm_model.Features{
|
||||
Users: &usersValue,
|
||||
LDAP: &falseValue,
|
||||
LDAPGroups: &falseValue,
|
||||
MFA: &trueValue,
|
||||
GoogleOAuth: &trueValue,
|
||||
Office365OAuth: &trueValue,
|
||||
OpenId: &trueValue,
|
||||
Compliance: &falseValue,
|
||||
Cluster: &falseValue,
|
||||
Metrics: &trueValue,
|
||||
MHPNS: &trueValue,
|
||||
SAML: &trueValue,
|
||||
Elasticsearch: &trueValue,
|
||||
Announcement: &trueValue,
|
||||
ThemeManagement: &trueValue,
|
||||
EmailNotificationContents: &trueValue,
|
||||
DataRetention: &trueValue,
|
||||
MessageExport: &trueValue,
|
||||
CustomPermissionsSchemes: &trueValue,
|
||||
CustomTermsOfService: &trueValue,
|
||||
GuestAccounts: &trueValue,
|
||||
GuestAccountsPermissions: &trueValue,
|
||||
IDLoadedPushNotifications: &trueValue,
|
||||
LockTeammateNameDisplay: &trueValue,
|
||||
EnterprisePlugins: &falseValue,
|
||||
AdvancedLogging: &trueValue,
|
||||
Cloud: &falseValue,
|
||||
SharedChannels: &trueValue,
|
||||
RemoteClusterService: &falseValue,
|
||||
FutureFeatures: &trueValue,
|
||||
},
|
||||
}
|
||||
|
||||
testStore := &TestStore{
|
||||
Store: store,
|
||||
license: license,
|
||||
}
|
||||
|
||||
return testStore
|
||||
}
|
||||
|
||||
func (s *TestStore) GetLicense() *mm_model.License {
|
||||
return s.license
|
||||
}
|
||||
271
server/boards/integrationtests/user_test.go
Обычный файл
271
server/boards/integrationtests/user_test.go
Обычный файл
@@ -0,0 +1,271 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/model"
|
||||
"github.com/mattermost/mattermost-server/v6/server/boards/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
fakeUsername = "fakeUsername"
|
||||
fakeEmail = "mock@test.com"
|
||||
)
|
||||
|
||||
func TestUserRegister(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
// register
|
||||
registerRequest := &model.RegisterRequest{
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: utils.NewID(utils.IDTypeNone),
|
||||
}
|
||||
success, resp := th.Client.Register(registerRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.True(t, success)
|
||||
|
||||
// register again will fail
|
||||
success, resp = th.Client.Register(registerRequest)
|
||||
require.Error(t, resp.Error)
|
||||
require.False(t, success)
|
||||
}
|
||||
|
||||
func TestUserLogin(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("with nonexist user", func(t *testing.T) {
|
||||
loginRequest := &model.LoginRequest{
|
||||
Type: "normal",
|
||||
Username: "nonexistuser",
|
||||
Email: "",
|
||||
Password: utils.NewID(utils.IDTypeNone),
|
||||
}
|
||||
data, resp := th.Client.Login(loginRequest)
|
||||
require.Error(t, resp.Error)
|
||||
require.Nil(t, data)
|
||||
})
|
||||
|
||||
t.Run("with registered user", func(t *testing.T) {
|
||||
password := utils.NewID(utils.IDTypeNone)
|
||||
// register
|
||||
registerRequest := &model.RegisterRequest{
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
success, resp := th.Client.Register(registerRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.True(t, success)
|
||||
|
||||
// login
|
||||
loginRequest := &model.LoginRequest{
|
||||
Type: "normal",
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
data, resp := th.Client.Login(loginRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, data)
|
||||
require.NotNil(t, data.Token)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetMe(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("not login yet", func(t *testing.T) {
|
||||
me, resp := th.Client.GetMe()
|
||||
require.Error(t, resp.Error)
|
||||
require.Nil(t, me)
|
||||
})
|
||||
|
||||
t.Run("logged in", func(t *testing.T) {
|
||||
// register
|
||||
password := utils.NewID(utils.IDTypeNone)
|
||||
registerRequest := &model.RegisterRequest{
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
success, resp := th.Client.Register(registerRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.True(t, success)
|
||||
// login
|
||||
loginRequest := &model.LoginRequest{
|
||||
Type: "normal",
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
data, resp := th.Client.Login(loginRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, data)
|
||||
require.NotNil(t, data.Token)
|
||||
|
||||
// get user me
|
||||
me, resp := th.Client.GetMe()
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, me)
|
||||
require.Equal(t, "", me.Email)
|
||||
require.Equal(t, registerRequest.Username, me.Username)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetUser(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
// register
|
||||
password := utils.NewID(utils.IDTypeNone)
|
||||
registerRequest := &model.RegisterRequest{
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
success, resp := th.Client.Register(registerRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.True(t, success)
|
||||
// login
|
||||
loginRequest := &model.LoginRequest{
|
||||
Type: "normal",
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
data, resp := th.Client.Login(loginRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, data)
|
||||
require.NotNil(t, data.Token)
|
||||
|
||||
me, resp := th.Client.GetMe()
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, me)
|
||||
|
||||
t.Run("me's id", func(t *testing.T) {
|
||||
user, resp := th.Client.GetUser(me.ID)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, user)
|
||||
require.Equal(t, me.ID, user.ID)
|
||||
require.Equal(t, me.Username, user.Username)
|
||||
})
|
||||
|
||||
t.Run("nonexist user", func(t *testing.T) {
|
||||
user, resp := th.Client.GetUser("nonexistid")
|
||||
require.Error(t, resp.Error)
|
||||
require.Nil(t, user)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserChangePassword(t *testing.T) {
|
||||
th := SetupTestHelper(t).Start()
|
||||
defer th.TearDown()
|
||||
|
||||
// register
|
||||
password := utils.NewID(utils.IDTypeNone)
|
||||
registerRequest := &model.RegisterRequest{
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
success, resp := th.Client.Register(registerRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.True(t, success)
|
||||
// login
|
||||
loginRequest := &model.LoginRequest{
|
||||
Type: "normal",
|
||||
Username: fakeUsername,
|
||||
Email: fakeEmail,
|
||||
Password: password,
|
||||
}
|
||||
data, resp := th.Client.Login(loginRequest)
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, data)
|
||||
require.NotNil(t, data.Token)
|
||||
|
||||
originalMe, resp := th.Client.GetMe()
|
||||
require.NoError(t, resp.Error)
|
||||
require.NotNil(t, originalMe)
|
||||
|
||||
// change password
|
||||
success, resp = th.Client.UserChangePassword(originalMe.ID, &model.ChangePasswordRequest{
|
||||
OldPassword: password,
|
||||
NewPassword: utils.NewID(utils.IDTypeNone),
|
||||
})
|
||||
require.NoError(t, resp.Error)
|
||||
require.True(t, success)
|
||||
}
|
||||
|
||||
func randomBytes(t *testing.T, n int) []byte {
|
||||
bb := make([]byte, n)
|
||||
_, err := rand.Read(bb)
|
||||
require.NoError(t, err)
|
||||
return bb
|
||||
}
|
||||
|
||||
func TestTeamUploadFile(t *testing.T) {
|
||||
t.Run("no permission", func(t *testing.T) { // native auth, but not login
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
teamID := "0"
|
||||
boardID := utils.NewID(utils.IDTypeBoard)
|
||||
data := randomBytes(t, 1024)
|
||||
result, resp := th.Client.TeamUploadFile(teamID, boardID, bytes.NewReader(data))
|
||||
require.Error(t, resp.Error)
|
||||
require.Nil(t, result)
|
||||
})
|
||||
|
||||
t.Run("a board admin should be able to update a file", func(t *testing.T) { // single token auth
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
teamID := "0"
|
||||
newBoard := &model.Board{
|
||||
Type: model.BoardTypeOpen,
|
||||
TeamID: teamID,
|
||||
}
|
||||
board, resp := th.Client.CreateBoard(newBoard)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, board)
|
||||
|
||||
data := randomBytes(t, 1024)
|
||||
result, resp := th.Client.TeamUploadFile(teamID, board.ID, bytes.NewReader(data))
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, result)
|
||||
require.NotEmpty(t, result.FileID)
|
||||
// TODO get the uploaded file
|
||||
})
|
||||
|
||||
t.Run("user that doesn't belong to the board should not be able to upload a file", func(t *testing.T) {
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
teamID := "0"
|
||||
newBoard := &model.Board{
|
||||
Type: model.BoardTypeOpen,
|
||||
TeamID: teamID,
|
||||
}
|
||||
board, resp := th.Client.CreateBoard(newBoard)
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, board)
|
||||
|
||||
data := randomBytes(t, 1024)
|
||||
|
||||
// a user that doesn't belong to the board tries to upload the file
|
||||
result, resp := th.Client2.TeamUploadFile(teamID, board.ID, bytes.NewReader(data))
|
||||
th.CheckForbidden(resp)
|
||||
require.Nil(t, result)
|
||||
})
|
||||
}
|
||||
60
server/boards/integrationtests/work_template_test.go
Обычный файл
60
server/boards/integrationtests/work_template_test.go
Обычный файл
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package integrationtests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// This test is there to guarantee that the board templates needed for
|
||||
// the work template are present in the default templates.
|
||||
// If this fails, you might need to sync with the channels team.
|
||||
func TestGetTemplatesForWorkTemplate(t *testing.T) {
|
||||
// map[name]trackingTemplateId
|
||||
knownInWorkTemplates := map[string]string{
|
||||
"Company Goals & OKRs": "7ba22ccfdfac391d63dea5c4b8cde0de",
|
||||
"Competitive Analysis": "06f4bff367a7c2126fab2380c9dec23c",
|
||||
"Content Calendar": "c75fbd659d2258b5183af2236d176ab4",
|
||||
"Meeting Agenda ": "54fcf9c610f0ac5e4c522c0657c90602",
|
||||
"Personal Goals ": "7f32dc8d2ae008cfe56554e9363505cc",
|
||||
"Personal Tasls ": "dfb70c146a4584b8a21837477c7b5431",
|
||||
"Project Tasks ": "a4ec399ab4f2088b1051c3cdf1dde4c3",
|
||||
"Roadmap ": "b728c6ca730e2cfc229741c5a4712b65",
|
||||
"Sales Pipeline CRM": "ecc250bb7dff0fe02247f1110f097544",
|
||||
"Sprint Planner ": "99b74e26d2f5d0a9b346d43c0a7bfb09",
|
||||
"Team Retrospective": "e4f03181c4ced8edd4d53d33d569a086",
|
||||
"User Research Sessions": "6c345c7f50f6833f78b7d0f08ce450a3",
|
||||
}
|
||||
th := SetupTestHelper(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
err := th.Server.App().InitTemplates()
|
||||
require.NoError(t, err, "InitTemplates should not fail")
|
||||
|
||||
rBoards, resp := th.Client.GetTemplatesForTeam("0")
|
||||
th.CheckOK(resp)
|
||||
require.NotNil(t, rBoards)
|
||||
|
||||
trackingTemplateIDs := []string{}
|
||||
for _, board := range rBoards {
|
||||
property, _ := board.GetPropertyString("trackingTemplateId")
|
||||
if property != "" {
|
||||
trackingTemplateIDs = append(trackingTemplateIDs, property)
|
||||
}
|
||||
}
|
||||
|
||||
// make sure all known templates are in trackingTemplateIds
|
||||
for name, ttID := range knownInWorkTemplates {
|
||||
found := false
|
||||
for _, trackingTemplateID := range trackingTemplateIDs {
|
||||
if trackingTemplateID == ttID {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
require.True(t, found, "trackingTemplateId %s for %s not found", ttID, name)
|
||||
}
|
||||
}
|
||||
Ссылка в новой задаче
Block a user