Files
upstream-mattermost/server/channels/app/channel_bookmark_test.go
upstream-mirror 240db4e2a7
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 00:29:55 +05:00

631 lines
22 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
import (
"fmt"
"testing"
"time"
"github.com/mattermost/mattermost/server/public/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func find_bookmark(slice []*model.ChannelBookmarkWithFileInfo, id string) *model.ChannelBookmarkWithFileInfo {
for _, element := range slice {
if element.Id == id {
return element
}
}
return nil
}
func createBookmark(name string, bookmarkType model.ChannelBookmarkType, channelId string, fileId string) *model.ChannelBookmark {
bookmark := &model.ChannelBookmark{
ChannelId: channelId,
DisplayName: name,
Type: bookmarkType,
Emoji: ":smile:",
}
if bookmarkType == model.ChannelBookmarkLink {
bookmark.LinkUrl = "https://mattermost.com"
}
if bookmarkType == model.ChannelBookmarkFile {
bookmark.FileId = fileId
}
return bookmark
}
func TestCreateBookmark(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic(t)
t.Run("create a channel bookmark", func(t *testing.T) {
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
bookmark1 := createBookmark("Link bookmark test", model.ChannelBookmarkLink, th.BasicChannel.Id, "")
bookmarkResp, err := th.App.CreateChannelBookmark(th.Context, bookmark1, "")
require.Nil(t, err)
require.NotNil(t, bookmarkResp)
assert.Equal(t, bookmarkResp.ChannelId, th.BasicChannel.Id)
assert.NotEmpty(t, bookmarkResp.Id)
bookmark2 := createBookmark("File bookmark test", model.ChannelBookmarkFile, th.BasicChannel.Id, "")
bookmarkResp, err = th.App.CreateChannelBookmark(th.Context, bookmark2, "")
assert.Nil(t, bookmarkResp)
assert.NotNil(t, err)
})
t.Run("Cannot create more than MaxBookmarksPerChannel", func(t *testing.T) {
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
for i := 1; i < model.MaxBookmarksPerChannel; i++ {
bookmark := createBookmark(fmt.Sprintf("Link bookmark test %d", i), model.ChannelBookmarkLink, th.BasicChannel.Id, "")
bookmarkResp, err := th.App.CreateChannelBookmark(th.Context, bookmark, "")
require.Nil(t, err)
require.NotNil(t, bookmarkResp)
assert.Equal(t, bookmarkResp.ChannelId, th.BasicChannel.Id)
assert.NotEmpty(t, bookmarkResp.Id)
}
bookmark := createBookmark("Bookmark that should not be added", model.ChannelBookmarkLink, th.BasicChannel.Id, "")
bookmarkResp, err := th.App.CreateChannelBookmark(th.Context, bookmark, "")
assert.Nil(t, bookmarkResp)
assert.NotNil(t, err)
})
}
func TestUpdateBookmark(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic(t)
var updateBookmark *model.ChannelBookmarkWithFileInfo
testUpdateAnotherFile := func(th *TestHelper, t *testing.T) {
file := &model.FileInfo{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
}
_, err := th.App.Srv().Store().FileInfo().Save(th.Context, file)
assert.NoError(t, err)
defer func() {
err = th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, file.Id)
assert.NoError(t, err)
}()
bookmark2 := createBookmark("File to be updated", model.ChannelBookmarkFile, th.BasicChannel.Id, file.Id)
bookmarkResp, appErr := th.App.CreateChannelBookmark(th.Context, bookmark2, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkResp)
file2 := &model.FileInfo{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
}
_, err = th.App.Srv().Store().FileInfo().Save(th.Context, file2)
assert.NoError(t, err)
err = th.App.Srv().Store().FileInfo().AttachToPost(th.Context, file2.Id, model.NewId(), th.BasicChannel.Id, model.BookmarkFileOwner)
assert.NoError(t, err)
defer func() {
err = th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, file2.Id)
require.NoError(t, err)
}()
bookmark2.FileId = file2.Id
bookmarkResp, appErr = th.App.CreateChannelBookmark(th.Context, bookmark2, "")
require.NotNil(t, appErr)
require.Nil(t, bookmarkResp)
}
var testUpdateInvalidFiles = func(th *TestHelper, t *testing.T, creatingUserId string, updatingUserId string) {
file := &model.FileInfo{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
}
_, err := th.App.Srv().Store().FileInfo().Save(th.Context, file)
assert.NoError(t, err)
defer func() {
err = th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, file.Id)
assert.NoError(t, err)
}()
th.Context.Session().UserId = creatingUserId
bookmark := createBookmark("File to be updated", model.ChannelBookmarkFile, th.BasicChannel.Id, file.Id)
bookmarkToEdit, appErr := th.App.CreateChannelBookmark(th.Context, bookmark, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkToEdit)
otherChannel := th.CreateChannel(t, th.BasicTeam)
createAt := time.Now().Add(-1 * time.Minute)
deleteAt := createAt.Add(1 * time.Second)
deletedFile := &model.FileInfo{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
CreateAt: createAt.UnixMilli(),
UpdateAt: createAt.UnixMilli(),
DeleteAt: deleteAt.UnixMilli(),
}
_, err = th.App.Srv().Store().FileInfo().Save(th.Context, deletedFile)
assert.NoError(t, err)
defer func() {
err = th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, deletedFile.Id)
assert.NoError(t, err)
}()
th.Context.Session().UserId = updatingUserId
updateBookmarkPending := bookmarkToEdit.Clone()
updateBookmarkPending.FileId = deletedFile.Id
bookmarkEdited, appErr := th.App.UpdateChannelBookmark(th.Context, updateBookmarkPending, "")
assert.NotNil(t, appErr)
require.Nil(t, bookmarkEdited)
anotherChannelFile := &model.FileInfo{
Id: model.NewId(),
ChannelId: otherChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
}
_, err = th.App.Srv().Store().FileInfo().Save(th.Context, anotherChannelFile)
assert.NoError(t, err)
defer func() {
err = th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, anotherChannelFile.Id)
require.NoError(t, err)
}()
updateBookmarkPending = bookmarkToEdit.Clone()
updateBookmarkPending.FileId = anotherChannelFile.Id
bookmarkEdited, appErr = th.App.UpdateChannelBookmark(th.Context, updateBookmarkPending, "")
assert.NotNil(t, appErr)
require.Nil(t, bookmarkEdited)
}
t.Run("same user update a channel bookmark", func(t *testing.T) {
bookmark1 := &model.ChannelBookmark{
ChannelId: th.BasicChannel.Id,
DisplayName: "Link bookmark test",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
Emoji: ":smile:",
}
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
bookmarkResp, err := th.App.CreateChannelBookmark(th.Context, bookmark1, "")
require.Nil(t, err)
require.NotNil(t, bookmarkResp)
updateBookmark = bookmarkResp.Clone()
updateBookmark.DisplayName = "New name"
time.Sleep(1 * time.Millisecond) // to avoid collisions
response, _ := th.App.UpdateChannelBookmark(th.Context, updateBookmark, "")
require.NotNil(t, response)
assert.Greater(t, response.Updated.UpdateAt, response.Updated.CreateAt)
testUpdateAnotherFile(th, t)
testUpdateInvalidFiles(th, t, th.BasicUser.Id, th.BasicUser.Id)
})
t.Run("another user update a channel bookmark", func(t *testing.T) {
updateBookmark2 := updateBookmark.Clone()
updateBookmark2.DisplayName = "Another new name"
th.Context.Session().UserId = th.BasicUser2.Id
response, _ := th.App.UpdateChannelBookmark(th.Context, updateBookmark2, "")
require.NotNil(t, response)
assert.Equal(t, response.Updated.OriginalId, response.Deleted.Id)
assert.Equal(t, response.Updated.DeleteAt, int64(0))
assert.Greater(t, response.Deleted.DeleteAt, int64(0))
assert.Equal(t, "Another new name", response.Updated.DisplayName)
assert.Equal(t, "New name", response.Deleted.DisplayName)
testUpdateAnotherFile(th, t)
testUpdateInvalidFiles(th, t, th.BasicUser.Id, th.BasicUser.Id)
})
t.Run("update an already deleted channel bookmark", func(t *testing.T) {
bookmark1 := &model.ChannelBookmark{
ChannelId: th.BasicChannel.Id,
DisplayName: "Link bookmark test",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
Emoji: ":smile:",
}
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
bookmarkResp, err := th.App.CreateChannelBookmark(th.Context, bookmark1, "")
require.Nil(t, err)
require.NotNil(t, bookmarkResp)
updateBookmark = bookmarkResp.Clone()
_, err = th.App.DeleteChannelBookmark(updateBookmark.Id, "")
assert.Nil(t, err)
updateBookmark.DisplayName = "New name"
_, err = th.App.UpdateChannelBookmark(th.Context, updateBookmark, "")
assert.NotNil(t, err)
})
t.Run("update a nonexisting channel bookmark", func(t *testing.T) {
updateBookmark := &model.ChannelBookmark{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
DisplayName: "Link bookmark test",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
Emoji: ":smile:",
}
_, err := th.App.UpdateChannelBookmark(th.Context, updateBookmark.ToBookmarkWithFileInfo(nil), "")
assert.NotNil(t, err)
assert.Equal(t, "app.channel.bookmark.get_existing.app_err", err.Id)
})
}
func TestDeleteBookmark(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic(t)
t.Run("delete a channel bookmark", func(t *testing.T) {
bookmark1 := &model.ChannelBookmark{
ChannelId: th.BasicChannel.Id,
DisplayName: "Link bookmark test",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
Emoji: ":smile:",
}
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
bookmarkResp, err := th.App.CreateChannelBookmark(th.Context, bookmark1, "")
require.Nil(t, err)
require.NotNil(t, bookmarkResp)
bookmarkResp, err = th.App.DeleteChannelBookmark(bookmarkResp.Id, "")
require.Nil(t, err)
require.NotNil(t, bookmarkResp)
assert.Greater(t, bookmarkResp.DeleteAt, int64(0))
})
}
func TestGetChannelBookmarks(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic(t)
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
bookmark1 := &model.ChannelBookmark{
ChannelId: th.BasicChannel.Id,
DisplayName: "Bookmark 1",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
Emoji: ":smile:",
}
_, appErr := th.App.CreateChannelBookmark(th.Context, bookmark1, "")
assert.Nil(t, appErr)
file := &model.FileInfo{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
}
_, err := th.App.Srv().Store().FileInfo().Save(th.Context, file)
assert.NoError(t, err)
defer func() {
err := th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, file.Id)
assert.NoError(t, err)
}()
bookmark2 := &model.ChannelBookmark{
ChannelId: th.BasicChannel.Id,
DisplayName: "Bookmark 2",
FileId: file.Id,
Type: model.ChannelBookmarkFile,
Emoji: ":smile:",
}
_, appErr = th.App.CreateChannelBookmark(th.Context, bookmark2, "")
assert.Nil(t, appErr)
t.Run("get bookmarks of a channel", func(t *testing.T) {
bookmarks, err := th.App.GetChannelBookmarks(th.BasicChannel.Id, 0)
require.Nil(t, err)
require.NotNil(t, bookmarks)
assert.Len(t, bookmarks, 2)
})
t.Run("get bookmarks of a channel after one is deleted (aka only return the changed bookmarks)", func(t *testing.T) {
now := model.GetMillis()
_, appErr := th.App.DeleteChannelBookmark(bookmark1.Id, "")
assert.Nil(t, appErr)
bookmarks, err := th.App.GetChannelBookmarks(th.BasicChannel.Id, 0)
require.Nil(t, err)
require.NotNil(t, bookmarks)
assert.Len(t, bookmarks, 1)
bookmarks, err = th.App.GetChannelBookmarks(th.BasicChannel.Id, now)
require.Nil(t, err)
require.NotNil(t, bookmarks)
assert.Len(t, bookmarks, 1)
deleted := false
for _, b := range bookmarks {
if b.DeleteAt > 0 {
deleted = true
break
}
}
assert.Equal(t, deleted, true)
})
}
func TestUpdateChannelBookmarkSortOrder(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic(t)
channelId := th.BasicChannel.Id
th.Context.Session().UserId = th.BasicUser.Id // set the user for the session
bookmark0 := &model.ChannelBookmark{
ChannelId: channelId,
DisplayName: "Bookmark 0",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
Emoji: ":smile:",
}
file := &model.FileInfo{
Id: model.NewId(),
ChannelId: th.BasicChannel.Id,
CreatorId: model.BookmarkFileOwner,
Path: "somepath",
ThumbnailPath: "thumbpath",
PreviewPath: "prevPath",
Name: "test file",
Extension: "png",
MimeType: "images/png",
Size: 873182,
Width: 3076,
Height: 2200,
HasPreviewImage: true,
}
bookmark1 := &model.ChannelBookmark{
ChannelId: channelId,
DisplayName: "Bookmark 1",
FileId: file.Id,
Type: model.ChannelBookmarkFile,
Emoji: ":smile:",
}
_, err := th.App.Srv().Store().FileInfo().Save(th.Context, file)
require.NoError(t, err)
defer func() {
err = th.App.Srv().Store().FileInfo().PermanentDelete(th.Context, file.Id)
require.NoError(t, err)
}()
bookmark2 := &model.ChannelBookmark{
ChannelId: channelId,
DisplayName: "Bookmark 2",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
}
bookmark3 := &model.ChannelBookmark{
ChannelId: channelId,
DisplayName: "Bookmark 3",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
}
bookmark4 := &model.ChannelBookmark{
ChannelId: channelId,
DisplayName: "Bookmark 4",
LinkUrl: "https://mattermost.com",
Type: model.ChannelBookmarkLink,
}
bookmarkResp, appErr := th.App.CreateChannelBookmark(th.Context, bookmark0, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkResp)
bookmark0 = bookmarkResp.ChannelBookmark.Clone()
bookmarkResp, appErr = th.App.CreateChannelBookmark(th.Context, bookmark1, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkResp)
bookmark1 = bookmarkResp.ChannelBookmark.Clone()
bookmarkResp, appErr = th.App.CreateChannelBookmark(th.Context, bookmark2, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkResp)
bookmark2 = bookmarkResp.ChannelBookmark.Clone()
bookmarkResp, appErr = th.App.CreateChannelBookmark(th.Context, bookmark3, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkResp)
bookmark3 = bookmarkResp.ChannelBookmark.Clone()
bookmarkResp, appErr = th.App.CreateChannelBookmark(th.Context, bookmark4, "")
require.Nil(t, appErr)
require.NotNil(t, bookmarkResp)
bookmark4 = bookmarkResp.ChannelBookmark.Clone()
t.Run("change order of bookmarks first to last", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark0.Id, channelId, int64(4), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(4))
})
t.Run("change order of bookmarks last to first", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark0.Id, channelId, int64(0), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(4))
})
t.Run("change order of bookmarks first to third", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark0.Id, channelId, int64(2), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(4))
// now reset order
_, appErr = th.App.UpdateChannelBookmarkSortOrder(bookmark0.Id, channelId, int64(0), "")
assert.Nil(t, appErr)
})
t.Run("change order of bookmarks second to third", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark1.Id, channelId, int64(2), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(4))
})
t.Run("change order of bookmarks third to second", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark1.Id, channelId, int64(1), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(4))
})
t.Run("change order of bookmarks last to previous last", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark4.Id, channelId, int64(3), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(4))
})
t.Run("change order of bookmarks last to second", func(t *testing.T) {
bookmarks, sortErr := th.App.UpdateChannelBookmarkSortOrder(bookmark3.Id, channelId, int64(1), "")
require.Nil(t, sortErr)
require.NotNil(t, bookmarks)
assert.Equal(t, find_bookmark(bookmarks, bookmark0.Id).SortOrder, int64(0))
assert.Equal(t, find_bookmark(bookmarks, bookmark3.Id).SortOrder, int64(1))
assert.Equal(t, find_bookmark(bookmarks, bookmark1.Id).SortOrder, int64(2))
assert.Equal(t, find_bookmark(bookmarks, bookmark2.Id).SortOrder, int64(3))
assert.Equal(t, find_bookmark(bookmarks, bookmark4.Id).SortOrder, int64(4))
})
t.Run("change order of bookmarks error when new index is out of bounds", func(t *testing.T) {
_, appErr = th.App.UpdateChannelBookmarkSortOrder(bookmark3.Id, channelId, int64(-1), "")
assert.NotNil(t, appErr)
_, appErr = th.App.UpdateChannelBookmarkSortOrder(bookmark3.Id, channelId, int64(5), "")
assert.NotNil(t, appErr)
})
t.Run("change order of bookmarks error when bookmark not found", func(t *testing.T) {
_, appErr = th.App.UpdateChannelBookmarkSortOrder(model.NewId(), channelId, int64(0), "")
assert.NotNil(t, appErr)
})
}