th.InitBasic initializes users, channels, and teams. But a lot of tests don't use it at all, causing unncessary delays. A single InitBasic call takes around 400ms. This PR removes 71 of them, approximately shaving off 28 seconds. Arguably, this would be more because some tests run in loops.
918 строки
27 KiB
Go
918 строки
27 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost-server/v5/model"
|
|
"github.com/mattermost/mattermost-server/v5/utils/fileutils"
|
|
)
|
|
|
|
func TestCreateBot(t *testing.T) {
|
|
t.Run("invalid bot", func(t *testing.T) {
|
|
t.Run("relative to user", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
_, err := th.App.CreateBot(&model.Bot{
|
|
Username: "invalid username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "model.user.is_valid.username.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("relative to bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
_, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: strings.Repeat("x", 1025),
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "model.bot.is_valid.description.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("username contains . character", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username.",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.NotNil(t, err)
|
|
require.Nil(t, bot)
|
|
require.Equal(t, "model.user.is_valid.email.app_error", err.Id)
|
|
})
|
|
})
|
|
|
|
t.Run("create bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
assert.Equal(t, "username", bot.Username)
|
|
assert.Equal(t, "a bot", bot.Description)
|
|
assert.Equal(t, th.BasicUser.Id, bot.OwnerId)
|
|
|
|
// Check that a post was created to add bot to team and channels
|
|
channel, err := th.App.GetOrCreateDirectChannel(bot.UserId, th.BasicUser.Id)
|
|
require.Nil(t, err)
|
|
posts, err := th.App.GetPosts(channel.Id, 0, 1)
|
|
require.Nil(t, err)
|
|
|
|
postArray := posts.ToSlice()
|
|
assert.Len(t, postArray, 1)
|
|
assert.Equal(t, postArray[0].Type, model.POST_ADD_BOT_TEAMS_CHANNELS)
|
|
})
|
|
|
|
t.Run("create bot, username already used by a non-bot user", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
_, err := th.App.CreateBot(&model.Bot{
|
|
Username: th.BasicUser.Username,
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "store.sql_user.save.username_exists.app_error", err.Id)
|
|
})
|
|
}
|
|
|
|
func TestPatchBot(t *testing.T) {
|
|
t.Run("invalid patch for user", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
botPatch := &model.BotPatch{
|
|
Username: sToP("invalid username"),
|
|
DisplayName: sToP("an updated bot"),
|
|
Description: sToP("updated bot"),
|
|
}
|
|
|
|
_, err = th.App.PatchBot(bot.UserId, botPatch)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "model.user.is_valid.username.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("invalid patch for bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
botPatch := &model.BotPatch{
|
|
Username: sToP("username"),
|
|
DisplayName: sToP("display name"),
|
|
Description: sToP(strings.Repeat("x", 1025)),
|
|
}
|
|
|
|
_, err = th.App.PatchBot(bot.UserId, botPatch)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "model.bot.is_valid.description.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("patch bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot := &model.Bot{
|
|
Username: "username",
|
|
DisplayName: "bot",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
}
|
|
|
|
createdBot, err := th.App.CreateBot(bot)
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(createdBot.UserId)
|
|
|
|
botPatch := &model.BotPatch{
|
|
Username: sToP("username2"),
|
|
DisplayName: sToP("updated bot"),
|
|
Description: sToP("an updated bot"),
|
|
}
|
|
|
|
patchedBot, err := th.App.PatchBot(createdBot.UserId, botPatch)
|
|
require.Nil(t, err)
|
|
|
|
// patchedBot should create a new .UpdateAt time
|
|
require.NotEqual(t, createdBot.UpdateAt, patchedBot.UpdateAt)
|
|
|
|
createdBot.Username = "username2"
|
|
createdBot.DisplayName = "updated bot"
|
|
createdBot.Description = "an updated bot"
|
|
createdBot.UpdateAt = patchedBot.UpdateAt
|
|
require.Equal(t, createdBot, patchedBot)
|
|
})
|
|
|
|
t.Run("patch bot, username already used by a non-bot user", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
DisplayName: "bot",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
botPatch := &model.BotPatch{
|
|
Username: sToP(th.BasicUser2.Username),
|
|
}
|
|
|
|
_, err = th.App.PatchBot(bot.UserId, botPatch)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "store.sql_user.update.username_taken.app_error", err.Id)
|
|
})
|
|
}
|
|
|
|
func TestGetBot(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot1, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot1.UserId)
|
|
|
|
bot2, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username2",
|
|
Description: "a second bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot2.UserId)
|
|
|
|
deletedBot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username3",
|
|
Description: "a deleted bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
deletedBot, err = th.App.UpdateBotActive(deletedBot.UserId, false)
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(deletedBot.UserId)
|
|
|
|
t.Run("get unknown bot", func(t *testing.T) {
|
|
_, err := th.App.GetBot(model.NewId(), false)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "store.sql_bot.get.missing.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("get bot1", func(t *testing.T) {
|
|
bot, err := th.App.GetBot(bot1.UserId, false)
|
|
require.Nil(t, err)
|
|
assert.Equal(t, bot1, bot)
|
|
})
|
|
|
|
t.Run("get bot2", func(t *testing.T) {
|
|
bot, err := th.App.GetBot(bot2.UserId, false)
|
|
require.Nil(t, err)
|
|
assert.Equal(t, bot2, bot)
|
|
})
|
|
|
|
t.Run("get deleted bot", func(t *testing.T) {
|
|
_, err := th.App.GetBot(deletedBot.UserId, false)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "store.sql_bot.get.missing.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("get deleted bot, include deleted", func(t *testing.T) {
|
|
bot, err := th.App.GetBot(deletedBot.UserId, true)
|
|
require.Nil(t, err)
|
|
assert.Equal(t, deletedBot, bot)
|
|
})
|
|
}
|
|
|
|
func TestGetBots(t *testing.T) {
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
OwnerId1 := model.NewId()
|
|
OwnerId2 := model.NewId()
|
|
|
|
bot1, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: OwnerId1,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot1.UserId)
|
|
|
|
deletedBot1, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username4",
|
|
Description: "a deleted bot",
|
|
OwnerId: OwnerId1,
|
|
})
|
|
require.Nil(t, err)
|
|
deletedBot1, err = th.App.UpdateBotActive(deletedBot1.UserId, false)
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(deletedBot1.UserId)
|
|
|
|
bot2, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username2",
|
|
Description: "a second bot",
|
|
OwnerId: OwnerId1,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot2.UserId)
|
|
|
|
bot3, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username3",
|
|
Description: "a third bot",
|
|
OwnerId: OwnerId1,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot3.UserId)
|
|
|
|
bot4, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username5",
|
|
Description: "a fourth bot",
|
|
OwnerId: OwnerId2,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot4.UserId)
|
|
|
|
deletedBot2, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username6",
|
|
Description: "a deleted bot",
|
|
OwnerId: OwnerId2,
|
|
})
|
|
require.Nil(t, err)
|
|
deletedBot2, err = th.App.UpdateBotActive(deletedBot2.UserId, false)
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(deletedBot2.UserId)
|
|
|
|
t.Run("get bots, page=0, perPage=10", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 10,
|
|
OwnerId: "",
|
|
IncludeDeleted: false,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot1, bot2, bot3, bot4}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=0, perPage=1", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 1,
|
|
OwnerId: "",
|
|
IncludeDeleted: false,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot1}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=1, perPage=2", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 1,
|
|
PerPage: 2,
|
|
OwnerId: "",
|
|
IncludeDeleted: false,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot3, bot4}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=2, perPage=2", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 2,
|
|
PerPage: 2,
|
|
OwnerId: "",
|
|
IncludeDeleted: false,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=0, perPage=10, include deleted", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 10,
|
|
OwnerId: "",
|
|
IncludeDeleted: true,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot1, deletedBot1, bot2, bot3, bot4, deletedBot2}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=0, perPage=1, include deleted", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 1,
|
|
OwnerId: "",
|
|
IncludeDeleted: true,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot1}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=1, perPage=2, include deleted", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 1,
|
|
PerPage: 2,
|
|
OwnerId: "",
|
|
IncludeDeleted: true,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot2, bot3}, bots)
|
|
})
|
|
|
|
t.Run("get bots, page=2, perPage=2, include deleted", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 2,
|
|
PerPage: 2,
|
|
OwnerId: "",
|
|
IncludeDeleted: true,
|
|
})
|
|
require.Nil(t, err)
|
|
assert.Equal(t, model.BotList{bot4, deletedBot2}, bots)
|
|
})
|
|
|
|
t.Run("get offset=0, limit=10, creator id 1", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 10,
|
|
OwnerId: OwnerId1,
|
|
IncludeDeleted: false,
|
|
})
|
|
require.Nil(t, err)
|
|
require.Equal(t, model.BotList{bot1, bot2, bot3}, bots)
|
|
})
|
|
|
|
t.Run("get offset=0, limit=10, creator id 2", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 10,
|
|
OwnerId: OwnerId2,
|
|
IncludeDeleted: false,
|
|
})
|
|
require.Nil(t, err)
|
|
require.Equal(t, model.BotList{bot4}, bots)
|
|
})
|
|
|
|
t.Run("get offset=0, limit=10, include deleted, creator id 1", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 10,
|
|
OwnerId: OwnerId1,
|
|
IncludeDeleted: true,
|
|
})
|
|
require.Nil(t, err)
|
|
require.Equal(t, model.BotList{bot1, deletedBot1, bot2, bot3}, bots)
|
|
})
|
|
|
|
t.Run("get offset=0, limit=10, include deleted, creator id 2", func(t *testing.T) {
|
|
bots, err := th.App.GetBots(&model.BotGetOptions{
|
|
Page: 0,
|
|
PerPage: 10,
|
|
OwnerId: OwnerId2,
|
|
IncludeDeleted: true,
|
|
})
|
|
require.Nil(t, err)
|
|
require.Equal(t, model.BotList{bot4, deletedBot2}, bots)
|
|
})
|
|
}
|
|
|
|
func TestUpdateBotActive(t *testing.T) {
|
|
t.Run("unknown bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
_, err := th.App.UpdateBotActive(model.NewId(), false)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "store.sql_user.missing_account.const", err.Id)
|
|
})
|
|
|
|
t.Run("disable/enable bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
disabledBot, err := th.App.UpdateBotActive(bot.UserId, false)
|
|
require.Nil(t, err)
|
|
require.NotEqual(t, 0, disabledBot.DeleteAt)
|
|
|
|
// Disabling should be idempotent
|
|
disabledBotAgain, err := th.App.UpdateBotActive(bot.UserId, false)
|
|
require.Nil(t, err)
|
|
require.Equal(t, disabledBot.DeleteAt, disabledBotAgain.DeleteAt)
|
|
|
|
reenabledBot, err := th.App.UpdateBotActive(bot.UserId, true)
|
|
require.Nil(t, err)
|
|
require.EqualValues(t, 0, reenabledBot.DeleteAt)
|
|
|
|
// Re-enabling should be idempotent
|
|
reenabledBotAgain, err := th.App.UpdateBotActive(bot.UserId, true)
|
|
require.Nil(t, err)
|
|
require.Equal(t, reenabledBot.DeleteAt, reenabledBotAgain.DeleteAt)
|
|
})
|
|
}
|
|
|
|
func TestPermanentDeleteBot(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username",
|
|
Description: "a bot",
|
|
OwnerId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
|
|
require.Nil(t, th.App.PermanentDeleteBot(bot.UserId))
|
|
|
|
_, err = th.App.GetBot(bot.UserId, false)
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "store.sql_bot.get.missing.app_error", err.Id)
|
|
}
|
|
|
|
func TestDisableUserBots(t *testing.T) {
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
ownerId1 := model.NewId()
|
|
ownerId2 := model.NewId()
|
|
|
|
bots := []*model.Bot{}
|
|
defer func() {
|
|
for _, bot := range bots {
|
|
th.App.PermanentDeleteBot(bot.UserId)
|
|
}
|
|
}()
|
|
|
|
for i := 0; i < 46; i++ {
|
|
bot, err := th.App.CreateBot(&model.Bot{
|
|
Username: fmt.Sprintf("username%v", i),
|
|
Description: "a bot",
|
|
OwnerId: ownerId1,
|
|
})
|
|
require.Nil(t, err)
|
|
bots = append(bots, bot)
|
|
}
|
|
require.Len(t, bots, 46)
|
|
|
|
u2bot1, err := th.App.CreateBot(&model.Bot{
|
|
Username: "username_nodisable",
|
|
Description: "a bot",
|
|
OwnerId: ownerId2,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(u2bot1.UserId)
|
|
|
|
err = th.App.disableUserBots(ownerId1)
|
|
require.Nil(t, err)
|
|
|
|
// Check all bots and corrensponding users are disabled for creator 1
|
|
for _, bot := range bots {
|
|
retbot, err2 := th.App.GetBot(bot.UserId, true)
|
|
require.Nil(t, err2)
|
|
require.NotZero(t, retbot.DeleteAt, bot.Username)
|
|
}
|
|
|
|
// Check bots and corresponding user not disabled for creator 2
|
|
bot, err := th.App.GetBot(u2bot1.UserId, true)
|
|
require.Nil(t, err)
|
|
require.Zero(t, bot.DeleteAt)
|
|
|
|
user, err := th.App.GetUser(u2bot1.UserId)
|
|
require.Nil(t, err)
|
|
require.Zero(t, user.DeleteAt)
|
|
|
|
// Bad id doesn't do anything or break horribly
|
|
err = th.App.disableUserBots(model.NewId())
|
|
require.Nil(t, err)
|
|
}
|
|
|
|
func TestNotifySysadminsBotOwnerDisabled(t *testing.T) {
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
userBots := []*model.Bot{}
|
|
defer func() {
|
|
for _, bot := range userBots {
|
|
th.App.PermanentDeleteBot(bot.UserId)
|
|
}
|
|
}()
|
|
|
|
// // Create two sysadmins
|
|
sysadmin1 := model.User{
|
|
Email: "sys1@example.com",
|
|
Nickname: "nn_sysadmin1",
|
|
Password: "hello1",
|
|
Username: "un_sysadmin1",
|
|
Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID}
|
|
_, err := th.App.CreateUser(&sysadmin1)
|
|
require.Nil(t, err, "failed to create user")
|
|
th.App.UpdateUserRoles(sysadmin1.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false)
|
|
|
|
sysadmin2 := model.User{
|
|
Email: "sys2@example.com",
|
|
Nickname: "nn_sysadmin2",
|
|
Password: "hello1",
|
|
Username: "un_sysadmin2",
|
|
Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID}
|
|
_, err = th.App.CreateUser(&sysadmin2)
|
|
require.Nil(t, err, "failed to create user")
|
|
th.App.UpdateUserRoles(sysadmin2.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false)
|
|
|
|
// create user to be disabled
|
|
user1, err := th.App.CreateUser(&model.User{
|
|
Email: "user1@example.com",
|
|
Username: "user1_disabled",
|
|
Nickname: "user1",
|
|
Password: "Password1",
|
|
})
|
|
require.Nil(t, err, "failed to create user")
|
|
|
|
// create user that doesn't own any bots
|
|
user2, err := th.App.CreateUser(&model.User{
|
|
Email: "user2@example.com",
|
|
Username: "user2_disabled",
|
|
Nickname: "user2",
|
|
Password: "Password1",
|
|
})
|
|
require.Nil(t, err, "failed to create user")
|
|
|
|
const numBotsToPrint = 10
|
|
|
|
// create bots owned by user (equal to numBotsToPrint)
|
|
var bot *model.Bot
|
|
for i := 0; i < numBotsToPrint; i++ {
|
|
bot, err = th.App.CreateBot(&model.Bot{
|
|
Username: fmt.Sprintf("bot%v", i),
|
|
Description: "a bot",
|
|
OwnerId: user1.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
userBots = append(userBots, bot)
|
|
}
|
|
assert.Len(t, userBots, 10)
|
|
|
|
// get DM channels for sysadmin1 and sysadmin2
|
|
channelSys1, appErr := th.App.GetOrCreateDirectChannel(sysadmin1.Id, sysadmin1.Id)
|
|
require.Nil(t, appErr)
|
|
channelSys2, appErr := th.App.GetOrCreateDirectChannel(sysadmin2.Id, sysadmin2.Id)
|
|
require.Nil(t, appErr)
|
|
|
|
// send notification for user without bots
|
|
err = th.App.notifySysadminsBotOwnerDeactivated(user2.Id)
|
|
require.Nil(t, err)
|
|
|
|
// get posts from sysadmin1 and sysadmin2 DM channels
|
|
posts1, err := th.App.GetPosts(channelSys1.Id, 0, 5)
|
|
require.Nil(t, err)
|
|
assert.Empty(t, posts1.Order)
|
|
|
|
posts2, err := th.App.GetPosts(channelSys2.Id, 0, 5)
|
|
require.Nil(t, err)
|
|
assert.Empty(t, posts2.Order)
|
|
|
|
// send notification for user with bots
|
|
err = th.App.notifySysadminsBotOwnerDeactivated(user1.Id)
|
|
require.Nil(t, err)
|
|
|
|
// get posts from sysadmin1 and sysadmin2 DM channels
|
|
posts1, err = th.App.GetPosts(channelSys1.Id, 0, 5)
|
|
require.Nil(t, err)
|
|
assert.Len(t, posts1.Order, 1)
|
|
|
|
posts2, err = th.App.GetPosts(channelSys2.Id, 0, 5)
|
|
require.Nil(t, err)
|
|
assert.Len(t, posts2.Order, 1)
|
|
|
|
post := posts1.Posts[posts1.Order[0]].Message
|
|
assert.Equal(t, "user1_disabled was deactivated. They managed the following bot accounts which have now been disabled.\n\n* bot0\n* bot1\n* bot2\n* bot3\n* bot4\n* bot5\n* bot6\n* bot7\n* bot8\n* bot9\nYou can take ownership of each bot by enabling it at **Integrations > Bot Accounts** and creating new tokens for the bot.\n\nFor more information, see our [documentation](https://docs.mattermost.com/developer/bot-accounts.html#what-happens-when-a-user-who-owns-bot-accounts-is-disabled).", post)
|
|
|
|
// print all bots
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = true })
|
|
message := th.App.getDisableBotSysadminMessage(user1, userBots)
|
|
assert.Equal(t, "user1_disabled was deactivated. They managed the following bot accounts which have now been disabled.\n\n* bot0\n* bot1\n* bot2\n* bot3\n* bot4\n* bot5\n* bot6\n* bot7\n* bot8\n* bot9\nYou can take ownership of each bot by enabling it at **Integrations > Bot Accounts** and creating new tokens for the bot.\n\nFor more information, see our [documentation](https://docs.mattermost.com/developer/bot-accounts.html#what-happens-when-a-user-who-owns-bot-accounts-is-disabled).", message)
|
|
|
|
// print all bots
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = false })
|
|
message = th.App.getDisableBotSysadminMessage(user1, userBots)
|
|
assert.Equal(t, "user1_disabled was deactivated. They managed the following bot accounts which are still enabled.\n\n* bot0\n* bot1\n* bot2\n* bot3\n* bot4\n* bot5\n* bot6\n* bot7\n* bot8\n* bot9\n\nWe strongly recommend you to take ownership of each bot by re-enabling it at **Integrations > Bot Accounts** and creating new tokens for the bot.\n\nFor more information, see our [documentation](https://docs.mattermost.com/developer/bot-accounts.html#what-happens-when-a-user-who-owns-bot-accounts-is-disabled).\n\nIf you want bot accounts to disable automatically after owner deactivation, set “Disable bot accounts when owner is deactivated” in **System Console > Integrations > Bot Accounts** to true.", message)
|
|
|
|
// create additional bot to go over the printable limit
|
|
for i := numBotsToPrint; i < numBotsToPrint+1; i++ {
|
|
bot, err = th.App.CreateBot(&model.Bot{
|
|
Username: fmt.Sprintf("bot%v", i),
|
|
Description: "a bot",
|
|
OwnerId: user1.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
userBots = append(userBots, bot)
|
|
}
|
|
assert.Len(t, userBots, 11)
|
|
|
|
// truncate number bots printed
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = true })
|
|
message = th.App.getDisableBotSysadminMessage(user1, userBots)
|
|
assert.Equal(t, "user1_disabled was deactivated. They managed 11 bot accounts which have now been disabled, including the following:\n\n* bot0\n* bot1\n* bot2\n* bot3\n* bot4\n* bot5\n* bot6\n* bot7\n* bot8\n* bot9\nYou can take ownership of each bot by enabling it at **Integrations > Bot Accounts** and creating new tokens for the bot.\n\nFor more information, see our [documentation](https://docs.mattermost.com/developer/bot-accounts.html#what-happens-when-a-user-who-owns-bot-accounts-is-disabled).", message)
|
|
|
|
// truncate number bots printed
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = false })
|
|
message = th.App.getDisableBotSysadminMessage(user1, userBots)
|
|
assert.Equal(t, "user1_disabled was deactivated. They managed 11 bot accounts which are still enabled, including the following:\n\n* bot0\n* bot1\n* bot2\n* bot3\n* bot4\n* bot5\n* bot6\n* bot7\n* bot8\n* bot9\nWe strongly recommend you to take ownership of each bot by re-enabling it at **Integrations > Bot Accounts** and creating new tokens for the bot.\n\nFor more information, see our [documentation](https://docs.mattermost.com/developer/bot-accounts.html#what-happens-when-a-user-who-owns-bot-accounts-is-disabled).\n\nIf you want bot accounts to disable automatically after owner deactivation, set “Disable bot accounts when owner is deactivated” in **System Console > Integrations > Bot Accounts** to true.", message)
|
|
}
|
|
|
|
func TestConvertUserToBot(t *testing.T) {
|
|
t.Run("invalid user", func(t *testing.T) {
|
|
t.Run("invalid user id", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
_, err := th.App.ConvertUserToBot(&model.User{
|
|
Username: "username",
|
|
Id: "",
|
|
})
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "model.bot.is_valid.user_id.app_error", err.Id)
|
|
})
|
|
|
|
t.Run("invalid username", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
_, err := th.App.ConvertUserToBot(&model.User{
|
|
Username: "invalid username",
|
|
Id: th.BasicUser.Id,
|
|
})
|
|
require.NotNil(t, err)
|
|
require.Equal(t, "model.bot.is_valid.username.app_error", err.Id)
|
|
})
|
|
})
|
|
|
|
t.Run("valid user", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
bot, err := th.App.ConvertUserToBot(&model.User{
|
|
Username: "username",
|
|
Id: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
assert.Equal(t, "username", bot.Username)
|
|
assert.Equal(t, th.BasicUser.Id, bot.OwnerId)
|
|
})
|
|
}
|
|
|
|
func TestSetBotIconImage(t *testing.T) {
|
|
t.Run("invalid bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
path, _ := fileutils.FindDir("tests")
|
|
svgFile, fileErr := os.Open(filepath.Join(path, "test.svg"))
|
|
require.NoError(t, fileErr)
|
|
defer svgFile.Close()
|
|
|
|
err := th.App.SetBotIconImage("invalid_bot_id", svgFile)
|
|
require.NotNil(t, err)
|
|
})
|
|
|
|
t.Run("valid bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
// Set an icon image
|
|
path, _ := fileutils.FindDir("tests")
|
|
svgFile, fileErr := os.Open(filepath.Join(path, "test.svg"))
|
|
require.NoError(t, fileErr)
|
|
defer svgFile.Close()
|
|
|
|
expectedData, fileErr := ioutil.ReadAll(svgFile)
|
|
require.Nil(t, fileErr)
|
|
require.NotNil(t, expectedData)
|
|
|
|
bot, err := th.App.ConvertUserToBot(&model.User{
|
|
Username: "username",
|
|
Id: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
fpath := fmt.Sprintf("/bots/%v/icon.svg", bot.UserId)
|
|
exists, err := th.App.FileExists(fpath)
|
|
require.Nil(t, err)
|
|
require.False(t, exists, "icon.svg shouldn't exist for the bot")
|
|
|
|
svgFile.Seek(0, 0)
|
|
err = th.App.SetBotIconImage(bot.UserId, svgFile)
|
|
require.Nil(t, err)
|
|
|
|
exists, err = th.App.FileExists(fpath)
|
|
require.Nil(t, err)
|
|
require.True(t, exists, "icon.svg should exist for the bot")
|
|
|
|
actualData, err := th.App.ReadFile(fpath)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actualData)
|
|
|
|
require.Equal(t, expectedData, actualData)
|
|
})
|
|
}
|
|
|
|
func TestGetBotIconImage(t *testing.T) {
|
|
t.Run("invalid bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
actualData, err := th.App.GetBotIconImage("invalid_bot_id")
|
|
require.NotNil(t, err)
|
|
require.Nil(t, actualData)
|
|
})
|
|
|
|
t.Run("valid bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
// Set an icon image
|
|
path, _ := fileutils.FindDir("tests")
|
|
svgFile, fileErr := os.Open(filepath.Join(path, "test.svg"))
|
|
require.NoError(t, fileErr)
|
|
defer svgFile.Close()
|
|
|
|
expectedData, fileErr := ioutil.ReadAll(svgFile)
|
|
require.Nil(t, fileErr)
|
|
require.NotNil(t, expectedData)
|
|
|
|
bot, err := th.App.ConvertUserToBot(&model.User{
|
|
Username: "username",
|
|
Id: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
svgFile.Seek(0, 0)
|
|
fpath := fmt.Sprintf("/bots/%v/icon.svg", bot.UserId)
|
|
_, err = th.App.WriteFile(svgFile, fpath)
|
|
require.Nil(t, err)
|
|
|
|
actualBytes, err := th.App.GetBotIconImage(bot.UserId)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actualBytes)
|
|
|
|
actualData, err := th.App.ReadFile(fpath)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actualData)
|
|
|
|
require.Equal(t, expectedData, actualData)
|
|
})
|
|
}
|
|
|
|
func TestDeleteBotIconImage(t *testing.T) {
|
|
t.Run("invalid bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
err := th.App.DeleteBotIconImage("invalid_bot_id")
|
|
require.NotNil(t, err)
|
|
})
|
|
|
|
t.Run("valid bot", func(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
// Set an icon image
|
|
path, _ := fileutils.FindDir("tests")
|
|
svgFile, fileErr := os.Open(filepath.Join(path, "test.svg"))
|
|
require.NoError(t, fileErr)
|
|
defer svgFile.Close()
|
|
|
|
expectedData, fileErr := ioutil.ReadAll(svgFile)
|
|
require.Nil(t, fileErr)
|
|
require.NotNil(t, expectedData)
|
|
|
|
bot, err := th.App.ConvertUserToBot(&model.User{
|
|
Username: "username",
|
|
Id: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, err)
|
|
defer th.App.PermanentDeleteBot(bot.UserId)
|
|
|
|
// Set icon
|
|
svgFile.Seek(0, 0)
|
|
err = th.App.SetBotIconImage(bot.UserId, svgFile)
|
|
require.Nil(t, err)
|
|
|
|
// Get icon
|
|
actualData, err := th.App.GetBotIconImage(bot.UserId)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actualData)
|
|
require.Equal(t, expectedData, actualData)
|
|
|
|
// Bot icon should exist
|
|
fpath := fmt.Sprintf("/bots/%v/icon.svg", bot.UserId)
|
|
exists, err := th.App.FileExists(fpath)
|
|
require.Nil(t, err)
|
|
require.True(t, exists, "icon.svg should exist for the bot")
|
|
|
|
// Delete icon
|
|
err = th.App.DeleteBotIconImage(bot.UserId)
|
|
require.Nil(t, err)
|
|
|
|
// Bot icon should not exist
|
|
exists, err = th.App.FileExists(fpath)
|
|
require.Nil(t, err)
|
|
require.False(t, exists, "icon.svg should be deleted for the bot")
|
|
})
|
|
}
|
|
|
|
func sToP(s string) *string {
|
|
return &s
|
|
}
|