332 lines
9.7 KiB
Go
332 lines
9.7 KiB
Go
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||
|
// See LICENSE.txt for license information.
|
||
|
|
||
|
package storetests
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
|
||
|
"github.com/mattermost/focalboard/server/model"
|
||
|
storeservice "github.com/mattermost/focalboard/server/services/store"
|
||
|
"github.com/mattermost/focalboard/server/utils"
|
||
|
)
|
||
|
|
||
|
func StoreTestCloudStore(t *testing.T, setup func(t *testing.T) (storeservice.Store, func())) {
|
||
|
t.Run("GetUsedCardsCount", func(t *testing.T) {
|
||
|
store, tearDown := setup(t)
|
||
|
defer tearDown()
|
||
|
testGetUsedCardsCount(t, store)
|
||
|
})
|
||
|
t.Run("TestGetCardLimitTimestamp", func(t *testing.T) {
|
||
|
store, tearDown := setup(t)
|
||
|
defer tearDown()
|
||
|
testGetCardLimitTimestamp(t, store)
|
||
|
})
|
||
|
t.Run("TestUpdateCardLimitTimestamp", func(t *testing.T) {
|
||
|
store, tearDown := setup(t)
|
||
|
defer tearDown()
|
||
|
testUpdateCardLimitTimestamp(t, store)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func testGetUsedCardsCount(t *testing.T, store storeservice.Store) {
|
||
|
userID := "user-id"
|
||
|
|
||
|
t.Run("should return zero when no cards have been created", func(t *testing.T) {
|
||
|
count, err := store.GetUsedCardsCount()
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, count)
|
||
|
})
|
||
|
|
||
|
t.Run("should correctly return the cards of all boards", func(t *testing.T) {
|
||
|
// two boards
|
||
|
for _, boardID := range []string{"board1", "board2"} {
|
||
|
boardType := model.BoardTypeOpen
|
||
|
if boardID == "board2" {
|
||
|
boardType = model.BoardTypePrivate
|
||
|
}
|
||
|
|
||
|
board := &model.Board{
|
||
|
ID: boardID,
|
||
|
TeamID: testTeamID,
|
||
|
Type: boardType,
|
||
|
}
|
||
|
|
||
|
_, err := store.InsertBoard(board, userID)
|
||
|
require.NoError(t, err)
|
||
|
}
|
||
|
|
||
|
// board 1 has three cards
|
||
|
for _, cardID := range []string{"card1", "card2", "card3"} {
|
||
|
card := model.Block{
|
||
|
ID: cardID,
|
||
|
ParentID: "board1",
|
||
|
BoardID: "board1",
|
||
|
Type: model.TypeCard,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&card, userID))
|
||
|
}
|
||
|
|
||
|
// board 2 has two cards
|
||
|
for _, cardID := range []string{"card4", "card5"} {
|
||
|
card := model.Block{
|
||
|
ID: cardID,
|
||
|
ParentID: "board2",
|
||
|
BoardID: "board2",
|
||
|
Type: model.TypeCard,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&card, userID))
|
||
|
}
|
||
|
|
||
|
count, err := store.GetUsedCardsCount()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, 5, count)
|
||
|
})
|
||
|
|
||
|
t.Run("should not take into account content blocks", func(t *testing.T) {
|
||
|
// we add a couple of content blocks
|
||
|
text := model.Block{
|
||
|
ID: "text-id",
|
||
|
ParentID: "card1",
|
||
|
BoardID: "board1",
|
||
|
Type: model.TypeText,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&text, userID))
|
||
|
|
||
|
view := model.Block{
|
||
|
ID: "view-id",
|
||
|
ParentID: "board1",
|
||
|
BoardID: "board1",
|
||
|
Type: model.TypeView,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&view, userID))
|
||
|
|
||
|
// and count should not change
|
||
|
count, err := store.GetUsedCardsCount()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, 5, count)
|
||
|
})
|
||
|
|
||
|
t.Run("should not take into account cards belonging to templates", func(t *testing.T) {
|
||
|
// we add a template with cards
|
||
|
templateID := "template-id"
|
||
|
boardTemplate := model.Block{
|
||
|
ID: templateID,
|
||
|
BoardID: templateID,
|
||
|
Type: model.TypeBoard,
|
||
|
Fields: map[string]interface{}{
|
||
|
"isTemplate": true,
|
||
|
},
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&boardTemplate, userID))
|
||
|
|
||
|
for _, cardID := range []string{"card6", "card7", "card8"} {
|
||
|
card := model.Block{
|
||
|
ID: cardID,
|
||
|
ParentID: templateID,
|
||
|
BoardID: templateID,
|
||
|
Type: model.TypeCard,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&card, userID))
|
||
|
}
|
||
|
|
||
|
// and count should still be the same
|
||
|
count, err := store.GetUsedCardsCount()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, 5, count)
|
||
|
})
|
||
|
|
||
|
t.Run("should not take into account deleted cards", func(t *testing.T) {
|
||
|
// we create a ninth card on the first board
|
||
|
card9 := model.Block{
|
||
|
ID: "card9",
|
||
|
ParentID: "board1",
|
||
|
BoardID: "board1",
|
||
|
Type: model.TypeCard,
|
||
|
DeleteAt: utils.GetMillis(),
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&card9, userID))
|
||
|
|
||
|
// and count should still be the same
|
||
|
count, err := store.GetUsedCardsCount()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, 5, count)
|
||
|
})
|
||
|
|
||
|
t.Run("should not take into account cards from deleted boards", func(t *testing.T) {
|
||
|
require.NoError(t, store.DeleteBoard("board2", "user-id"))
|
||
|
|
||
|
count, err := store.GetUsedCardsCount()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, 3, count)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func testGetCardLimitTimestamp(t *testing.T, store storeservice.Store) {
|
||
|
t.Run("should return 0 if there is no entry in the database", func(t *testing.T) {
|
||
|
rawValue, err := store.GetSystemSetting(storeservice.CardLimitTimestampSystemKey)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, "", rawValue)
|
||
|
|
||
|
cardLimitTimestamp, err := store.GetCardLimitTimestamp()
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
})
|
||
|
|
||
|
t.Run("should return an int64 representation of the value", func(t *testing.T) {
|
||
|
require.NoError(t, store.SetSystemSetting(storeservice.CardLimitTimestampSystemKey, "1234"))
|
||
|
|
||
|
cardLimitTimestamp, err := store.GetCardLimitTimestamp()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, int64(1234), cardLimitTimestamp)
|
||
|
})
|
||
|
|
||
|
t.Run("should return an invalid value error if the value is not a number", func(t *testing.T) {
|
||
|
require.NoError(t, store.SetSystemSetting(storeservice.CardLimitTimestampSystemKey, "abc"))
|
||
|
|
||
|
cardLimitTimestamp, err := store.GetCardLimitTimestamp()
|
||
|
require.ErrorContains(t, err, "card limit value is invalid")
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func testUpdateCardLimitTimestamp(t *testing.T, store storeservice.Store) {
|
||
|
userID := "user-id"
|
||
|
|
||
|
// two boards
|
||
|
for _, boardID := range []string{"board1", "board2"} {
|
||
|
boardType := model.BoardTypeOpen
|
||
|
if boardID == "board2" {
|
||
|
boardType = model.BoardTypePrivate
|
||
|
}
|
||
|
|
||
|
board := &model.Board{
|
||
|
ID: boardID,
|
||
|
TeamID: testTeamID,
|
||
|
Type: boardType,
|
||
|
}
|
||
|
|
||
|
_, err := store.InsertBoard(board, userID)
|
||
|
require.NoError(t, err)
|
||
|
}
|
||
|
|
||
|
// board 1 has five cards
|
||
|
for _, cardID := range []string{"card1", "card2", "card3", "card4", "card5"} {
|
||
|
card := model.Block{
|
||
|
ID: cardID,
|
||
|
ParentID: "board1",
|
||
|
BoardID: "board1",
|
||
|
Type: model.TypeCard,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&card, userID))
|
||
|
time.Sleep(10 * time.Millisecond)
|
||
|
}
|
||
|
|
||
|
// board 2 has five cards
|
||
|
for _, cardID := range []string{"card6", "card7", "card8", "card9", "card10"} {
|
||
|
card := model.Block{
|
||
|
ID: cardID,
|
||
|
ParentID: "board2",
|
||
|
BoardID: "board2",
|
||
|
Type: model.TypeCard,
|
||
|
}
|
||
|
require.NoError(t, store.InsertBlock(&card, userID))
|
||
|
time.Sleep(10 * time.Millisecond)
|
||
|
}
|
||
|
|
||
|
t.Run("should set the timestamp to zero if the card limit is zero", func(t *testing.T) {
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(0)
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
|
||
|
cardLimitTimestampStr, err := store.GetSystemSetting(storeservice.CardLimitTimestampSystemKey)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, "0", cardLimitTimestampStr)
|
||
|
})
|
||
|
|
||
|
t.Run("should correctly modify the limit several times in a row", func(t *testing.T) {
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(0)
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
|
||
|
cardLimitTimestamp, err = store.UpdateCardLimitTimestamp(10)
|
||
|
require.NoError(t, err)
|
||
|
require.NotZero(t, cardLimitTimestamp)
|
||
|
|
||
|
cardLimitTimestampStr, err := store.GetSystemSetting(storeservice.CardLimitTimestampSystemKey)
|
||
|
require.NoError(t, err)
|
||
|
require.NotEqual(t, "0", cardLimitTimestampStr)
|
||
|
|
||
|
cardLimitTimestamp, err = store.UpdateCardLimitTimestamp(0)
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
|
||
|
cardLimitTimestampStr, err = store.GetSystemSetting(storeservice.CardLimitTimestampSystemKey)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, "0", cardLimitTimestampStr)
|
||
|
})
|
||
|
|
||
|
t.Run("should set the correct timestamp", func(t *testing.T) {
|
||
|
t.Run("limit 10", func(t *testing.T) {
|
||
|
// we fetch the first block
|
||
|
card1, err := store.GetBlock("card1")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// and assert that if the limit is 10, the stored
|
||
|
// timestamp corresponds to the card's update_at
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(10)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, card1.UpdateAt, cardLimitTimestamp)
|
||
|
})
|
||
|
|
||
|
t.Run("limit 5", func(t *testing.T) {
|
||
|
// if the limit is 5, the timestamp should be the one from
|
||
|
// the sixth card (the first five are older and out of the
|
||
|
card6, err := store.GetBlock("card6")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(5)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, card6.UpdateAt, cardLimitTimestamp)
|
||
|
})
|
||
|
|
||
|
t.Run("limit should be zero if we have less cards than the limit", func(t *testing.T) {
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(100)
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
})
|
||
|
|
||
|
t.Run("we update the first inserted card and assert that with limit 1 that's the limit that is set", func(t *testing.T) {
|
||
|
time.Sleep(10 * time.Millisecond)
|
||
|
card1, err := store.GetBlock("card1")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
card1.Title = "New title"
|
||
|
require.NoError(t, store.InsertBlock(card1, userID))
|
||
|
|
||
|
newCard1, err := store.GetBlock("card1")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(1)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, newCard1.UpdateAt, cardLimitTimestamp)
|
||
|
})
|
||
|
|
||
|
t.Run("limit should stop applying if we remove the last card", func(t *testing.T) {
|
||
|
initialCardLimitTimestamp, err := store.GetCardLimitTimestamp()
|
||
|
require.NoError(t, err)
|
||
|
require.NotZero(t, initialCardLimitTimestamp)
|
||
|
|
||
|
time.Sleep(10 * time.Millisecond)
|
||
|
require.NoError(t, store.DeleteBlock("card1", userID))
|
||
|
|
||
|
cardLimitTimestamp, err := store.UpdateCardLimitTimestamp(10)
|
||
|
require.NoError(t, err)
|
||
|
require.Zero(t, cardLimitTimestamp)
|
||
|
})
|
||
|
})
|
||
|
}
|