2021-01-29 17:50:20 +01:00
|
|
|
package storetests
|
2020-10-18 01:09:12 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2021-01-29 19:32:33 +01:00
|
|
|
"time"
|
2020-10-18 01:09:12 +02:00
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
2021-01-26 23:13:46 +01:00
|
|
|
"github.com/mattermost/focalboard/server/model"
|
2021-01-29 17:50:20 +01:00
|
|
|
"github.com/mattermost/focalboard/server/services/store"
|
2021-10-07 13:51:01 +02:00
|
|
|
"github.com/mattermost/focalboard/server/utils"
|
2020-10-18 01:09:12 +02:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
const (
|
|
|
|
testUserID = "user-id"
|
|
|
|
)
|
|
|
|
|
2021-01-29 17:50:20 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-01-29 17:50:20 +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
|
|
|
})
|
2021-12-10 15:17:00 +01:00
|
|
|
t.Run("InsertBlocks", func(t *testing.T) {
|
|
|
|
store, tearDown := setup(t)
|
|
|
|
defer tearDown()
|
|
|
|
testInsertBlocks(t, store, container)
|
|
|
|
})
|
2021-08-06 14:10:24 +02:00
|
|
|
t.Run("PatchBlock", func(t *testing.T) {
|
|
|
|
store, tearDown := setup(t)
|
|
|
|
defer tearDown()
|
|
|
|
testPatchBlock(t, store, container)
|
|
|
|
})
|
2021-12-10 15:17:00 +01:00
|
|
|
t.Run("PatchBlocks", func(t *testing.T) {
|
|
|
|
store, tearDown := setup(t)
|
|
|
|
defer tearDown()
|
|
|
|
testPatchBlocks(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)
|
2021-01-29 17:50:20 +01:00
|
|
|
})
|
2022-02-22 18:42:49 +01:00
|
|
|
t.Run("UndeleteBlock", func(t *testing.T) {
|
|
|
|
store, tearDown := setup(t)
|
|
|
|
defer tearDown()
|
|
|
|
testUndeleteBlock(t, store, container)
|
|
|
|
})
|
2021-01-29 17:50:20 +01:00
|
|
|
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)
|
2021-01-29 17:50:20 +01:00
|
|
|
})
|
|
|
|
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-07-09 03:09:02 +02:00
|
|
|
testGetParents(t, store, container)
|
2021-04-30 16:31:04 +02:00
|
|
|
})
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("GetBlocks", func(t *testing.T) {
|
2021-04-30 16:31:04 +02:00
|
|
|
store, tearDown := setup(t)
|
|
|
|
defer tearDown()
|
2021-07-09 03:09:02 +02:00
|
|
|
testGetBlocks(t, store, container)
|
2021-07-08 16:36:43 +02:00
|
|
|
})
|
2021-07-09 06:36:50 +02:00
|
|
|
t.Run("GetBlock", func(t *testing.T) {
|
|
|
|
store, tearDown := setup(t)
|
|
|
|
defer tearDown()
|
|
|
|
testGetBlock(t, store, container)
|
|
|
|
})
|
2021-01-29 17:50:20 +01:00
|
|
|
}
|
|
|
|
|
2021-03-26 19:01:54 +01:00
|
|
|
func testInsertBlock(t *testing.T, store store.Store, container store.Container) {
|
2021-07-09 03:09:02 +02:00
|
|
|
userID := testUserID
|
2021-01-12 20:16:25 +01:00
|
|
|
|
2021-07-09 12:59:44 +02:00
|
|
|
blocks, errBlocks := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, errBlocks)
|
2021-01-06 04:47:18 +01:00
|
|
|
initialCount := len(blocks)
|
2020-10-18 01:09:12 +02:00
|
|
|
|
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,
|
|
|
|
}
|
2020-10-18 01:09:12 +02:00
|
|
|
|
2021-07-08 16:36:43 +02:00
|
|
|
err := store.InsertBlock(container, &block, "user-id-1")
|
2021-01-29 19:21:55 +01:00
|
|
|
require.NoError(t, err)
|
2020-10-18 01:09:12 +02:00
|
|
|
|
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-10-18 01:09:12 +02:00
|
|
|
|
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,
|
|
|
|
}
|
2020-10-18 01:09:12 +02:00
|
|
|
|
2021-07-08 16:36:43 +02:00
|
|
|
err := store.InsertBlock(container, &block, "user-id-1")
|
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-07-08 16:36:43 +02:00
|
|
|
err := store.InsertBlock(container, &block, "user-id-1")
|
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)
|
|
|
|
})
|
2021-07-08 16:36:43 +02:00
|
|
|
|
|
|
|
t.Run("insert new block", func(t *testing.T) {
|
|
|
|
block := model.Block{
|
|
|
|
RootID: "root-id",
|
|
|
|
}
|
|
|
|
|
|
|
|
err := store.InsertBlock(container, &block, "user-id-2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "user-id-2", block.CreatedBy)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("update existing block", func(t *testing.T) {
|
|
|
|
block := model.Block{
|
|
|
|
ID: "id-2",
|
|
|
|
RootID: "root-id",
|
|
|
|
Title: "Old Title",
|
|
|
|
}
|
|
|
|
|
|
|
|
// inserting
|
|
|
|
err := store.InsertBlock(container, &block, "user-id-2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// created by populated from user id for new blocks
|
|
|
|
require.Equal(t, "user-id-2", block.CreatedBy)
|
|
|
|
|
|
|
|
// hack to avoid multiple, quick updates to a card
|
|
|
|
// violating block_history composite primary key constraint
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
// updating
|
|
|
|
newBlock := model.Block{
|
|
|
|
ID: "id-2",
|
|
|
|
RootID: "root-id",
|
|
|
|
CreatedBy: "user-id-3",
|
|
|
|
Title: "New Title",
|
|
|
|
}
|
|
|
|
err = store.InsertBlock(container, &newBlock, "user-id-4")
|
|
|
|
require.NoError(t, err)
|
|
|
|
// created by is not altered for existing blocks
|
|
|
|
require.Equal(t, "user-id-3", newBlock.CreatedBy)
|
|
|
|
require.Equal(t, "New Title", newBlock.Title)
|
|
|
|
})
|
|
|
|
|
|
|
|
createdAt, err := time.Parse(time.RFC822, "01 Jan 90 01:00 IST")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
updateAt, err := time.Parse(time.RFC822, "02 Jan 90 01:00 IST")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
t.Run("data tamper attempt", func(t *testing.T) {
|
|
|
|
block := model.Block{
|
2021-07-09 03:09:02 +02:00
|
|
|
ID: "id-10",
|
|
|
|
RootID: "root-id",
|
|
|
|
Title: "Old Title",
|
2021-10-07 13:51:01 +02:00
|
|
|
CreateAt: utils.GetMillisForTime(createdAt),
|
|
|
|
UpdateAt: utils.GetMillisForTime(updateAt),
|
2021-07-09 03:09:02 +02:00
|
|
|
CreatedBy: "user-id-5",
|
2021-07-08 16:36:43 +02:00
|
|
|
ModifiedBy: "user-id-6",
|
|
|
|
}
|
|
|
|
|
|
|
|
// inserting
|
|
|
|
err := store.InsertBlock(container, &block, "user-id-1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedBlock, err := store.GetBlock(container, "id-10")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NotNil(t, retrievedBlock)
|
|
|
|
assert.Equal(t, "user-id-1", retrievedBlock.CreatedBy)
|
|
|
|
assert.Equal(t, "user-id-1", retrievedBlock.ModifiedBy)
|
2021-10-07 13:51:01 +02:00
|
|
|
assert.WithinDurationf(t, time.Now(), utils.GetTimeForMillis(retrievedBlock.CreateAt), 1*time.Second, "create time should be current time")
|
|
|
|
assert.WithinDurationf(t, time.Now(), utils.GetTimeForMillis(retrievedBlock.UpdateAt), 1*time.Second, "update time should be current time")
|
2021-07-08 16:36:43 +02:00
|
|
|
})
|
2020-10-18 01:09:12 +02:00
|
|
|
}
|
2020-11-12 19:48:08 +01:00
|
|
|
|
2021-12-10 15:17:00 +01:00
|
|
|
func testInsertBlocks(t *testing.T, store store.Store, container store.Container) {
|
|
|
|
userID := testUserID
|
|
|
|
|
|
|
|
blocks, errBlocks := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, errBlocks)
|
|
|
|
initialCount := len(blocks)
|
|
|
|
|
|
|
|
t.Run("invalid block", func(t *testing.T) {
|
|
|
|
validBlock := model.Block{
|
|
|
|
ID: "id-test",
|
|
|
|
RootID: "id-test",
|
|
|
|
ModifiedBy: userID,
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidBlock := model.Block{
|
|
|
|
ID: "id-test",
|
|
|
|
RootID: "",
|
|
|
|
ModifiedBy: userID,
|
|
|
|
}
|
|
|
|
|
|
|
|
newBlocks := []model.Block{validBlock, invalidBlock}
|
|
|
|
|
2022-02-22 22:30:47 +01:00
|
|
|
time.Sleep(1 * time.Millisecond)
|
2021-12-10 15:17:00 +01:00
|
|
|
err := store.InsertBlocks(container, newBlocks, "user-id-1")
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, err)
|
|
|
|
// no blocks should have been inserted
|
|
|
|
require.Len(t, blocks, initialCount)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-08-06 14:10:24 +02:00
|
|
|
func testPatchBlock(t *testing.T, store store.Store, container store.Container) {
|
|
|
|
userID := testUserID
|
|
|
|
|
|
|
|
block := model.Block{
|
|
|
|
ID: "id-test",
|
|
|
|
RootID: "id-test",
|
|
|
|
Title: "oldTitle",
|
|
|
|
ModifiedBy: userID,
|
|
|
|
Fields: map[string]interface{}{"test": "test value", "test2": "test value 2"},
|
|
|
|
}
|
|
|
|
|
|
|
|
err := store.InsertBlock(container, &block, "user-id-1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
blocks, errBlocks := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, errBlocks)
|
|
|
|
initialCount := len(blocks)
|
|
|
|
|
|
|
|
t.Run("not existing block", func(t *testing.T) {
|
|
|
|
err := store.PatchBlock(container, "invalid-block-id", &model.BlockPatch{}, "user-id-1")
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, blocks, initialCount)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("invalid rootid", func(t *testing.T) {
|
|
|
|
wrongRootID := ""
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
RootID: &wrongRootID,
|
|
|
|
}
|
|
|
|
|
|
|
|
err := store.PatchBlock(container, "id-test", &blockPatch, "user-id-1")
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, blocks, initialCount)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("invalid fields data", func(t *testing.T) {
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
UpdatedFields: map[string]interface{}{"no-serialiable-value": t.Run},
|
|
|
|
}
|
|
|
|
|
|
|
|
err := store.PatchBlock(container, "id-test", &blockPatch, "user-id-1")
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, blocks, initialCount)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("update block fields", func(t *testing.T) {
|
|
|
|
newTitle := "New title"
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
Title: &newTitle,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
|
|
|
|
// inserting
|
|
|
|
err := store.PatchBlock(container, "id-test", &blockPatch, "user-id-2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedBlock, err := store.GetBlock(container, "id-test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// created by populated from user id for new blocks
|
|
|
|
require.Equal(t, "user-id-2", retrievedBlock.ModifiedBy)
|
|
|
|
require.Equal(t, "New title", retrievedBlock.Title)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("update block custom fields", func(t *testing.T) {
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
UpdatedFields: map[string]interface{}{"test": "new test value", "test3": "new value"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
|
|
|
|
// inserting
|
|
|
|
err := store.PatchBlock(container, "id-test", &blockPatch, "user-id-2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedBlock, err := store.GetBlock(container, "id-test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// created by populated from user id for new blocks
|
|
|
|
require.Equal(t, "user-id-2", retrievedBlock.ModifiedBy)
|
|
|
|
require.Equal(t, "new test value", retrievedBlock.Fields["test"])
|
|
|
|
require.Equal(t, "test value 2", retrievedBlock.Fields["test2"])
|
|
|
|
require.Equal(t, "new value", retrievedBlock.Fields["test3"])
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("remove block custom fields", func(t *testing.T) {
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
DeletedFields: []string{"test", "test3", "test100"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
|
|
|
|
// inserting
|
|
|
|
err := store.PatchBlock(container, "id-test", &blockPatch, "user-id-2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedBlock, err := store.GetBlock(container, "id-test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// created by populated from user id for new blocks
|
|
|
|
require.Equal(t, "user-id-2", retrievedBlock.ModifiedBy)
|
|
|
|
require.Equal(t, nil, retrievedBlock.Fields["test"])
|
|
|
|
require.Equal(t, "test value 2", retrievedBlock.Fields["test2"])
|
|
|
|
require.Equal(t, nil, retrievedBlock.Fields["test3"])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-12-10 15:17:00 +01:00
|
|
|
func testPatchBlocks(t *testing.T, store store.Store, container store.Container) {
|
|
|
|
block := model.Block{
|
|
|
|
ID: "id-test",
|
|
|
|
RootID: "id-test",
|
|
|
|
Title: "oldTitle",
|
|
|
|
}
|
|
|
|
|
|
|
|
block2 := model.Block{
|
|
|
|
ID: "id-test2",
|
|
|
|
RootID: "id-test2",
|
|
|
|
Title: "oldTitle2",
|
|
|
|
}
|
|
|
|
|
|
|
|
insertBlocks := []model.Block{block, block2}
|
|
|
|
err := store.InsertBlocks(container, insertBlocks, "user-id-1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
t.Run("successful updated existing blocks", func(t *testing.T) {
|
|
|
|
title := "updatedTitle"
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
Title: &title,
|
|
|
|
}
|
|
|
|
|
|
|
|
blockPatch2 := model.BlockPatch{
|
|
|
|
Title: &title,
|
|
|
|
}
|
|
|
|
|
|
|
|
blockIds := []string{"id-test", "id-test2"}
|
|
|
|
blockPatches := []model.BlockPatch{blockPatch, blockPatch2}
|
|
|
|
|
2022-02-22 18:42:49 +01:00
|
|
|
time.Sleep(1 * time.Millisecond)
|
2021-12-10 15:17:00 +01:00
|
|
|
err := store.PatchBlocks(container, &model.BlockPatchBatch{BlockIDs: blockIds, BlockPatches: blockPatches}, "user-id-1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedBlock, err := store.GetBlock(container, "id-test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, title, retrievedBlock.Title)
|
|
|
|
|
|
|
|
retrievedBlock2, err := store.GetBlock(container, "id-test2")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, title, retrievedBlock2.Title)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("invalid block id, nothing updated existing blocks", func(t *testing.T) {
|
2022-02-22 22:30:47 +01:00
|
|
|
if store.DBType() == "sqlite3" {
|
|
|
|
t.Skip("No transactions support int sqlite")
|
|
|
|
}
|
|
|
|
|
2021-12-10 15:17:00 +01:00
|
|
|
title := "Another Title"
|
|
|
|
blockPatch := model.BlockPatch{
|
|
|
|
Title: &title,
|
|
|
|
}
|
|
|
|
|
|
|
|
blockPatch2 := model.BlockPatch{
|
|
|
|
Title: &title,
|
|
|
|
}
|
|
|
|
|
|
|
|
blockIds := []string{"id-test", "invalid id"}
|
|
|
|
blockPatches := []model.BlockPatch{blockPatch, blockPatch2}
|
|
|
|
|
|
|
|
err := store.PatchBlocks(container, &model.BlockPatchBatch{BlockIDs: blockIds, BlockPatches: blockPatches}, "user-id-1")
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
retrievedBlock, err := store.GetBlock(container, "id-test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotEqual(t, title, retrievedBlock.Title)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
var (
|
|
|
|
subtreeSampleBlocks = []model.Block{
|
2021-01-29 17:50:20 +01:00
|
|
|
{
|
2021-01-12 20:16:25 +01:00
|
|
|
ID: "parent",
|
|
|
|
RootID: "parent",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2020-11-12 19:48:08 +01:00
|
|
|
},
|
2021-01-29 17:50:20 +01:00
|
|
|
{
|
2021-01-12 20:16:25 +01:00
|
|
|
ID: "child1",
|
|
|
|
RootID: "parent",
|
|
|
|
ParentID: "parent",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2020-11-12 19:48:08 +01:00
|
|
|
},
|
2021-01-29 17:50:20 +01:00
|
|
|
{
|
2021-01-12 20:16:25 +01:00
|
|
|
ID: "child2",
|
|
|
|
RootID: "parent",
|
|
|
|
ParentID: "parent",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2020-11-12 19:48:08 +01:00
|
|
|
},
|
2021-01-29 17:50:20 +01:00
|
|
|
{
|
2021-01-12 20:16:25 +01:00
|
|
|
ID: "grandchild1",
|
|
|
|
RootID: "parent",
|
|
|
|
ParentID: "child1",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2020-11-12 19:48:08 +01:00
|
|
|
},
|
2021-01-29 17:50:20 +01:00
|
|
|
{
|
2021-01-12 20:16:25 +01:00
|
|
|
ID: "grandchild2",
|
|
|
|
RootID: "parent",
|
|
|
|
ParentID: "child2",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2020-11-12 19:48:08 +01:00
|
|
|
},
|
2021-01-29 17:50:20 +01:00
|
|
|
{
|
2021-01-12 20:16:25 +01:00
|
|
|
ID: "greatgrandchild1",
|
|
|
|
RootID: "parent",
|
|
|
|
ParentID: "grandchild1",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2020-11-12 19:48:08 +01:00
|
|
|
},
|
|
|
|
}
|
2021-07-09 03:09:02 +02:00
|
|
|
)
|
2020-11-12 19:48:08 +01:00
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
func testGetSubTree2(t *testing.T, store store.Store, container store.Container) {
|
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, err)
|
|
|
|
initialCount := len(blocks)
|
|
|
|
|
|
|
|
InsertBlocks(t, store, container, subtreeSampleBlocks, "user-id-1")
|
|
|
|
defer DeleteBlocks(t, store, container, subtreeSampleBlocks, "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-12-10 16:46:37 +01:00
|
|
|
blocks, err = store.GetSubTree2(container, "parent", model.QuerySubtreeOptions{})
|
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-12-10 16:46:37 +01:00
|
|
|
blocks, err = store.GetSubTree2(container, "child1", model.QuerySubtreeOptions{})
|
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-12-10 16:46:37 +01:00
|
|
|
blocks, err = store.GetSubTree2(container, "not-exists", model.QuerySubtreeOptions{})
|
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) {
|
|
|
|
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
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
InsertBlocks(t, store, container, subtreeSampleBlocks, "user-id-1")
|
|
|
|
defer DeleteBlocks(t, store, container, subtreeSampleBlocks, "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-12-10 16:46:37 +01:00
|
|
|
blocks, err = store.GetSubTree3(container, "parent", model.QuerySubtreeOptions{})
|
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-12-10 16:46:37 +01:00
|
|
|
blocks, err = store.GetSubTree3(container, "child1", model.QuerySubtreeOptions{})
|
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-12-10 16:46:37 +01:00
|
|
|
blocks, err = store.GetSubTree3(container, "not-exists", model.QuerySubtreeOptions{})
|
2021-01-29 19:21:55 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, blocks, 0)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
func testGetParents(t *testing.T, store store.Store, container store.Container) {
|
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)
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
InsertBlocks(t, store, container, subtreeSampleBlocks, "user-id-1")
|
|
|
|
defer DeleteBlocks(t, store, container, subtreeSampleBlocks, "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)
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("root 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)
|
|
|
|
})
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("root 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)
|
|
|
|
})
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("root 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)
|
|
|
|
})
|
2021-01-29 19:32:33 +01:00
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("parent 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)
|
|
|
|
})
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("parent 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)
|
|
|
|
})
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
t.Run("parent 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-07-09 03:09:02 +02:00
|
|
|
userID := testUserID
|
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)
|
|
|
|
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-07-08 16:36:43 +02:00
|
|
|
InsertBlocks(t, store, container, blocksToInsert, "user-id-1")
|
2021-04-22 22:53:01 +02:00
|
|
|
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)
|
|
|
|
})
|
|
|
|
}
|
2021-04-30 16:31:04 +02:00
|
|
|
|
2022-02-22 18:42:49 +01:00
|
|
|
func testUndeleteBlock(t *testing.T, store store.Store, container store.Container) {
|
|
|
|
userID := testUserID
|
|
|
|
|
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
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,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
InsertBlocks(t, store, container, blocksToInsert, "user-id-1")
|
|
|
|
defer DeleteBlocks(t, store, container, blocksToInsert, "test")
|
|
|
|
|
|
|
|
blocks, err = store.GetAllBlocks(container)
|
|
|
|
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)
|
|
|
|
err := store.DeleteBlock(container, "block1", userID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
block, err := store.GetBlock(container, "block1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, block)
|
|
|
|
|
|
|
|
err = store.UndeleteBlock(container, "block1", userID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
block, err = store.GetBlock(container, "block1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, block)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("exiting id multiple times", func(t *testing.T) {
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
err := store.DeleteBlock(container, "block1", userID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
block, err := store.GetBlock(container, "block1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, block)
|
|
|
|
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
err = store.UndeleteBlock(container, "block1", userID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
block, err = store.GetBlock(container, "block1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, block)
|
|
|
|
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
err = store.UndeleteBlock(container, "block1", userID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
block, err = store.GetBlock(container, "block1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, block)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("from not existing id", func(t *testing.T) {
|
|
|
|
// Wait for not colliding the ID+insert_at key
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
err := store.UndeleteBlock(container, "not-exists", userID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
block, err := store.GetBlock(container, "not-exists")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, block)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-09 03:09:02 +02:00
|
|
|
func testGetBlocks(t *testing.T, store store.Store, container store.Container) {
|
2021-04-30 16:31:04 +02:00
|
|
|
blocks, err := store.GetAllBlocks(container)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
blocksToInsert := []model.Block{
|
|
|
|
{
|
|
|
|
ID: "block1",
|
|
|
|
ParentID: "",
|
|
|
|
RootID: "block1",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2021-04-30 16:31:04 +02:00
|
|
|
Type: "test",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID: "block2",
|
|
|
|
ParentID: "block1",
|
|
|
|
RootID: "block1",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2021-04-30 16:31:04 +02:00
|
|
|
Type: "test",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID: "block3",
|
|
|
|
ParentID: "block1",
|
|
|
|
RootID: "block1",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2021-04-30 16:31:04 +02:00
|
|
|
Type: "test",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID: "block4",
|
|
|
|
ParentID: "block1",
|
|
|
|
RootID: "block1",
|
2021-07-09 03:09:02 +02:00
|
|
|
ModifiedBy: testUserID,
|
2021-04-30 16:31:04 +02:00
|
|
|
Type: "test2",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ID: "block5",
|
|
|
|
ParentID: "block2",
|
2021-07-09 03:09:02 +02:00
|
|
|
RootID: "block2",
|
|
|
|
ModifiedBy: testUserID,
|
2021-04-30 16:31:04 +02:00
|
|
|
Type: "test",
|
|
|
|
},
|
|
|
|
}
|
2021-07-08 16:36:43 +02:00
|
|
|
InsertBlocks(t, store, container, blocksToInsert, "user-id-1")
|
2021-04-30 16:31:04 +02:00
|
|
|
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)
|
|
|
|
})
|
|
|
|
|
|
|
|
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)
|
|
|
|
})
|
|
|
|
|
|
|
|
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)
|
|
|
|
})
|
2021-05-13 23:04:49 +02:00
|
|
|
|
|
|
|
t.Run("not existing parent", func(t *testing.T) {
|
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
blocks, err = store.GetBlocksWithRootID(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.GetBlocksWithRootID(container, "block1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, blocks, 4)
|
|
|
|
})
|
|
|
|
}
|
2021-07-08 16:36:43 +02:00
|
|
|
|
|
|
|
func testGetBlock(t *testing.T, store store.Store, container store.Container) {
|
|
|
|
t.Run("get a block", func(t *testing.T) {
|
|
|
|
block := model.Block{
|
|
|
|
ID: "block-id-10",
|
|
|
|
RootID: "root-id-1",
|
|
|
|
ModifiedBy: "user-id-1",
|
|
|
|
}
|
|
|
|
|
|
|
|
err := store.InsertBlock(container, &block, "user-id-1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
fetchedBlock, err := store.GetBlock(container, "block-id-10")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, fetchedBlock)
|
|
|
|
require.Equal(t, "block-id-10", fetchedBlock.ID)
|
|
|
|
require.Equal(t, "root-id-1", fetchedBlock.RootID)
|
|
|
|
require.Equal(t, "user-id-1", fetchedBlock.CreatedBy)
|
|
|
|
require.Equal(t, "user-id-1", fetchedBlock.ModifiedBy)
|
2021-10-07 13:51:01 +02:00
|
|
|
assert.WithinDurationf(t, time.Now(), utils.GetTimeForMillis(fetchedBlock.CreateAt), 1*time.Second, "create time should be current time")
|
|
|
|
assert.WithinDurationf(t, time.Now(), utils.GetTimeForMillis(fetchedBlock.UpdateAt), 1*time.Second, "update time should be current time")
|
2021-07-08 16:36:43 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get a non-existing block", func(t *testing.T) {
|
|
|
|
fetchedBlock, err := store.GetBlock(container, "non-existing-id")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, fetchedBlock)
|
|
|
|
})
|
|
|
|
}
|