focalboard/server/services/store/storetests/blocks.go

659 lines
16 KiB
Go
Raw Normal View History

package storetests
import (
"testing"
2021-01-29 19:32:33 +01:00
"time"
2021-01-26 23:13:46 +01:00
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/services/store"
"github.com/stretchr/testify/require"
)
func StoreTestBlocksStore(t *testing.T, setup func(t *testing.T) (store.Store, func())) {
2021-03-26 19:01:54 +01:00
container := store.Container{
2021-03-30 23:04:00 +02:00
WorkspaceID: "0",
2021-03-26 19:01:54 +01:00
}
t.Run("InsertBlock", func(t *testing.T) {
store, tearDown := setup(t)
2021-01-29 19:32:33 +01:00
defer tearDown()
2021-03-26 19:01:54 +01:00
testInsertBlock(t, store, container)
2021-01-29 19:32:33 +01:00
})
t.Run("DeleteBlock", func(t *testing.T) {
store, tearDown := setup(t)
defer tearDown()
2021-03-26 19:01:54 +01:00
testDeleteBlock(t, store, container)
})
t.Run("GetSubTree2", func(t *testing.T) {
store, tearDown := setup(t)
2021-01-29 19:32:33 +01:00
defer tearDown()
2021-03-26 19:01:54 +01:00
testGetSubTree2(t, store, container)
})
t.Run("GetSubTree3", func(t *testing.T) {
store, tearDown := setup(t)
2021-01-29 19:32:33 +01:00
defer tearDown()
2021-03-26 19:01:54 +01:00
testGetSubTree3(t, store, container)
2021-01-29 19:32:33 +01:00
})
t.Run("GetParentID", func(t *testing.T) {
store, tearDown := setup(t)
defer tearDown()
2021-03-26 19:01:54 +01:00
testGetParentID(t, store, container)
})
2021-01-29 19:21:55 +01:00
t.Run("GetRootID", func(t *testing.T) {
store, tearDown := setup(t)
2021-01-29 19:32:33 +01:00
defer tearDown()
2021-03-26 19:01:54 +01:00
testGetRootID(t, store, container)
2021-01-29 19:21:55 +01:00
})
t.Run("GetBlocksWithParentAndType", func(t *testing.T) {
store, tearDown := setup(t)
defer tearDown()
testGetBlocksWithParentAndType(t, store, container)
})
t.Run("GetBlocksWithParent", func(t *testing.T) {
store, tearDown := setup(t)
defer tearDown()
testGetBlocksWithParent(t, store, container)
})
t.Run("GetBlocksWithType", func(t *testing.T) {
store, tearDown := setup(t)
defer tearDown()
testGetBlocksWithType(t, store, container)
})
}
2021-03-26 19:01:54 +01:00
func testInsertBlock(t *testing.T, store store.Store, container store.Container) {
2021-01-12 20:16:25 +01:00
userID := "user-id"
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
require.NoError(t, err)
2021-01-06 04:47:18 +01:00
initialCount := len(blocks)
2021-01-29 19:21:55 +01:00
t.Run("valid block", func(t *testing.T) {
block := model.Block{
ID: "id-test",
RootID: "id-test",
ModifiedBy: userID,
}
2021-03-26 19:01:54 +01:00
err := store.InsertBlock(container, block)
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+1)
})
2021-01-29 19:21:55 +01:00
t.Run("invalid rootid", func(t *testing.T) {
block := model.Block{
ID: "id-test",
RootID: "",
ModifiedBy: userID,
}
2021-03-26 19:01:54 +01:00
err := store.InsertBlock(container, block)
2021-01-29 19:21:55 +01:00
require.Error(t, err)
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+1)
})
t.Run("invalid fields data", func(t *testing.T) {
block := model.Block{
ID: "id-test",
RootID: "id-test",
ModifiedBy: userID,
Fields: map[string]interface{}{"no-serialiable-value": t.Run},
}
2021-03-26 19:01:54 +01:00
err := store.InsertBlock(container, block)
2021-01-29 19:21:55 +01:00
require.Error(t, err)
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+1)
})
}
2020-11-12 19:48:08 +01:00
2021-03-26 19:01:54 +01:00
func testGetSubTree2(t *testing.T, store store.Store, container store.Container) {
2021-01-12 20:16:25 +01:00
userID := "user-id"
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2020-11-12 19:48:08 +01:00
require.NoError(t, err)
2021-01-06 04:47:18 +01:00
initialCount := len(blocks)
2020-11-12 19:48:08 +01:00
blocksToInsert := []model.Block{
{
2021-01-12 20:16:25 +01:00
ID: "parent",
RootID: "parent",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "child1",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "child2",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "grandchild1",
RootID: "parent",
ParentID: "child1",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "grandchild2",
RootID: "parent",
ParentID: "child2",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "greatgrandchild1",
RootID: "parent",
ParentID: "grandchild1",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
}
2021-03-26 19:01:54 +01:00
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
2020-11-12 19:48:08 +01:00
2021-03-26 19:01:54 +01:00
blocks, err = store.GetAllBlocks(container)
2021-01-06 04:47:18 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+6)
2021-01-29 19:21:55 +01:00
t.Run("from root id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
blocks, err = store.GetSubTree2(container, "parent")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, 3)
require.True(t, ContainsBlockWithID(blocks, "parent"))
require.True(t, ContainsBlockWithID(blocks, "child1"))
require.True(t, ContainsBlockWithID(blocks, "child2"))
})
2020-11-12 19:48:08 +01:00
2021-01-29 19:21:55 +01:00
t.Run("from child id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
blocks, err = store.GetSubTree2(container, "child1")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, 2)
require.True(t, ContainsBlockWithID(blocks, "child1"))
require.True(t, ContainsBlockWithID(blocks, "grandchild1"))
})
2020-11-12 19:48:08 +01:00
2021-01-29 19:21:55 +01:00
t.Run("from not existing id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
blocks, err = store.GetSubTree2(container, "not-exists")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, 0)
})
2020-11-12 19:48:08 +01:00
}
2021-03-26 19:01:54 +01:00
func testGetSubTree3(t *testing.T, store store.Store, container store.Container) {
2021-01-12 20:16:25 +01:00
userID := "user-id"
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2020-11-12 19:48:08 +01:00
require.NoError(t, err)
2021-01-06 04:47:18 +01:00
initialCount := len(blocks)
2020-11-12 19:48:08 +01:00
blocksToInsert := []model.Block{
{
2021-01-12 20:16:25 +01:00
ID: "parent",
RootID: "parent",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "child1",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "child2",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "grandchild1",
RootID: "parent",
ParentID: "child1",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "grandchild2",
RootID: "parent",
ParentID: "child2",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
{
2021-01-12 20:16:25 +01:00
ID: "greatgrandchild1",
RootID: "parent",
ParentID: "grandchild1",
ModifiedBy: userID,
2020-11-12 19:48:08 +01:00
},
}
2021-03-26 19:01:54 +01:00
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
2020-11-12 19:48:08 +01:00
2021-03-26 19:01:54 +01:00
blocks, err = store.GetAllBlocks(container)
2021-01-06 04:47:18 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+6)
2021-01-29 19:21:55 +01:00
t.Run("from root id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
blocks, err = store.GetSubTree3(container, "parent")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, 5)
require.True(t, ContainsBlockWithID(blocks, "parent"))
require.True(t, ContainsBlockWithID(blocks, "child1"))
require.True(t, ContainsBlockWithID(blocks, "child2"))
require.True(t, ContainsBlockWithID(blocks, "grandchild1"))
require.True(t, ContainsBlockWithID(blocks, "grandchild2"))
})
t.Run("from child id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
blocks, err = store.GetSubTree3(container, "child1")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, 3)
require.True(t, ContainsBlockWithID(blocks, "child1"))
require.True(t, ContainsBlockWithID(blocks, "grandchild1"))
require.True(t, ContainsBlockWithID(blocks, "greatgrandchild1"))
})
t.Run("from not existing id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
blocks, err = store.GetSubTree3(container, "not-exists")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Len(t, blocks, 0)
})
}
2021-03-26 19:01:54 +01:00
func testGetRootID(t *testing.T, store store.Store, container store.Container) {
2021-01-29 19:21:55 +01:00
userID := "user-id"
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2020-11-12 19:48:08 +01:00
require.NoError(t, err)
2021-01-29 19:21:55 +01:00
initialCount := len(blocks)
blocksToInsert := []model.Block{
{
ID: "parent",
RootID: "parent",
ModifiedBy: userID,
},
{
ID: "child1",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
},
{
ID: "child2",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
},
{
ID: "grandchild1",
RootID: "parent",
ParentID: "child1",
ModifiedBy: userID,
},
{
ID: "grandchild2",
RootID: "parent",
ParentID: "child2",
ModifiedBy: userID,
},
{
ID: "greatgrandchild1",
RootID: "parent",
ParentID: "grandchild1",
ModifiedBy: userID,
},
}
2020-11-12 19:48:08 +01:00
2021-03-26 19:01:54 +01:00
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
2020-11-12 19:48:08 +01:00
2021-03-26 19:01:54 +01:00
blocks, err = store.GetAllBlocks(container)
2020-11-12 19:48:08 +01:00
require.NoError(t, err)
2021-01-29 19:21:55 +01:00
require.Len(t, blocks, initialCount+6)
t.Run("from root id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
rootID, err := store.GetRootID(container, "parent")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Equal(t, "parent", rootID)
})
t.Run("from child id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
rootID, err := store.GetRootID(container, "child1")
2021-01-29 19:21:55 +01:00
require.NoError(t, err)
require.Equal(t, "parent", rootID)
})
t.Run("from not existing id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
_, err := store.GetRootID(container, "not-exists")
2021-01-29 19:21:55 +01:00
require.Error(t, err)
})
2020-11-12 19:48:08 +01:00
}
2021-01-29 19:32:33 +01:00
2021-03-26 19:01:54 +01:00
func testGetParentID(t *testing.T, store store.Store, container store.Container) {
2021-01-29 19:32:33 +01:00
userID := "user-id"
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
initialCount := len(blocks)
blocksToInsert := []model.Block{
{
ID: "parent",
RootID: "parent",
ModifiedBy: userID,
},
{
ID: "child1",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
},
{
ID: "child2",
RootID: "parent",
ParentID: "parent",
ModifiedBy: userID,
},
{
ID: "grandchild1",
RootID: "parent",
ParentID: "child1",
ModifiedBy: userID,
},
{
ID: "grandchild2",
RootID: "parent",
ParentID: "child2",
ModifiedBy: userID,
},
{
ID: "greatgrandchild1",
RootID: "parent",
ParentID: "grandchild1",
ModifiedBy: userID,
},
}
2021-03-26 19:01:54 +01:00
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
2021-01-29 19:32:33 +01:00
2021-03-26 19:01:54 +01:00
blocks, err = store.GetAllBlocks(container)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+6)
t.Run("from root id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
parentID, err := store.GetParentID(container, "parent")
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
require.Equal(t, "", parentID)
})
t.Run("from child id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
parentID, err := store.GetParentID(container, "grandchild1")
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
require.Equal(t, "child1", parentID)
})
t.Run("from not existing id", func(t *testing.T) {
2021-03-26 19:01:54 +01:00
_, err := store.GetParentID(container, "not-exists")
2021-01-29 19:32:33 +01:00
require.Error(t, err)
})
}
2021-03-26 19:01:54 +01:00
func testDeleteBlock(t *testing.T, store store.Store, container store.Container) {
2021-01-29 19:32:33 +01:00
userID := "user-id"
2021-03-26 19:01:54 +01:00
blocks, err := store.GetAllBlocks(container)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
initialCount := len(blocks)
blocksToInsert := []model.Block{
{
ID: "block1",
RootID: "block1",
ModifiedBy: userID,
},
{
ID: "block2",
RootID: "block2",
ModifiedBy: userID,
},
{
ID: "block3",
RootID: "block3",
ModifiedBy: userID,
},
}
2021-03-26 19:01:54 +01:00
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
2021-01-29 19:32:33 +01:00
2021-03-26 19:01:54 +01:00
blocks, err = store.GetAllBlocks(container)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
require.Len(t, blocks, initialCount+3)
t.Run("exiting id", func(t *testing.T) {
// Wait for not colliding the ID+insert_at key
time.Sleep(1 * time.Millisecond)
2021-03-26 19:01:54 +01:00
err := store.DeleteBlock(container, "block1", userID)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
})
t.Run("exiting id multiple times", func(t *testing.T) {
// Wait for not colliding the ID+insert_at key
time.Sleep(1 * time.Millisecond)
2021-03-26 19:01:54 +01:00
err := store.DeleteBlock(container, "block1", userID)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
// Wait for not colliding the ID+insert_at key
time.Sleep(1 * time.Millisecond)
2021-03-26 19:01:54 +01:00
err = store.DeleteBlock(container, "block1", userID)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
})
t.Run("from not existing id", func(t *testing.T) {
// Wait for not colliding the ID+insert_at key
time.Sleep(1 * time.Millisecond)
2021-03-26 19:01:54 +01:00
err := store.DeleteBlock(container, "not-exists", userID)
2021-01-29 19:32:33 +01:00
require.NoError(t, err)
})
}
func testGetBlocksWithParentAndType(t *testing.T, store store.Store, container store.Container) {
userID := "user-id"
blocks, err := store.GetAllBlocks(container)
require.NoError(t, err)
blocksToInsert := []model.Block{
{
ID: "block1",
ParentID: "",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block2",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block3",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block4",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test2",
},
{
ID: "block5",
ParentID: "block2",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
}
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
t.Run("not existing parent", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithParentAndType(container, "not-exists", "test")
require.NoError(t, err)
require.Len(t, blocks, 0)
})
t.Run("not existing type", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithParentAndType(container, "block1", "not-existing")
require.NoError(t, err)
require.Len(t, blocks, 0)
})
t.Run("valid parent and type", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithParentAndType(container, "block1", "test")
require.NoError(t, err)
require.Len(t, blocks, 2)
})
}
func testGetBlocksWithParent(t *testing.T, store store.Store, container store.Container) {
userID := "user-id"
blocks, err := store.GetAllBlocks(container)
require.NoError(t, err)
blocksToInsert := []model.Block{
{
ID: "block1",
ParentID: "",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block2",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block3",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block4",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test2",
},
{
ID: "block5",
ParentID: "block2",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
}
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
t.Run("not existing parent", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithParent(container, "not-exists")
require.NoError(t, err)
require.Len(t, blocks, 0)
})
t.Run("valid parent", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithParent(container, "block1")
require.NoError(t, err)
require.Len(t, blocks, 3)
})
}
func testGetBlocksWithType(t *testing.T, store store.Store, container store.Container) {
userID := "user-id"
blocks, err := store.GetAllBlocks(container)
require.NoError(t, err)
blocksToInsert := []model.Block{
{
ID: "block1",
ParentID: "",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block2",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block3",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
{
ID: "block4",
ParentID: "block1",
RootID: "block1",
ModifiedBy: userID,
Type: "test2",
},
{
ID: "block5",
ParentID: "block2",
RootID: "block1",
ModifiedBy: userID,
Type: "test",
},
}
InsertBlocks(t, store, container, blocksToInsert)
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
t.Run("not existing type", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithType(container, "not-exists")
require.NoError(t, err)
require.Len(t, blocks, 0)
})
t.Run("valid type", func(t *testing.T) {
time.Sleep(1 * time.Millisecond)
blocks, err = store.GetBlocksWithType(container, "test")
require.NoError(t, err)
require.Len(t, blocks, 4)
})
}