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

332 lines
9.7 KiB
Go
Raw Normal View History

// 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)
})
})
}