You've already forked focalboard
							
							
				mirror of
				https://github.com/mattermost/focalboard.git
				synced 2025-10-31 00:17:42 +02:00 
			
		
		
		
	* WIP * WIP * Removed unused webapp util * Added server tests * Lint fix * Updating existing tests * Updating existing tests * Updating existing tests * Fixing existing tests * Fixing existing tests * Fixing existing tests * Added category type and tests * updated tests * Fixed integration test * type fix * removed seconds from boards name * wip * debugging cy test * Fixed a bug preventing users from collapsing boards category * Debugging cypress test * CI * debugging cy test * Testing a fix * reverting test fix * Handled personal server * Fixed a case for personal server * fixed a test
		
			
				
	
	
		
			823 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			823 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package integrationtests
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/mattermost/focalboard/server/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)
 | |
| 	})
 | |
| }
 |