github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/plugin/helpers_bots_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package plugin_test 5 6 import ( 7 "io/ioutil" 8 "path/filepath" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 13 "github.com/mattermost/mattermost-server/v5/model" 14 "github.com/mattermost/mattermost-server/v5/plugin" 15 "github.com/mattermost/mattermost-server/v5/plugin/plugintest" 16 "github.com/mattermost/mattermost-server/v5/plugin/plugintest/mock" 17 "github.com/mattermost/mattermost-server/v5/utils/fileutils" 18 ) 19 20 func TestEnsureBot(t *testing.T) { 21 setupAPI := func() *plugintest.API { 22 return &plugintest.API{} 23 } 24 25 testbot := &model.Bot{ 26 Username: "testbot", 27 DisplayName: "Test Bot", 28 Description: "testbotdescription", 29 } 30 31 t.Run("server version incompatible", func(t *testing.T) { 32 api := setupAPI() 33 api.On("GetServerVersion").Return("5.9.0") 34 defer api.AssertExpectations(t) 35 36 p := &plugin.HelpersImpl{} 37 p.API = api 38 39 _, retErr := p.EnsureBot(nil) 40 41 assert.NotNil(t, retErr) 42 assert.Equal(t, "failed to ensure bot: incompatible server version for plugin, minimum required version: 5.10.0, current version: 5.9.0", retErr.Error()) 43 }) 44 45 t.Run("bad parameters", func(t *testing.T) { 46 t.Run("no bot", func(t *testing.T) { 47 api := setupAPI() 48 api.On("GetServerVersion").Return("5.10.0") 49 50 p := &plugin.HelpersImpl{} 51 p.API = api 52 botID, err := p.EnsureBot(nil) 53 assert.Equal(t, "", botID) 54 assert.NotNil(t, err) 55 }) 56 t.Run("bad username", func(t *testing.T) { 57 api := setupAPI() 58 api.On("GetServerVersion").Return("5.10.0") 59 60 p := &plugin.HelpersImpl{} 61 p.API = api 62 botID, err := p.EnsureBot(&model.Bot{ 63 Username: "", 64 }) 65 assert.Equal(t, "", botID) 66 assert.NotNil(t, err) 67 }) 68 }) 69 70 t.Run("if bot already exists", func(t *testing.T) { 71 t.Run("should find and return the existing bot ID", func(t *testing.T) { 72 expectedBotID := model.NewId() 73 74 api := setupAPI() 75 api.On("GetServerVersion").Return("5.10.0") 76 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 77 api.On("PatchBot", expectedBotID, &model.BotPatch{ 78 Username: &testbot.Username, 79 DisplayName: &testbot.DisplayName, 80 Description: &testbot.Description, 81 }).Return(nil, nil) 82 defer api.AssertExpectations(t) 83 84 p := &plugin.HelpersImpl{} 85 p.API = api 86 87 botID, err := p.EnsureBot(testbot) 88 89 assert.Equal(t, expectedBotID, botID) 90 assert.Nil(t, err) 91 }) 92 93 t.Run("should return an error if unable to get bot", func(t *testing.T) { 94 api := setupAPI() 95 api.On("GetServerVersion").Return("5.10.0") 96 api.On("KVGet", plugin.BotUserKey).Return(nil, &model.AppError{}) 97 defer api.AssertExpectations(t) 98 99 p := &plugin.HelpersImpl{} 100 p.API = api 101 102 botID, err := p.EnsureBot(testbot) 103 104 assert.Equal(t, "", botID) 105 assert.NotNil(t, err) 106 }) 107 108 t.Run("should set the bot profile image when specified", func(t *testing.T) { 109 expectedBotID := model.NewId() 110 api := setupAPI() 111 112 testsDir, _ := fileutils.FindDir("tests") 113 testImage := filepath.Join(testsDir, "test.png") 114 imageBytes, err := ioutil.ReadFile(testImage) 115 116 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 117 api.On("GetBundlePath").Return("", nil) 118 api.On("SetProfileImage", expectedBotID, imageBytes).Return(nil) 119 api.On("GetServerVersion").Return("5.10.0") 120 api.On("PatchBot", expectedBotID, &model.BotPatch{ 121 Username: &testbot.Username, 122 DisplayName: &testbot.DisplayName, 123 Description: &testbot.Description, 124 }).Return(nil, nil) 125 defer api.AssertExpectations(t) 126 127 p := &plugin.HelpersImpl{} 128 p.API = api 129 130 assert.Nil(t, err) 131 132 botID, err := p.EnsureBot(testbot, plugin.ProfileImagePath(testImage)) 133 assert.Equal(t, expectedBotID, botID) 134 assert.Nil(t, err) 135 }) 136 137 t.Run("should set the bot icon image when specified", func(t *testing.T) { 138 expectedBotID := model.NewId() 139 api := setupAPI() 140 141 testsDir, _ := fileutils.FindDir("tests") 142 testImage := filepath.Join(testsDir, "test.png") 143 imageBytes, err := ioutil.ReadFile(testImage) 144 assert.Nil(t, err) 145 146 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 147 api.On("GetBundlePath").Return("", nil) 148 api.On("SetBotIconImage", expectedBotID, imageBytes).Return(nil) 149 api.On("GetServerVersion").Return("5.10.0") 150 api.On("PatchBot", expectedBotID, &model.BotPatch{ 151 Username: &testbot.Username, 152 DisplayName: &testbot.DisplayName, 153 Description: &testbot.Description, 154 }).Return(nil, nil) 155 defer api.AssertExpectations(t) 156 157 p := &plugin.HelpersImpl{} 158 p.API = api 159 160 botID, err := p.EnsureBot(testbot, plugin.IconImagePath(testImage)) 161 assert.Equal(t, expectedBotID, botID) 162 assert.Nil(t, err) 163 }) 164 165 t.Run("should set both the profile image and bot icon image when specified", func(t *testing.T) { 166 expectedBotID := model.NewId() 167 api := setupAPI() 168 169 testsDir, _ := fileutils.FindDir("tests") 170 testImage := filepath.Join(testsDir, "test.png") 171 imageBytes, err := ioutil.ReadFile(testImage) 172 assert.Nil(t, err) 173 174 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 175 api.On("GetBundlePath").Return("", nil) 176 api.On("SetProfileImage", expectedBotID, imageBytes).Return(nil) 177 api.On("SetBotIconImage", expectedBotID, imageBytes).Return(nil) 178 api.On("GetServerVersion").Return("5.10.0") 179 api.On("PatchBot", expectedBotID, &model.BotPatch{ 180 Username: &testbot.Username, 181 DisplayName: &testbot.DisplayName, 182 Description: &testbot.Description, 183 }).Return(nil, nil) 184 defer api.AssertExpectations(t) 185 186 p := &plugin.HelpersImpl{} 187 p.API = api 188 189 botID, err := p.EnsureBot(testbot, plugin.ProfileImagePath(testImage), plugin.IconImagePath(testImage)) 190 assert.Equal(t, expectedBotID, botID) 191 assert.Nil(t, err) 192 }) 193 194 t.Run("should find and update the bot with new bot details", func(t *testing.T) { 195 expectedBotID := model.NewId() 196 197 expectedBotUsername := "updated_testbot" 198 expectedBotDisplayName := "Updated Test Bot" 199 expectedBotDescription := "updated testbotdescription" 200 201 testsDir, _ := fileutils.FindDir("tests") 202 testImage := filepath.Join(testsDir, "test.png") 203 imageBytes, err := ioutil.ReadFile(testImage) 204 assert.Nil(t, err) 205 206 api := setupAPI() 207 api.On("GetServerVersion").Return("5.10.0") 208 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 209 api.On("GetBundlePath").Return("", nil) 210 api.On("SetProfileImage", expectedBotID, imageBytes).Return(nil) 211 api.On("SetBotIconImage", expectedBotID, imageBytes).Return(nil) 212 api.On("PatchBot", expectedBotID, &model.BotPatch{ 213 Username: &expectedBotUsername, 214 DisplayName: &expectedBotDisplayName, 215 Description: &expectedBotDescription, 216 }).Return(nil, nil) 217 defer api.AssertExpectations(t) 218 219 p := &plugin.HelpersImpl{} 220 p.API = api 221 222 updatedTestbot := &model.Bot{ 223 Username: "updated_testbot", 224 DisplayName: "Updated Test Bot", 225 Description: "updated testbotdescription", 226 } 227 botID, err := p.EnsureBot(updatedTestbot, plugin.ProfileImagePath(testImage), plugin.IconImagePath(testImage)) 228 229 assert.Equal(t, expectedBotID, botID) 230 assert.Nil(t, err) 231 }) 232 }) 233 234 t.Run("if bot doesn't exist", func(t *testing.T) { 235 t.Run("should create the bot and return the ID", func(t *testing.T) { 236 expectedBotID := model.NewId() 237 238 api := setupAPI() 239 api.On("GetServerVersion").Return("5.10.0") 240 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 241 api.On("GetUserByUsername", testbot.Username).Return(nil, nil) 242 api.On("CreateBot", testbot).Return(&model.Bot{ 243 UserId: expectedBotID, 244 }, nil) 245 api.On("KVSet", plugin.BotUserKey, []byte(expectedBotID)).Return(nil) 246 defer api.AssertExpectations(t) 247 248 p := &plugin.HelpersImpl{} 249 p.API = api 250 251 botID, err := p.EnsureBot(testbot) 252 253 assert.Equal(t, expectedBotID, botID) 254 assert.Nil(t, err) 255 }) 256 257 t.Run("should claim existing bot and return the ID", func(t *testing.T) { 258 expectedBotID := model.NewId() 259 260 api := setupAPI() 261 api.On("GetServerVersion").Return("5.10.0") 262 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 263 api.On("GetUserByUsername", testbot.Username).Return(&model.User{ 264 Id: expectedBotID, 265 IsBot: true, 266 }, nil) 267 api.On("KVSet", plugin.BotUserKey, []byte(expectedBotID)).Return(nil) 268 defer api.AssertExpectations(t) 269 270 p := &plugin.HelpersImpl{} 271 p.API = api 272 273 botID, err := p.EnsureBot(testbot) 274 275 assert.Equal(t, expectedBotID, botID) 276 assert.Nil(t, err) 277 }) 278 279 t.Run("should return the non-bot account but log a message if user exists with the same name and is not a bot", func(t *testing.T) { 280 expectedBotID := model.NewId() 281 api := setupAPI() 282 api.On("GetServerVersion").Return("5.10.0") 283 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 284 api.On("GetUserByUsername", testbot.Username).Return(&model.User{ 285 Id: expectedBotID, 286 IsBot: false, 287 }, nil) 288 api.On("LogError", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return() 289 defer api.AssertExpectations(t) 290 291 p := &plugin.HelpersImpl{} 292 p.API = api 293 294 botID, err := p.EnsureBot(testbot) 295 296 assert.Equal(t, expectedBotID, botID) 297 assert.Nil(t, err) 298 }) 299 300 t.Run("should fail if create bot fails", func(t *testing.T) { 301 api := setupAPI() 302 api.On("GetServerVersion").Return("5.10.0") 303 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 304 api.On("GetUserByUsername", testbot.Username).Return(nil, nil) 305 api.On("CreateBot", testbot).Return(nil, &model.AppError{}) 306 defer api.AssertExpectations(t) 307 308 p := &plugin.HelpersImpl{} 309 p.API = api 310 311 botID, err := p.EnsureBot(testbot) 312 313 assert.Equal(t, "", botID) 314 assert.NotNil(t, err) 315 }) 316 317 t.Run("should create bot and set the bot profile image when specified", func(t *testing.T) { 318 expectedBotID := model.NewId() 319 api := setupAPI() 320 321 testsDir, _ := fileutils.FindDir("tests") 322 testImage := filepath.Join(testsDir, "test.png") 323 imageBytes, err := ioutil.ReadFile(testImage) 324 assert.Nil(t, err) 325 326 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 327 api.On("GetUserByUsername", testbot.Username).Return(nil, nil) 328 api.On("CreateBot", testbot).Return(&model.Bot{ 329 UserId: expectedBotID, 330 }, nil) 331 api.On("KVSet", plugin.BotUserKey, []byte(expectedBotID)).Return(nil) 332 api.On("GetBundlePath").Return("", nil) 333 api.On("SetProfileImage", expectedBotID, imageBytes).Return(nil) 334 api.On("GetServerVersion").Return("5.10.0") 335 defer api.AssertExpectations(t) 336 337 p := &plugin.HelpersImpl{} 338 p.API = api 339 340 botID, err := p.EnsureBot(testbot, plugin.ProfileImagePath(testImage)) 341 assert.Equal(t, expectedBotID, botID) 342 assert.Nil(t, err) 343 }) 344 345 t.Run("should create bot and set the bot icon image when specified", func(t *testing.T) { 346 expectedBotID := model.NewId() 347 api := setupAPI() 348 349 testsDir, _ := fileutils.FindDir("tests") 350 testImage := filepath.Join(testsDir, "test.png") 351 imageBytes, err := ioutil.ReadFile(testImage) 352 assert.Nil(t, err) 353 354 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 355 api.On("GetUserByUsername", testbot.Username).Return(nil, nil) 356 api.On("CreateBot", testbot).Return(&model.Bot{ 357 UserId: expectedBotID, 358 }, nil) 359 api.On("KVSet", plugin.BotUserKey, []byte(expectedBotID)).Return(nil) 360 api.On("GetBundlePath").Return("", nil) 361 api.On("SetBotIconImage", expectedBotID, imageBytes).Return(nil) 362 api.On("GetServerVersion").Return("5.10.0") 363 defer api.AssertExpectations(t) 364 365 p := &plugin.HelpersImpl{} 366 p.API = api 367 368 botID, err := p.EnsureBot(testbot, plugin.IconImagePath(testImage)) 369 assert.Equal(t, expectedBotID, botID) 370 assert.Nil(t, err) 371 }) 372 373 t.Run("should create bot and set both the profile image and bot icon image when specified", func(t *testing.T) { 374 expectedBotID := model.NewId() 375 api := setupAPI() 376 377 testsDir, _ := fileutils.FindDir("tests") 378 testImage := filepath.Join(testsDir, "test.png") 379 imageBytes, err := ioutil.ReadFile(testImage) 380 assert.Nil(t, err) 381 382 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 383 api.On("GetUserByUsername", testbot.Username).Return(nil, nil) 384 api.On("CreateBot", testbot).Return(&model.Bot{ 385 UserId: expectedBotID, 386 }, nil) 387 api.On("KVSet", plugin.BotUserKey, []byte(expectedBotID)).Return(nil) 388 api.On("GetBundlePath").Return("", nil) 389 api.On("SetProfileImage", expectedBotID, imageBytes).Return(nil) 390 api.On("SetBotIconImage", expectedBotID, imageBytes).Return(nil) 391 api.On("GetServerVersion").Return("5.10.0") 392 defer api.AssertExpectations(t) 393 394 p := &plugin.HelpersImpl{} 395 p.API = api 396 397 botID, err := p.EnsureBot(testbot, plugin.ProfileImagePath(testImage), plugin.IconImagePath(testImage)) 398 assert.Equal(t, expectedBotID, botID) 399 assert.Nil(t, err) 400 }) 401 }) 402 } 403 404 func TestShouldProcessMessage(t *testing.T) { 405 p := &plugin.HelpersImpl{} 406 expectedBotID := model.NewId() 407 408 setupAPI := func() *plugintest.API { 409 return &plugintest.API{} 410 } 411 412 t.Run("should not respond to itself", func(t *testing.T) { 413 api := setupAPI() 414 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 415 p.API = api 416 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{Type: model.POST_HEADER_CHANGE, UserId: expectedBotID}, plugin.AllowSystemMessages(), plugin.AllowBots()) 417 418 assert.False(t, shouldProcessMessage) 419 }) 420 421 t.Run("should not process as the post is generated by system", func(t *testing.T) { 422 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{Type: model.POST_HEADER_CHANGE}) 423 424 assert.False(t, shouldProcessMessage) 425 }) 426 427 t.Run("should not process as the post is sent to another channel", func(t *testing.T) { 428 channelID := "channel-id" 429 api := setupAPI() 430 api.On("GetChannel", channelID).Return(&model.Channel{Id: channelID, Type: model.CHANNEL_GROUP}, nil) 431 p.API = api 432 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 433 434 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{ChannelId: channelID}, plugin.AllowSystemMessages(), plugin.AllowBots(), plugin.FilterChannelIDs([]string{"another-channel-id"})) 435 436 assert.False(t, shouldProcessMessage) 437 }) 438 439 t.Run("should not process as the post is created by bot", func(t *testing.T) { 440 userID := "user-id" 441 channelID := "1" 442 api := setupAPI() 443 p.API = api 444 api.On("GetUser", userID).Return(&model.User{IsBot: true}, nil) 445 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 446 447 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{UserId: userID, ChannelId: channelID}, 448 plugin.AllowSystemMessages(), plugin.FilterUserIDs([]string{"another-user-id"})) 449 450 assert.False(t, shouldProcessMessage) 451 }) 452 453 t.Run("should not process the message as the post is not in bot dm channel", func(t *testing.T) { 454 userID := "user-id" 455 channelID := "1" 456 channel := model.Channel{ 457 Name: "user1__" + expectedBotID, 458 Type: model.CHANNEL_OPEN, 459 } 460 api := setupAPI() 461 api.On("GetChannel", channelID).Return(&channel, nil) 462 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 463 p.API = api 464 465 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{UserId: userID, ChannelId: channelID}, plugin.AllowSystemMessages(), plugin.AllowBots(), plugin.OnlyBotDMs()) 466 467 assert.False(t, shouldProcessMessage) 468 }) 469 470 t.Run("should process the message", func(t *testing.T) { 471 channelID := "1" 472 api := setupAPI() 473 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 474 p.API = api 475 476 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{UserId: "1", Type: model.POST_HEADER_CHANGE, ChannelId: channelID}, 477 plugin.AllowSystemMessages(), plugin.FilterChannelIDs([]string{channelID}), plugin.AllowBots(), plugin.FilterUserIDs([]string{"1"})) 478 479 assert.True(t, shouldProcessMessage) 480 }) 481 482 t.Run("should process the message for plugin without a bot", func(t *testing.T) { 483 channelID := "1" 484 api := setupAPI() 485 api.On("KVGet", plugin.BotUserKey).Return(nil, nil) 486 p.API = api 487 488 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{UserId: "1", Type: model.POST_HEADER_CHANGE, ChannelId: channelID}, 489 plugin.AllowSystemMessages(), plugin.FilterChannelIDs([]string{channelID}), plugin.AllowBots(), plugin.FilterUserIDs([]string{"1"})) 490 491 assert.True(t, shouldProcessMessage) 492 }) 493 494 t.Run("should process the message when filter channel and filter users list is empty", func(t *testing.T) { 495 channelID := "1" 496 api := setupAPI() 497 channel := model.Channel{ 498 Name: "user1__" + expectedBotID, 499 Type: model.CHANNEL_DIRECT, 500 } 501 api.On("GetChannel", channelID).Return(&channel, nil) 502 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 503 p.API = api 504 505 shouldProcessMessage, _ := p.ShouldProcessMessage(&model.Post{UserId: "1", Type: model.POST_HEADER_CHANGE, ChannelId: channelID}, 506 plugin.AllowSystemMessages(), plugin.AllowBots()) 507 508 assert.True(t, shouldProcessMessage) 509 }) 510 511 t.Run("should not process the message which have from_webhook", func(t *testing.T) { 512 channelID := "1" 513 api := setupAPI() 514 api.On("GetChannel", channelID).Return(&model.Channel{Id: channelID, Type: model.CHANNEL_GROUP}, nil) 515 p.API = api 516 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 517 518 shouldProcessMessage, err := p.ShouldProcessMessage(&model.Post{ChannelId: channelID, Props: model.StringInterface{"from_webhook": "true"}}, plugin.AllowBots()) 519 520 assert.False(t, shouldProcessMessage) 521 assert.Nil(t, err) 522 }) 523 524 t.Run("should process the message which have from_webhook with allow webhook plugin", func(t *testing.T) { 525 channelID := "1" 526 api := setupAPI() 527 api.On("GetChannel", channelID).Return(&model.Channel{Id: channelID, Type: model.CHANNEL_GROUP}, nil) 528 p.API = api 529 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 530 531 shouldProcessMessage, err := p.ShouldProcessMessage(&model.Post{ChannelId: channelID, Props: model.StringInterface{"from_webhook": "true"}}, plugin.AllowBots(), plugin.AllowWebhook()) 532 assert.Nil(t, err) 533 534 assert.True(t, shouldProcessMessage) 535 }) 536 537 t.Run("should process the message where from_webhook is not set", func(t *testing.T) { 538 channelID := "1" 539 api := setupAPI() 540 api.On("GetChannel", channelID).Return(&model.Channel{Id: channelID, Type: model.CHANNEL_GROUP}, nil) 541 p.API = api 542 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 543 544 shouldProcessMessage, err := p.ShouldProcessMessage(&model.Post{ChannelId: channelID}, plugin.AllowBots()) 545 assert.Nil(t, err) 546 547 assert.True(t, shouldProcessMessage) 548 }) 549 550 t.Run("should process the message which have from_webhook false", func(t *testing.T) { 551 channelID := "1" 552 api := setupAPI() 553 api.On("GetChannel", channelID).Return(&model.Channel{Id: channelID, Type: model.CHANNEL_GROUP}, nil) 554 p.API = api 555 api.On("KVGet", plugin.BotUserKey).Return([]byte(expectedBotID), nil) 556 557 shouldProcessMessage, err := p.ShouldProcessMessage(&model.Post{ChannelId: channelID, Props: model.StringInterface{"from_webhook": "false"}}, plugin.AllowBots()) 558 assert.Nil(t, err) 559 560 assert.True(t, shouldProcessMessage) 561 }) 562 563 }