github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/store/storetest/bot_store.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package storetest 5 6 import ( 7 "errors" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/mattermost/mattermost-server/v5/model" 13 "github.com/mattermost/mattermost-server/v5/store" 14 ) 15 16 func makeBotWithUser(t *testing.T, ss store.Store, bot *model.Bot) (*model.Bot, *model.User) { 17 user, err := ss.User().Save(model.UserFromBot(bot)) 18 require.NoError(t, err) 19 20 bot.UserId = user.Id 21 bot, nErr := ss.Bot().Save(bot) 22 require.NoError(t, nErr) 23 24 return bot, user 25 } 26 27 func TestBotStore(t *testing.T, ss store.Store, s SqlStore) { 28 t.Run("Get", func(t *testing.T) { testBotStoreGet(t, ss, s) }) 29 t.Run("GetAll", func(t *testing.T) { testBotStoreGetAll(t, ss, s) }) 30 t.Run("Save", func(t *testing.T) { testBotStoreSave(t, ss) }) 31 t.Run("Update", func(t *testing.T) { testBotStoreUpdate(t, ss) }) 32 t.Run("PermanentDelete", func(t *testing.T) { testBotStorePermanentDelete(t, ss) }) 33 } 34 35 func testBotStoreGet(t *testing.T, ss store.Store, s SqlStore) { 36 deletedBot, _ := makeBotWithUser(t, ss, &model.Bot{ 37 Username: "deleted_bot", 38 Description: "A deleted bot", 39 OwnerId: model.NewId(), 40 LastIconUpdate: model.GetMillis(), 41 }) 42 deletedBot.DeleteAt = 1 43 deletedBot, err := ss.Bot().Update(deletedBot) 44 require.NoError(t, err) 45 defer func() { require.NoError(t, ss.Bot().PermanentDelete(deletedBot.UserId)) }() 46 defer func() { require.NoError(t, ss.User().PermanentDelete(deletedBot.UserId)) }() 47 48 permanentlyDeletedBot, _ := makeBotWithUser(t, ss, &model.Bot{ 49 Username: "permanently_deleted_bot", 50 Description: "A permanently deleted bot", 51 OwnerId: model.NewId(), 52 LastIconUpdate: model.GetMillis(), 53 DeleteAt: 0, 54 }) 55 require.NoError(t, ss.Bot().PermanentDelete(permanentlyDeletedBot.UserId)) 56 defer func() { require.NoError(t, ss.User().PermanentDelete(permanentlyDeletedBot.UserId)) }() 57 58 b1, _ := makeBotWithUser(t, ss, &model.Bot{ 59 Username: "b1", 60 Description: "The first bot", 61 OwnerId: model.NewId(), 62 LastIconUpdate: model.GetMillis(), 63 }) 64 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b1.UserId)) }() 65 defer func() { require.NoError(t, ss.User().PermanentDelete(b1.UserId)) }() 66 67 b2, _ := makeBotWithUser(t, ss, &model.Bot{ 68 Username: "b2", 69 Description: "The second bot", 70 OwnerId: model.NewId(), 71 LastIconUpdate: 0, 72 }) 73 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b2.UserId)) }() 74 defer func() { require.NoError(t, ss.User().PermanentDelete(b2.UserId)) }() 75 76 // Artificially set b2.LastIconUpdate to NULL to verify handling of same. 77 _, sqlErr := s.GetMaster().Exec("UPDATE Bots SET LastIconUpdate = NULL WHERE UserId = '" + b2.UserId + "'") 78 require.NoError(t, sqlErr) 79 80 t.Run("get non-existent bot", func(t *testing.T) { 81 _, err := ss.Bot().Get("unknown", false) 82 require.Error(t, err) 83 var nfErr *store.ErrNotFound 84 require.True(t, errors.As(err, &nfErr)) 85 }) 86 87 t.Run("get deleted bot", func(t *testing.T) { 88 _, err := ss.Bot().Get(deletedBot.UserId, false) 89 require.Error(t, err) 90 var nfErr *store.ErrNotFound 91 require.True(t, errors.As(err, &nfErr)) 92 }) 93 94 t.Run("get deleted bot, include deleted", func(t *testing.T) { 95 bot, err := ss.Bot().Get(deletedBot.UserId, true) 96 require.NoError(t, err) 97 require.Equal(t, deletedBot, bot) 98 }) 99 100 t.Run("get permanently deleted bot", func(t *testing.T) { 101 _, err := ss.Bot().Get(permanentlyDeletedBot.UserId, false) 102 require.Error(t, err) 103 var nfErr *store.ErrNotFound 104 require.True(t, errors.As(err, &nfErr)) 105 }) 106 107 t.Run("get bot 1", func(t *testing.T) { 108 bot, err := ss.Bot().Get(b1.UserId, false) 109 require.NoError(t, err) 110 require.Equal(t, b1, bot) 111 }) 112 113 t.Run("get bot 2", func(t *testing.T) { 114 bot, err := ss.Bot().Get(b2.UserId, false) 115 require.NoError(t, err) 116 require.Equal(t, b2, bot) 117 }) 118 } 119 120 func testBotStoreGetAll(t *testing.T, ss store.Store, s SqlStore) { 121 OwnerId1 := model.NewId() 122 OwnerId2 := model.NewId() 123 124 deletedBot, _ := makeBotWithUser(t, ss, &model.Bot{ 125 Username: "deleted_bot", 126 Description: "A deleted bot", 127 OwnerId: OwnerId1, 128 LastIconUpdate: model.GetMillis(), 129 }) 130 deletedBot.DeleteAt = 1 131 deletedBot, err := ss.Bot().Update(deletedBot) 132 require.NoError(t, err) 133 defer func() { require.NoError(t, ss.Bot().PermanentDelete(deletedBot.UserId)) }() 134 defer func() { require.NoError(t, ss.User().PermanentDelete(deletedBot.UserId)) }() 135 136 permanentlyDeletedBot, _ := makeBotWithUser(t, ss, &model.Bot{ 137 Username: "permanently_deleted_bot", 138 Description: "A permanently deleted bot", 139 OwnerId: OwnerId1, 140 LastIconUpdate: model.GetMillis(), 141 DeleteAt: 0, 142 }) 143 require.NoError(t, ss.Bot().PermanentDelete(permanentlyDeletedBot.UserId)) 144 defer func() { require.NoError(t, ss.User().PermanentDelete(permanentlyDeletedBot.UserId)) }() 145 146 b1, _ := makeBotWithUser(t, ss, &model.Bot{ 147 Username: "b1", 148 Description: "The first bot", 149 OwnerId: OwnerId1, 150 LastIconUpdate: model.GetMillis(), 151 }) 152 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b1.UserId)) }() 153 defer func() { require.NoError(t, ss.User().PermanentDelete(b1.UserId)) }() 154 155 b2, _ := makeBotWithUser(t, ss, &model.Bot{ 156 Username: "b2", 157 Description: "The second bot", 158 OwnerId: OwnerId1, 159 LastIconUpdate: 0, 160 }) 161 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b2.UserId)) }() 162 defer func() { require.NoError(t, ss.User().PermanentDelete(b2.UserId)) }() 163 164 // Artificially set b2.LastIconUpdate to NULL to verify handling of same. 165 _, sqlErr := s.GetMaster().Exec("UPDATE Bots SET LastIconUpdate = NULL WHERE UserId = '" + b2.UserId + "'") 166 require.NoError(t, sqlErr) 167 168 t.Run("get original bots", func(t *testing.T) { 169 bot, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10}) 170 require.NoError(t, err) 171 require.Equal(t, []*model.Bot{ 172 b1, 173 b2, 174 }, bot) 175 }) 176 177 b3, _ := makeBotWithUser(t, ss, &model.Bot{ 178 Username: "b3", 179 Description: "The third bot", 180 OwnerId: OwnerId1, 181 }) 182 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b3.UserId)) }() 183 defer func() { require.NoError(t, ss.User().PermanentDelete(b3.UserId)) }() 184 185 b4, _ := makeBotWithUser(t, ss, &model.Bot{ 186 Username: "b4", 187 Description: "The fourth bot", 188 OwnerId: OwnerId2, 189 }) 190 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b4.UserId)) }() 191 defer func() { require.NoError(t, ss.User().PermanentDelete(b4.UserId)) }() 192 193 deletedUser := model.User{ 194 Email: MakeEmail(), 195 Username: model.NewId(), 196 } 197 _, err1 := ss.User().Save(&deletedUser) 198 require.NoError(t, err1, "couldn't save user") 199 200 deletedUser.DeleteAt = model.GetMillis() 201 _, err2 := ss.User().Update(&deletedUser, true) 202 require.NoError(t, err2, "couldn't delete user") 203 204 defer func() { require.NoError(t, ss.User().PermanentDelete(deletedUser.Id)) }() 205 ob5, _ := makeBotWithUser(t, ss, &model.Bot{ 206 Username: "ob5", 207 Description: "Orphaned bot 5", 208 OwnerId: deletedUser.Id, 209 }) 210 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b4.UserId)) }() 211 defer func() { require.NoError(t, ss.User().PermanentDelete(b4.UserId)) }() 212 213 t.Run("get newly created bot stoo", func(t *testing.T) { 214 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10}) 215 require.NoError(t, err) 216 require.Equal(t, []*model.Bot{ 217 b1, 218 b2, 219 b3, 220 b4, 221 ob5, 222 }, bots) 223 }) 224 225 t.Run("get orphaned", func(t *testing.T) { 226 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10, OnlyOrphaned: true}) 227 require.NoError(t, err) 228 require.Equal(t, []*model.Bot{ 229 ob5, 230 }, bots) 231 }) 232 233 t.Run("get page=0, per_page=2", func(t *testing.T) { 234 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 2}) 235 require.NoError(t, err) 236 require.Equal(t, []*model.Bot{ 237 b1, 238 b2, 239 }, bots) 240 }) 241 242 t.Run("get page=1, limit=2", func(t *testing.T) { 243 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 1, PerPage: 2}) 244 require.NoError(t, err) 245 require.Equal(t, []*model.Bot{ 246 b3, 247 b4, 248 }, bots) 249 }) 250 251 t.Run("get page=5, perpage=1000", func(t *testing.T) { 252 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 5, PerPage: 1000}) 253 require.NoError(t, err) 254 require.Equal(t, []*model.Bot{}, bots) 255 }) 256 257 t.Run("get offset=0, limit=2, include deleted", func(t *testing.T) { 258 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 2, IncludeDeleted: true}) 259 require.NoError(t, err) 260 require.Equal(t, []*model.Bot{ 261 deletedBot, 262 b1, 263 }, bots) 264 }) 265 266 t.Run("get offset=2, limit=2, include deleted", func(t *testing.T) { 267 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 1, PerPage: 2, IncludeDeleted: true}) 268 require.NoError(t, err) 269 require.Equal(t, []*model.Bot{ 270 b2, 271 b3, 272 }, bots) 273 }) 274 275 t.Run("get offset=0, limit=10, creator id 1", func(t *testing.T) { 276 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10, OwnerId: OwnerId1}) 277 require.NoError(t, err) 278 require.Equal(t, []*model.Bot{ 279 b1, 280 b2, 281 b3, 282 }, bots) 283 }) 284 285 t.Run("get offset=0, limit=10, creator id 2", func(t *testing.T) { 286 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10, OwnerId: OwnerId2}) 287 require.NoError(t, err) 288 require.Equal(t, []*model.Bot{ 289 b4, 290 }, bots) 291 }) 292 293 t.Run("get offset=0, limit=10, include deleted, creator id 1", func(t *testing.T) { 294 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10, IncludeDeleted: true, OwnerId: OwnerId1}) 295 require.NoError(t, err) 296 require.Equal(t, []*model.Bot{ 297 deletedBot, 298 b1, 299 b2, 300 b3, 301 }, bots) 302 }) 303 304 t.Run("get offset=0, limit=10, include deleted, creator id 2", func(t *testing.T) { 305 bots, err := ss.Bot().GetAll(&model.BotGetOptions{Page: 0, PerPage: 10, IncludeDeleted: true, OwnerId: OwnerId2}) 306 require.NoError(t, err) 307 require.Equal(t, []*model.Bot{ 308 b4, 309 }, bots) 310 }) 311 } 312 313 func testBotStoreSave(t *testing.T, ss store.Store) { 314 t.Run("invalid bot", func(t *testing.T) { 315 bot := &model.Bot{ 316 UserId: model.NewId(), 317 Username: "invalid bot", 318 Description: "description", 319 } 320 321 _, err := ss.Bot().Save(bot) 322 require.Error(t, err) 323 var appErr *model.AppError 324 require.True(t, errors.As(err, &appErr)) 325 // require.Equal(t, "model.bot.is_valid.username.app_error", err.Id) 326 }) 327 328 t.Run("normal bot", func(t *testing.T) { 329 bot := &model.Bot{ 330 Username: "normal_bot", 331 Description: "description", 332 OwnerId: model.NewId(), 333 } 334 335 user, err := ss.User().Save(model.UserFromBot(bot)) 336 require.NoError(t, err) 337 defer func() { require.NoError(t, ss.User().PermanentDelete(user.Id)) }() 338 bot.UserId = user.Id 339 340 returnedNewBot, nErr := ss.Bot().Save(bot) 341 require.NoError(t, nErr) 342 defer func() { require.NoError(t, ss.Bot().PermanentDelete(bot.UserId)) }() 343 344 // Verify the returned bot matches the saved bot, modulo expected changes 345 require.NotEqual(t, 0, returnedNewBot.CreateAt) 346 require.NotEqual(t, 0, returnedNewBot.UpdateAt) 347 require.Equal(t, returnedNewBot.CreateAt, returnedNewBot.UpdateAt) 348 bot.UserId = returnedNewBot.UserId 349 bot.CreateAt = returnedNewBot.CreateAt 350 bot.UpdateAt = returnedNewBot.UpdateAt 351 bot.DeleteAt = 0 352 require.Equal(t, bot, returnedNewBot) 353 354 // Verify the actual bot in the database matches the saved bot. 355 actualNewBot, nErr := ss.Bot().Get(bot.UserId, false) 356 require.NoError(t, nErr) 357 require.Equal(t, bot, actualNewBot) 358 }) 359 } 360 361 func testBotStoreUpdate(t *testing.T, ss store.Store) { 362 t.Run("invalid bot should fail to update", func(t *testing.T) { 363 existingBot, _ := makeBotWithUser(t, ss, &model.Bot{ 364 Username: "existing_bot", 365 OwnerId: model.NewId(), 366 }) 367 defer func() { require.NoError(t, ss.Bot().PermanentDelete(existingBot.UserId)) }() 368 defer func() { require.NoError(t, ss.User().PermanentDelete(existingBot.UserId)) }() 369 370 bot := existingBot.Clone() 371 bot.Username = "invalid username" 372 _, err := ss.Bot().Update(bot) 373 require.Error(t, err) 374 var appErr *model.AppError 375 require.True(t, errors.As(err, &appErr)) 376 require.Equal(t, "model.bot.is_valid.username.app_error", appErr.Id) 377 }) 378 379 t.Run("existing bot should update", func(t *testing.T) { 380 existingBot, _ := makeBotWithUser(t, ss, &model.Bot{ 381 Username: "existing_bot", 382 OwnerId: model.NewId(), 383 }) 384 defer func() { require.NoError(t, ss.Bot().PermanentDelete(existingBot.UserId)) }() 385 defer func() { require.NoError(t, ss.User().PermanentDelete(existingBot.UserId)) }() 386 387 bot := existingBot.Clone() 388 bot.OwnerId = model.NewId() 389 bot.Description = "updated description" 390 bot.CreateAt = 999999 // Ignored 391 bot.UpdateAt = 999999 // Ignored 392 bot.LastIconUpdate = 100000 // Allowed 393 bot.DeleteAt = 100000 // Allowed 394 395 returnedBot, err := ss.Bot().Update(bot) 396 require.NoError(t, err) 397 398 // Verify the returned bot matches the updated bot, modulo expected timestamp changes 399 require.Equal(t, existingBot.CreateAt, returnedBot.CreateAt) 400 require.NotEqual(t, bot.UpdateAt, returnedBot.UpdateAt, "update should have advanced UpdateAt") 401 require.True(t, returnedBot.UpdateAt > bot.UpdateAt, "update should have advanced UpdateAt") 402 require.NotEqual(t, 99999, returnedBot.UpdateAt, "should have ignored user-provided UpdateAt") 403 require.Equal(t, bot.LastIconUpdate, returnedBot.LastIconUpdate, "should have marked icon as updated") 404 require.Equal(t, bot.DeleteAt, returnedBot.DeleteAt, "should have marked bot as deleted") 405 bot.CreateAt = returnedBot.CreateAt 406 bot.UpdateAt = returnedBot.UpdateAt 407 408 // Verify the actual (now deleted) bot in the database 409 actualBot, err := ss.Bot().Get(bot.UserId, true) 410 require.NoError(t, err) 411 require.Equal(t, bot, actualBot) 412 }) 413 414 t.Run("deleted bot should update, restoring", func(t *testing.T) { 415 existingBot, _ := makeBotWithUser(t, ss, &model.Bot{ 416 Username: "existing_bot", 417 OwnerId: model.NewId(), 418 }) 419 defer func() { require.NoError(t, ss.Bot().PermanentDelete(existingBot.UserId)) }() 420 defer func() { require.NoError(t, ss.User().PermanentDelete(existingBot.UserId)) }() 421 422 existingBot.DeleteAt = 100000 423 existingBot, err := ss.Bot().Update(existingBot) 424 require.NoError(t, err) 425 426 bot := existingBot.Clone() 427 bot.DeleteAt = 0 428 429 returnedBot, err := ss.Bot().Update(bot) 430 require.NoError(t, err) 431 432 // Verify the returned bot matches the updated bot, modulo expected timestamp changes 433 require.EqualValues(t, 0, returnedBot.DeleteAt) 434 bot.UpdateAt = returnedBot.UpdateAt 435 436 // Verify the actual bot in the database 437 actualBot, err := ss.Bot().Get(bot.UserId, false) 438 require.NoError(t, err) 439 require.Equal(t, bot, actualBot) 440 }) 441 } 442 443 func testBotStorePermanentDelete(t *testing.T, ss store.Store) { 444 b1, _ := makeBotWithUser(t, ss, &model.Bot{ 445 Username: "b1", 446 OwnerId: model.NewId(), 447 }) 448 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b1.UserId)) }() 449 defer func() { require.NoError(t, ss.User().PermanentDelete(b1.UserId)) }() 450 451 b2, _ := makeBotWithUser(t, ss, &model.Bot{ 452 Username: "b2", 453 OwnerId: model.NewId(), 454 }) 455 defer func() { require.NoError(t, ss.Bot().PermanentDelete(b2.UserId)) }() 456 defer func() { require.NoError(t, ss.User().PermanentDelete(b2.UserId)) }() 457 458 t.Run("permanently delete a non-existent bot", func(t *testing.T) { 459 err := ss.Bot().PermanentDelete("unknown") 460 require.NoError(t, err) 461 }) 462 463 t.Run("permanently delete bot", func(t *testing.T) { 464 err := ss.Bot().PermanentDelete(b1.UserId) 465 require.NoError(t, err) 466 467 _, err = ss.Bot().Get(b1.UserId, false) 468 require.Error(t, err) 469 var nfErr *store.ErrNotFound 470 require.True(t, errors.As(err, &nfErr)) 471 }) 472 }