github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/app/bot_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 17 "github.com/mattermost/mattermost-server/v5/model" 18 "github.com/mattermost/mattermost-server/v5/utils/fileutils" 19 ) 20 21 func TestCreateBot(t *testing.T) { 22 t.Run("invalid bot", func(t *testing.T) { 23 t.Run("relative to user", func(t *testing.T) { 24 th := Setup(t).InitBasic() 25 defer th.TearDown() 26 27 _, err := th.App.CreateBot(&model.Bot{ 28 Username: "invalid username", 29 Description: "a bot", 30 OwnerId: th.BasicUser.Id, 31 }) 32 require.NotNil(t, err) 33 require.Equal(t, "model.user.is_valid.username.app_error", err.Id) 34 }) 35 36 t.Run("relative to bot", func(t *testing.T) { 37 th := Setup(t).InitBasic() 38 defer th.TearDown() 39 40 _, err := th.App.CreateBot(&model.Bot{ 41 Username: "username", 42 Description: strings.Repeat("x", 1025), 43 OwnerId: th.BasicUser.Id, 44 }) 45 require.NotNil(t, err) 46 require.Equal(t, "model.bot.is_valid.description.app_error", err.Id) 47 }) 48 49 t.Run("username contains . character", func(t *testing.T) { 50 th := Setup(t).InitBasic() 51 defer th.TearDown() 52 53 bot, err := th.App.CreateBot(&model.Bot{ 54 Username: "username.", 55 Description: "a bot", 56 OwnerId: th.BasicUser.Id, 57 }) 58 require.NotNil(t, err) 59 require.Nil(t, bot) 60 require.Equal(t, "model.user.is_valid.email.app_error", err.Id) 61 }) 62 }) 63 64 t.Run("create bot", func(t *testing.T) { 65 th := Setup(t).InitBasic() 66 defer th.TearDown() 67 68 bot, err := th.App.CreateBot(&model.Bot{ 69 Username: "username", 70 Description: "a bot", 71 OwnerId: th.BasicUser.Id, 72 }) 73 require.Nil(t, err) 74 defer th.App.PermanentDeleteBot(bot.UserId) 75 assert.Equal(t, "username", bot.Username) 76 assert.Equal(t, "a bot", bot.Description) 77 assert.Equal(t, th.BasicUser.Id, bot.OwnerId) 78 79 // Check that a post was created to add bot to team and channels 80 channel, err := th.App.GetOrCreateDirectChannel(bot.UserId, th.BasicUser.Id) 81 require.Nil(t, err) 82 posts, err := th.App.GetPosts(channel.Id, 0, 1) 83 require.Nil(t, err) 84 85 postArray := posts.ToSlice() 86 assert.Len(t, postArray, 1) 87 assert.Equal(t, postArray[0].Type, model.POST_ADD_BOT_TEAMS_CHANNELS) 88 }) 89 90 t.Run("create bot, username already used by a non-bot user", func(t *testing.T) { 91 th := Setup(t).InitBasic() 92 defer th.TearDown() 93 94 _, err := th.App.CreateBot(&model.Bot{ 95 Username: th.BasicUser.Username, 96 Description: "a bot", 97 OwnerId: th.BasicUser.Id, 98 }) 99 require.NotNil(t, err) 100 require.Equal(t, "store.sql_user.save.username_exists.app_error", err.Id) 101 }) 102 } 103 104 func TestPatchBot(t *testing.T) { 105 t.Run("invalid patch for user", func(t *testing.T) { 106 th := Setup(t).InitBasic() 107 defer th.TearDown() 108 109 bot, err := th.App.CreateBot(&model.Bot{ 110 Username: "username", 111 Description: "a bot", 112 OwnerId: th.BasicUser.Id, 113 }) 114 require.Nil(t, err) 115 defer th.App.PermanentDeleteBot(bot.UserId) 116 117 botPatch := &model.BotPatch{ 118 Username: sToP("invalid username"), 119 DisplayName: sToP("an updated bot"), 120 Description: sToP("updated bot"), 121 } 122 123 _, err = th.App.PatchBot(bot.UserId, botPatch) 124 require.NotNil(t, err) 125 require.Equal(t, "model.user.is_valid.username.app_error", err.Id) 126 }) 127 128 t.Run("invalid patch for bot", func(t *testing.T) { 129 th := Setup(t).InitBasic() 130 defer th.TearDown() 131 132 bot, err := th.App.CreateBot(&model.Bot{ 133 Username: "username", 134 Description: "a bot", 135 OwnerId: th.BasicUser.Id, 136 }) 137 require.Nil(t, err) 138 defer th.App.PermanentDeleteBot(bot.UserId) 139 140 botPatch := &model.BotPatch{ 141 Username: sToP("username"), 142 DisplayName: sToP("display name"), 143 Description: sToP(strings.Repeat("x", 1025)), 144 } 145 146 _, err = th.App.PatchBot(bot.UserId, botPatch) 147 require.NotNil(t, err) 148 require.Equal(t, "model.bot.is_valid.description.app_error", err.Id) 149 }) 150 151 t.Run("patch bot", func(t *testing.T) { 152 th := Setup(t).InitBasic() 153 defer th.TearDown() 154 155 bot := &model.Bot{ 156 Username: "username", 157 DisplayName: "bot", 158 Description: "a bot", 159 OwnerId: th.BasicUser.Id, 160 } 161 162 createdBot, err := th.App.CreateBot(bot) 163 require.Nil(t, err) 164 defer th.App.PermanentDeleteBot(createdBot.UserId) 165 166 botPatch := &model.BotPatch{ 167 Username: sToP("username2"), 168 DisplayName: sToP("updated bot"), 169 Description: sToP("an updated bot"), 170 } 171 172 patchedBot, err := th.App.PatchBot(createdBot.UserId, botPatch) 173 require.Nil(t, err) 174 175 // patchedBot should create a new .UpdateAt time 176 require.NotEqual(t, createdBot.UpdateAt, patchedBot.UpdateAt) 177 178 createdBot.Username = "username2" 179 createdBot.DisplayName = "updated bot" 180 createdBot.Description = "an updated bot" 181 createdBot.UpdateAt = patchedBot.UpdateAt 182 require.Equal(t, createdBot, patchedBot) 183 }) 184 185 t.Run("patch bot, username already used by a non-bot user", func(t *testing.T) { 186 th := Setup(t).InitBasic() 187 defer th.TearDown() 188 189 bot, err := th.App.CreateBot(&model.Bot{ 190 Username: "username", 191 DisplayName: "bot", 192 Description: "a bot", 193 OwnerId: th.BasicUser.Id, 194 }) 195 require.Nil(t, err) 196 defer th.App.PermanentDeleteBot(bot.UserId) 197 198 botPatch := &model.BotPatch{ 199 Username: sToP(th.BasicUser2.Username), 200 } 201 202 _, err = th.App.PatchBot(bot.UserId, botPatch) 203 require.NotNil(t, err) 204 require.Equal(t, "store.sql_user.update.username_taken.app_error", err.Id) 205 }) 206 } 207 208 func TestGetBot(t *testing.T) { 209 th := Setup(t).InitBasic() 210 defer th.TearDown() 211 212 bot1, err := th.App.CreateBot(&model.Bot{ 213 Username: "username", 214 Description: "a bot", 215 OwnerId: th.BasicUser.Id, 216 }) 217 require.Nil(t, err) 218 defer th.App.PermanentDeleteBot(bot1.UserId) 219 220 bot2, err := th.App.CreateBot(&model.Bot{ 221 Username: "username2", 222 Description: "a second bot", 223 OwnerId: th.BasicUser.Id, 224 }) 225 require.Nil(t, err) 226 defer th.App.PermanentDeleteBot(bot2.UserId) 227 228 deletedBot, err := th.App.CreateBot(&model.Bot{ 229 Username: "username3", 230 Description: "a deleted bot", 231 OwnerId: th.BasicUser.Id, 232 }) 233 require.Nil(t, err) 234 deletedBot, err = th.App.UpdateBotActive(deletedBot.UserId, false) 235 require.Nil(t, err) 236 defer th.App.PermanentDeleteBot(deletedBot.UserId) 237 238 t.Run("get unknown bot", func(t *testing.T) { 239 _, err := th.App.GetBot(model.NewId(), false) 240 require.NotNil(t, err) 241 require.Equal(t, "store.sql_bot.get.missing.app_error", err.Id) 242 }) 243 244 t.Run("get bot1", func(t *testing.T) { 245 bot, err := th.App.GetBot(bot1.UserId, false) 246 require.Nil(t, err) 247 assert.Equal(t, bot1, bot) 248 }) 249 250 t.Run("get bot2", func(t *testing.T) { 251 bot, err := th.App.GetBot(bot2.UserId, false) 252 require.Nil(t, err) 253 assert.Equal(t, bot2, bot) 254 }) 255 256 t.Run("get deleted bot", func(t *testing.T) { 257 _, err := th.App.GetBot(deletedBot.UserId, false) 258 require.NotNil(t, err) 259 require.Equal(t, "store.sql_bot.get.missing.app_error", err.Id) 260 }) 261 262 t.Run("get deleted bot, include deleted", func(t *testing.T) { 263 bot, err := th.App.GetBot(deletedBot.UserId, true) 264 require.Nil(t, err) 265 assert.Equal(t, deletedBot, bot) 266 }) 267 } 268 269 func TestGetBots(t *testing.T) { 270 th := Setup(t) 271 defer th.TearDown() 272 273 OwnerId1 := model.NewId() 274 OwnerId2 := model.NewId() 275 276 bot1, err := th.App.CreateBot(&model.Bot{ 277 Username: "username", 278 Description: "a bot", 279 OwnerId: OwnerId1, 280 }) 281 require.Nil(t, err) 282 defer th.App.PermanentDeleteBot(bot1.UserId) 283 284 deletedBot1, err := th.App.CreateBot(&model.Bot{ 285 Username: "username4", 286 Description: "a deleted bot", 287 OwnerId: OwnerId1, 288 }) 289 require.Nil(t, err) 290 deletedBot1, err = th.App.UpdateBotActive(deletedBot1.UserId, false) 291 require.Nil(t, err) 292 defer th.App.PermanentDeleteBot(deletedBot1.UserId) 293 294 bot2, err := th.App.CreateBot(&model.Bot{ 295 Username: "username2", 296 Description: "a second bot", 297 OwnerId: OwnerId1, 298 }) 299 require.Nil(t, err) 300 defer th.App.PermanentDeleteBot(bot2.UserId) 301 302 bot3, err := th.App.CreateBot(&model.Bot{ 303 Username: "username3", 304 Description: "a third bot", 305 OwnerId: OwnerId1, 306 }) 307 require.Nil(t, err) 308 defer th.App.PermanentDeleteBot(bot3.UserId) 309 310 bot4, err := th.App.CreateBot(&model.Bot{ 311 Username: "username5", 312 Description: "a fourth bot", 313 OwnerId: OwnerId2, 314 }) 315 require.Nil(t, err) 316 defer th.App.PermanentDeleteBot(bot4.UserId) 317 318 deletedBot2, err := th.App.CreateBot(&model.Bot{ 319 Username: "username6", 320 Description: "a deleted bot", 321 OwnerId: OwnerId2, 322 }) 323 require.Nil(t, err) 324 deletedBot2, err = th.App.UpdateBotActive(deletedBot2.UserId, false) 325 require.Nil(t, err) 326 defer th.App.PermanentDeleteBot(deletedBot2.UserId) 327 328 t.Run("get bots, page=0, perPage=10", func(t *testing.T) { 329 bots, err := th.App.GetBots(&model.BotGetOptions{ 330 Page: 0, 331 PerPage: 10, 332 OwnerId: "", 333 IncludeDeleted: false, 334 }) 335 require.Nil(t, err) 336 assert.Equal(t, model.BotList{bot1, bot2, bot3, bot4}, bots) 337 }) 338 339 t.Run("get bots, page=0, perPage=1", func(t *testing.T) { 340 bots, err := th.App.GetBots(&model.BotGetOptions{ 341 Page: 0, 342 PerPage: 1, 343 OwnerId: "", 344 IncludeDeleted: false, 345 }) 346 require.Nil(t, err) 347 assert.Equal(t, model.BotList{bot1}, bots) 348 }) 349 350 t.Run("get bots, page=1, perPage=2", func(t *testing.T) { 351 bots, err := th.App.GetBots(&model.BotGetOptions{ 352 Page: 1, 353 PerPage: 2, 354 OwnerId: "", 355 IncludeDeleted: false, 356 }) 357 require.Nil(t, err) 358 assert.Equal(t, model.BotList{bot3, bot4}, bots) 359 }) 360 361 t.Run("get bots, page=2, perPage=2", func(t *testing.T) { 362 bots, err := th.App.GetBots(&model.BotGetOptions{ 363 Page: 2, 364 PerPage: 2, 365 OwnerId: "", 366 IncludeDeleted: false, 367 }) 368 require.Nil(t, err) 369 assert.Equal(t, model.BotList{}, bots) 370 }) 371 372 t.Run("get bots, page=0, perPage=10, include deleted", func(t *testing.T) { 373 bots, err := th.App.GetBots(&model.BotGetOptions{ 374 Page: 0, 375 PerPage: 10, 376 OwnerId: "", 377 IncludeDeleted: true, 378 }) 379 require.Nil(t, err) 380 assert.Equal(t, model.BotList{bot1, deletedBot1, bot2, bot3, bot4, deletedBot2}, bots) 381 }) 382 383 t.Run("get bots, page=0, perPage=1, include deleted", func(t *testing.T) { 384 bots, err := th.App.GetBots(&model.BotGetOptions{ 385 Page: 0, 386 PerPage: 1, 387 OwnerId: "", 388 IncludeDeleted: true, 389 }) 390 require.Nil(t, err) 391 assert.Equal(t, model.BotList{bot1}, bots) 392 }) 393 394 t.Run("get bots, page=1, perPage=2, include deleted", func(t *testing.T) { 395 bots, err := th.App.GetBots(&model.BotGetOptions{ 396 Page: 1, 397 PerPage: 2, 398 OwnerId: "", 399 IncludeDeleted: true, 400 }) 401 require.Nil(t, err) 402 assert.Equal(t, model.BotList{bot2, bot3}, bots) 403 }) 404 405 t.Run("get bots, page=2, perPage=2, include deleted", func(t *testing.T) { 406 bots, err := th.App.GetBots(&model.BotGetOptions{ 407 Page: 2, 408 PerPage: 2, 409 OwnerId: "", 410 IncludeDeleted: true, 411 }) 412 require.Nil(t, err) 413 assert.Equal(t, model.BotList{bot4, deletedBot2}, bots) 414 }) 415 416 t.Run("get offset=0, limit=10, creator id 1", func(t *testing.T) { 417 bots, err := th.App.GetBots(&model.BotGetOptions{ 418 Page: 0, 419 PerPage: 10, 420 OwnerId: OwnerId1, 421 IncludeDeleted: false, 422 }) 423 require.Nil(t, err) 424 require.Equal(t, model.BotList{bot1, bot2, bot3}, bots) 425 }) 426 427 t.Run("get offset=0, limit=10, creator id 2", func(t *testing.T) { 428 bots, err := th.App.GetBots(&model.BotGetOptions{ 429 Page: 0, 430 PerPage: 10, 431 OwnerId: OwnerId2, 432 IncludeDeleted: false, 433 }) 434 require.Nil(t, err) 435 require.Equal(t, model.BotList{bot4}, bots) 436 }) 437 438 t.Run("get offset=0, limit=10, include deleted, creator id 1", func(t *testing.T) { 439 bots, err := th.App.GetBots(&model.BotGetOptions{ 440 Page: 0, 441 PerPage: 10, 442 OwnerId: OwnerId1, 443 IncludeDeleted: true, 444 }) 445 require.Nil(t, err) 446 require.Equal(t, model.BotList{bot1, deletedBot1, bot2, bot3}, bots) 447 }) 448 449 t.Run("get offset=0, limit=10, include deleted, creator id 2", func(t *testing.T) { 450 bots, err := th.App.GetBots(&model.BotGetOptions{ 451 Page: 0, 452 PerPage: 10, 453 OwnerId: OwnerId2, 454 IncludeDeleted: true, 455 }) 456 require.Nil(t, err) 457 require.Equal(t, model.BotList{bot4, deletedBot2}, bots) 458 }) 459 } 460 461 func TestUpdateBotActive(t *testing.T) { 462 t.Run("unknown bot", func(t *testing.T) { 463 th := Setup(t).InitBasic() 464 defer th.TearDown() 465 466 _, err := th.App.UpdateBotActive(model.NewId(), false) 467 require.NotNil(t, err) 468 require.Equal(t, "store.sql_user.missing_account.const", err.Id) 469 }) 470 471 t.Run("disable/enable bot", func(t *testing.T) { 472 th := Setup(t).InitBasic() 473 defer th.TearDown() 474 475 bot, err := th.App.CreateBot(&model.Bot{ 476 Username: "username", 477 Description: "a bot", 478 OwnerId: th.BasicUser.Id, 479 }) 480 require.Nil(t, err) 481 defer th.App.PermanentDeleteBot(bot.UserId) 482 483 disabledBot, err := th.App.UpdateBotActive(bot.UserId, false) 484 require.Nil(t, err) 485 require.NotEqual(t, 0, disabledBot.DeleteAt) 486 487 // Disabling should be idempotent 488 disabledBotAgain, err := th.App.UpdateBotActive(bot.UserId, false) 489 require.Nil(t, err) 490 require.Equal(t, disabledBot.DeleteAt, disabledBotAgain.DeleteAt) 491 492 reenabledBot, err := th.App.UpdateBotActive(bot.UserId, true) 493 require.Nil(t, err) 494 require.EqualValues(t, 0, reenabledBot.DeleteAt) 495 496 // Re-enabling should be idempotent 497 reenabledBotAgain, err := th.App.UpdateBotActive(bot.UserId, true) 498 require.Nil(t, err) 499 require.Equal(t, reenabledBot.DeleteAt, reenabledBotAgain.DeleteAt) 500 }) 501 } 502 503 func TestPermanentDeleteBot(t *testing.T) { 504 th := Setup(t).InitBasic() 505 defer th.TearDown() 506 507 bot, err := th.App.CreateBot(&model.Bot{ 508 Username: "username", 509 Description: "a bot", 510 OwnerId: th.BasicUser.Id, 511 }) 512 require.Nil(t, err) 513 514 require.Nil(t, th.App.PermanentDeleteBot(bot.UserId)) 515 516 _, err = th.App.GetBot(bot.UserId, false) 517 require.NotNil(t, err) 518 require.Equal(t, "store.sql_bot.get.missing.app_error", err.Id) 519 } 520 521 func TestDisableUserBots(t *testing.T) { 522 th := Setup(t) 523 defer th.TearDown() 524 525 ownerId1 := model.NewId() 526 ownerId2 := model.NewId() 527 528 bots := []*model.Bot{} 529 defer func() { 530 for _, bot := range bots { 531 th.App.PermanentDeleteBot(bot.UserId) 532 } 533 }() 534 535 for i := 0; i < 46; i++ { 536 bot, err := th.App.CreateBot(&model.Bot{ 537 Username: fmt.Sprintf("username%v", i), 538 Description: "a bot", 539 OwnerId: ownerId1, 540 }) 541 require.Nil(t, err) 542 bots = append(bots, bot) 543 } 544 require.Len(t, bots, 46) 545 546 u2bot1, err := th.App.CreateBot(&model.Bot{ 547 Username: "username_nodisable", 548 Description: "a bot", 549 OwnerId: ownerId2, 550 }) 551 require.Nil(t, err) 552 defer th.App.PermanentDeleteBot(u2bot1.UserId) 553 554 err = th.App.disableUserBots(ownerId1) 555 require.Nil(t, err) 556 557 // Check all bots and corrensponding users are disabled for creator 1 558 for _, bot := range bots { 559 retbot, err2 := th.App.GetBot(bot.UserId, true) 560 require.Nil(t, err2) 561 require.NotZero(t, retbot.DeleteAt, bot.Username) 562 } 563 564 // Check bots and corresponding user not disabled for creator 2 565 bot, err := th.App.GetBot(u2bot1.UserId, true) 566 require.Nil(t, err) 567 require.Zero(t, bot.DeleteAt) 568 569 user, err := th.App.GetUser(u2bot1.UserId) 570 require.Nil(t, err) 571 require.Zero(t, user.DeleteAt) 572 573 // Bad id doesn't do anything or break horribly 574 err = th.App.disableUserBots(model.NewId()) 575 require.Nil(t, err) 576 } 577 578 func TestNotifySysadminsBotOwnerDisabled(t *testing.T) { 579 th := Setup(t) 580 defer th.TearDown() 581 582 userBots := []*model.Bot{} 583 defer func() { 584 for _, bot := range userBots { 585 th.App.PermanentDeleteBot(bot.UserId) 586 } 587 }() 588 589 // // Create two sysadmins 590 sysadmin1 := model.User{ 591 Email: "sys1@example.com", 592 Nickname: "nn_sysadmin1", 593 Password: "hello1", 594 Username: "un_sysadmin1", 595 Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 596 _, err := th.App.CreateUser(&sysadmin1) 597 require.Nil(t, err, "failed to create user") 598 th.App.UpdateUserRoles(sysadmin1.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false) 599 600 sysadmin2 := model.User{ 601 Email: "sys2@example.com", 602 Nickname: "nn_sysadmin2", 603 Password: "hello1", 604 Username: "un_sysadmin2", 605 Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 606 _, err = th.App.CreateUser(&sysadmin2) 607 require.Nil(t, err, "failed to create user") 608 th.App.UpdateUserRoles(sysadmin2.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false) 609 610 // create user to be disabled 611 user1, err := th.App.CreateUser(&model.User{ 612 Email: "user1@example.com", 613 Username: "user1_disabled", 614 Nickname: "user1", 615 Password: "Password1", 616 }) 617 require.Nil(t, err, "failed to create user") 618 619 // create user that doesn't own any bots 620 user2, err := th.App.CreateUser(&model.User{ 621 Email: "user2@example.com", 622 Username: "user2_disabled", 623 Nickname: "user2", 624 Password: "Password1", 625 }) 626 require.Nil(t, err, "failed to create user") 627 628 const numBotsToPrint = 10 629 630 // create bots owned by user (equal to numBotsToPrint) 631 var bot *model.Bot 632 for i := 0; i < numBotsToPrint; i++ { 633 bot, err = th.App.CreateBot(&model.Bot{ 634 Username: fmt.Sprintf("bot%v", i), 635 Description: "a bot", 636 OwnerId: user1.Id, 637 }) 638 require.Nil(t, err) 639 userBots = append(userBots, bot) 640 } 641 assert.Len(t, userBots, 10) 642 643 // get DM channels for sysadmin1 and sysadmin2 644 channelSys1, appErr := th.App.GetOrCreateDirectChannel(sysadmin1.Id, sysadmin1.Id) 645 require.Nil(t, appErr) 646 channelSys2, appErr := th.App.GetOrCreateDirectChannel(sysadmin2.Id, sysadmin2.Id) 647 require.Nil(t, appErr) 648 649 // send notification for user without bots 650 err = th.App.notifySysadminsBotOwnerDeactivated(user2.Id) 651 require.Nil(t, err) 652 653 // get posts from sysadmin1 and sysadmin2 DM channels 654 posts1, err := th.App.GetPosts(channelSys1.Id, 0, 5) 655 require.Nil(t, err) 656 assert.Empty(t, posts1.Order) 657 658 posts2, err := th.App.GetPosts(channelSys2.Id, 0, 5) 659 require.Nil(t, err) 660 assert.Empty(t, posts2.Order) 661 662 // send notification for user with bots 663 err = th.App.notifySysadminsBotOwnerDeactivated(user1.Id) 664 require.Nil(t, err) 665 666 // get posts from sysadmin1 and sysadmin2 DM channels 667 posts1, err = th.App.GetPosts(channelSys1.Id, 0, 5) 668 require.Nil(t, err) 669 assert.Len(t, posts1.Order, 1) 670 671 posts2, err = th.App.GetPosts(channelSys2.Id, 0, 5) 672 require.Nil(t, err) 673 assert.Len(t, posts2.Order, 1) 674 675 post := posts1.Posts[posts1.Order[0]].Message 676 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) 677 678 // print all bots 679 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = true }) 680 message := th.App.getDisableBotSysadminMessage(user1, userBots) 681 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) 682 683 // print all bots 684 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = false }) 685 message = th.App.getDisableBotSysadminMessage(user1, userBots) 686 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) 687 688 // create additional bot to go over the printable limit 689 for i := numBotsToPrint; i < numBotsToPrint+1; i++ { 690 bot, err = th.App.CreateBot(&model.Bot{ 691 Username: fmt.Sprintf("bot%v", i), 692 Description: "a bot", 693 OwnerId: user1.Id, 694 }) 695 require.Nil(t, err) 696 userBots = append(userBots, bot) 697 } 698 assert.Len(t, userBots, 11) 699 700 // truncate number bots printed 701 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = true }) 702 message = th.App.getDisableBotSysadminMessage(user1, userBots) 703 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) 704 705 // truncate number bots printed 706 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = false }) 707 message = th.App.getDisableBotSysadminMessage(user1, userBots) 708 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) 709 } 710 711 func TestConvertUserToBot(t *testing.T) { 712 t.Run("invalid user", func(t *testing.T) { 713 t.Run("invalid user id", func(t *testing.T) { 714 th := Setup(t).InitBasic() 715 defer th.TearDown() 716 717 _, err := th.App.ConvertUserToBot(&model.User{ 718 Username: "username", 719 Id: "", 720 }) 721 require.NotNil(t, err) 722 require.Equal(t, "model.bot.is_valid.user_id.app_error", err.Id) 723 }) 724 725 t.Run("invalid username", func(t *testing.T) { 726 th := Setup(t).InitBasic() 727 defer th.TearDown() 728 729 _, err := th.App.ConvertUserToBot(&model.User{ 730 Username: "invalid username", 731 Id: th.BasicUser.Id, 732 }) 733 require.NotNil(t, err) 734 require.Equal(t, "model.bot.is_valid.username.app_error", err.Id) 735 }) 736 }) 737 738 t.Run("valid user", func(t *testing.T) { 739 th := Setup(t).InitBasic() 740 defer th.TearDown() 741 742 bot, err := th.App.ConvertUserToBot(&model.User{ 743 Username: "username", 744 Id: th.BasicUser.Id, 745 }) 746 require.Nil(t, err) 747 defer th.App.PermanentDeleteBot(bot.UserId) 748 assert.Equal(t, "username", bot.Username) 749 assert.Equal(t, th.BasicUser.Id, bot.OwnerId) 750 }) 751 } 752 753 func TestSetBotIconImage(t *testing.T) { 754 t.Run("invalid bot", func(t *testing.T) { 755 th := Setup(t).InitBasic() 756 defer th.TearDown() 757 758 path, _ := fileutils.FindDir("tests") 759 svgFile, fileErr := os.Open(filepath.Join(path, "test.svg")) 760 require.NoError(t, fileErr) 761 defer svgFile.Close() 762 763 err := th.App.SetBotIconImage("invalid_bot_id", svgFile) 764 require.NotNil(t, err) 765 }) 766 767 t.Run("valid bot", func(t *testing.T) { 768 th := Setup(t).InitBasic() 769 defer th.TearDown() 770 771 // Set an icon image 772 path, _ := fileutils.FindDir("tests") 773 svgFile, fileErr := os.Open(filepath.Join(path, "test.svg")) 774 require.NoError(t, fileErr) 775 defer svgFile.Close() 776 777 expectedData, fileErr := ioutil.ReadAll(svgFile) 778 require.Nil(t, fileErr) 779 require.NotNil(t, expectedData) 780 781 bot, err := th.App.ConvertUserToBot(&model.User{ 782 Username: "username", 783 Id: th.BasicUser.Id, 784 }) 785 require.Nil(t, err) 786 defer th.App.PermanentDeleteBot(bot.UserId) 787 788 fpath := fmt.Sprintf("/bots/%v/icon.svg", bot.UserId) 789 exists, err := th.App.FileExists(fpath) 790 require.Nil(t, err) 791 require.False(t, exists, "icon.svg shouldn't exist for the bot") 792 793 svgFile.Seek(0, 0) 794 err = th.App.SetBotIconImage(bot.UserId, svgFile) 795 require.Nil(t, err) 796 797 exists, err = th.App.FileExists(fpath) 798 require.Nil(t, err) 799 require.True(t, exists, "icon.svg should exist for the bot") 800 801 actualData, err := th.App.ReadFile(fpath) 802 require.Nil(t, err) 803 require.NotNil(t, actualData) 804 805 require.Equal(t, expectedData, actualData) 806 }) 807 } 808 809 func TestGetBotIconImage(t *testing.T) { 810 t.Run("invalid bot", func(t *testing.T) { 811 th := Setup(t).InitBasic() 812 defer th.TearDown() 813 814 actualData, err := th.App.GetBotIconImage("invalid_bot_id") 815 require.NotNil(t, err) 816 require.Nil(t, actualData) 817 }) 818 819 t.Run("valid bot", func(t *testing.T) { 820 th := Setup(t).InitBasic() 821 defer th.TearDown() 822 823 // Set an icon image 824 path, _ := fileutils.FindDir("tests") 825 svgFile, fileErr := os.Open(filepath.Join(path, "test.svg")) 826 require.NoError(t, fileErr) 827 defer svgFile.Close() 828 829 expectedData, fileErr := ioutil.ReadAll(svgFile) 830 require.Nil(t, fileErr) 831 require.NotNil(t, expectedData) 832 833 bot, err := th.App.ConvertUserToBot(&model.User{ 834 Username: "username", 835 Id: th.BasicUser.Id, 836 }) 837 require.Nil(t, err) 838 defer th.App.PermanentDeleteBot(bot.UserId) 839 840 svgFile.Seek(0, 0) 841 fpath := fmt.Sprintf("/bots/%v/icon.svg", bot.UserId) 842 _, err = th.App.WriteFile(svgFile, fpath) 843 require.Nil(t, err) 844 845 actualBytes, err := th.App.GetBotIconImage(bot.UserId) 846 require.Nil(t, err) 847 require.NotNil(t, actualBytes) 848 849 actualData, err := th.App.ReadFile(fpath) 850 require.Nil(t, err) 851 require.NotNil(t, actualData) 852 853 require.Equal(t, expectedData, actualData) 854 }) 855 } 856 857 func TestDeleteBotIconImage(t *testing.T) { 858 t.Run("invalid bot", func(t *testing.T) { 859 th := Setup(t).InitBasic() 860 defer th.TearDown() 861 862 err := th.App.DeleteBotIconImage("invalid_bot_id") 863 require.NotNil(t, err) 864 }) 865 866 t.Run("valid bot", func(t *testing.T) { 867 th := Setup(t).InitBasic() 868 defer th.TearDown() 869 870 // Set an icon image 871 path, _ := fileutils.FindDir("tests") 872 svgFile, fileErr := os.Open(filepath.Join(path, "test.svg")) 873 require.NoError(t, fileErr) 874 defer svgFile.Close() 875 876 expectedData, fileErr := ioutil.ReadAll(svgFile) 877 require.Nil(t, fileErr) 878 require.NotNil(t, expectedData) 879 880 bot, err := th.App.ConvertUserToBot(&model.User{ 881 Username: "username", 882 Id: th.BasicUser.Id, 883 }) 884 require.Nil(t, err) 885 defer th.App.PermanentDeleteBot(bot.UserId) 886 887 // Set icon 888 svgFile.Seek(0, 0) 889 err = th.App.SetBotIconImage(bot.UserId, svgFile) 890 require.Nil(t, err) 891 892 // Get icon 893 actualData, err := th.App.GetBotIconImage(bot.UserId) 894 require.Nil(t, err) 895 require.NotNil(t, actualData) 896 require.Equal(t, expectedData, actualData) 897 898 // Bot icon should exist 899 fpath := fmt.Sprintf("/bots/%v/icon.svg", bot.UserId) 900 exists, err := th.App.FileExists(fpath) 901 require.Nil(t, err) 902 require.True(t, exists, "icon.svg should exist for the bot") 903 904 // Delete icon 905 err = th.App.DeleteBotIconImage(bot.UserId) 906 require.Nil(t, err) 907 908 // Bot icon should not exist 909 exists, err = th.App.FileExists(fpath) 910 require.Nil(t, err) 911 require.False(t, exists, "icon.svg should be deleted for the bot") 912 }) 913 } 914 915 func sToP(s string) *string { 916 return &s 917 }