github.com/mattermost/mattermost-server/v5@v5.39.3/store/storetest/file_info_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 "fmt" 8 "sort" 9 "testing" 10 "time" 11 12 "github.com/mattermost/mattermost-server/v5/model" 13 "github.com/mattermost/mattermost-server/v5/store" 14 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestFileInfoStore(t *testing.T, ss store.Store) { 20 t.Run("FileInfoSaveGet", func(t *testing.T) { testFileInfoSaveGet(t, ss) }) 21 t.Run("FileInfoSaveGetByPath", func(t *testing.T) { testFileInfoSaveGetByPath(t, ss) }) 22 t.Run("FileInfoGetForPost", func(t *testing.T) { testFileInfoGetForPost(t, ss) }) 23 t.Run("FileInfoGetForUser", func(t *testing.T) { testFileInfoGetForUser(t, ss) }) 24 t.Run("FileInfoGetWithOptions", func(t *testing.T) { testFileInfoGetWithOptions(t, ss) }) 25 t.Run("FileInfoAttachToPost", func(t *testing.T) { testFileInfoAttachToPost(t, ss) }) 26 t.Run("FileInfoDeleteForPost", func(t *testing.T) { testFileInfoDeleteForPost(t, ss) }) 27 t.Run("FileInfoPermanentDelete", func(t *testing.T) { testFileInfoPermanentDelete(t, ss) }) 28 t.Run("FileInfoPermanentDeleteBatch", func(t *testing.T) { testFileInfoPermanentDeleteBatch(t, ss) }) 29 t.Run("FileInfoPermanentDeleteByUser", func(t *testing.T) { testFileInfoPermanentDeleteByUser(t, ss) }) 30 t.Run("GetFilesBatchForIndexing", func(t *testing.T) { testFileInfoStoreGetFilesBatchForIndexing(t, ss) }) 31 t.Run("CountAll", func(t *testing.T) { testFileInfoStoreCountAll(t, ss) }) 32 } 33 34 func testFileInfoSaveGet(t *testing.T, ss store.Store) { 35 info := &model.FileInfo{ 36 CreatorId: model.NewId(), 37 Path: "file.txt", 38 } 39 40 info, err := ss.FileInfo().Save(info) 41 require.NoError(t, err) 42 require.NotEqual(t, len(info.Id), 0) 43 44 defer func() { 45 ss.FileInfo().PermanentDelete(info.Id) 46 }() 47 48 rinfo, err := ss.FileInfo().Get(info.Id) 49 require.NoError(t, err) 50 require.Equal(t, info.Id, rinfo.Id) 51 52 info2, err := ss.FileInfo().Save(&model.FileInfo{ 53 CreatorId: model.NewId(), 54 Path: "file.txt", 55 DeleteAt: 123, 56 }) 57 require.NoError(t, err) 58 59 _, err = ss.FileInfo().Get(info2.Id) 60 assert.Error(t, err) 61 62 defer func() { 63 ss.FileInfo().PermanentDelete(info2.Id) 64 }() 65 } 66 67 func testFileInfoSaveGetByPath(t *testing.T, ss store.Store) { 68 info := &model.FileInfo{ 69 CreatorId: model.NewId(), 70 Path: fmt.Sprintf("%v/file.txt", model.NewId()), 71 } 72 73 info, err := ss.FileInfo().Save(info) 74 require.NoError(t, err) 75 assert.NotEqual(t, len(info.Id), 0) 76 defer func() { 77 ss.FileInfo().PermanentDelete(info.Id) 78 }() 79 80 rinfo, err := ss.FileInfo().GetByPath(info.Path) 81 require.NoError(t, err) 82 assert.Equal(t, info.Id, rinfo.Id) 83 84 info2, err := ss.FileInfo().Save(&model.FileInfo{ 85 CreatorId: model.NewId(), 86 Path: "file.txt", 87 DeleteAt: 123, 88 }) 89 require.NoError(t, err) 90 91 _, err = ss.FileInfo().GetByPath(info2.Id) 92 assert.Error(t, err) 93 94 defer func() { 95 ss.FileInfo().PermanentDelete(info2.Id) 96 }() 97 } 98 99 func testFileInfoGetForPost(t *testing.T, ss store.Store) { 100 userId := model.NewId() 101 postId := model.NewId() 102 103 infos := []*model.FileInfo{ 104 { 105 PostId: postId, 106 CreatorId: userId, 107 Path: "file.txt", 108 }, 109 { 110 PostId: postId, 111 CreatorId: userId, 112 Path: "file.txt", 113 }, 114 { 115 PostId: postId, 116 CreatorId: userId, 117 Path: "file.txt", 118 DeleteAt: 123, 119 }, 120 { 121 PostId: model.NewId(), 122 CreatorId: userId, 123 Path: "file.txt", 124 }, 125 } 126 127 for i, info := range infos { 128 newInfo, err := ss.FileInfo().Save(info) 129 require.NoError(t, err) 130 infos[i] = newInfo 131 defer func(id string) { 132 ss.FileInfo().PermanentDelete(id) 133 }(newInfo.Id) 134 } 135 136 testCases := []struct { 137 Name string 138 PostId string 139 ReadFromMaster bool 140 IncludeDeleted bool 141 AllowFromCache bool 142 ExpectedPosts int 143 }{ 144 { 145 Name: "Fetch from master, without deleted and without cache", 146 PostId: postId, 147 ReadFromMaster: true, 148 IncludeDeleted: false, 149 AllowFromCache: false, 150 ExpectedPosts: 2, 151 }, 152 { 153 Name: "Fetch from master, with deleted and without cache", 154 PostId: postId, 155 ReadFromMaster: true, 156 IncludeDeleted: true, 157 AllowFromCache: false, 158 ExpectedPosts: 3, 159 }, 160 { 161 Name: "Fetch from master, with deleted and with cache", 162 PostId: postId, 163 ReadFromMaster: true, 164 IncludeDeleted: true, 165 AllowFromCache: true, 166 ExpectedPosts: 3, 167 }, 168 { 169 Name: "Fetch from replica, without deleted and without cache", 170 PostId: postId, 171 ReadFromMaster: false, 172 IncludeDeleted: false, 173 AllowFromCache: false, 174 ExpectedPosts: 2, 175 }, 176 { 177 Name: "Fetch from replica, with deleted and without cache", 178 PostId: postId, 179 ReadFromMaster: false, 180 IncludeDeleted: true, 181 AllowFromCache: false, 182 ExpectedPosts: 3, 183 }, 184 { 185 Name: "Fetch from replica, with deleted and without cache", 186 PostId: postId, 187 ReadFromMaster: false, 188 IncludeDeleted: true, 189 AllowFromCache: true, 190 ExpectedPosts: 3, 191 }, 192 { 193 Name: "Fetch from replica, without deleted and with cache", 194 PostId: postId, 195 ReadFromMaster: true, 196 IncludeDeleted: false, 197 AllowFromCache: true, 198 ExpectedPosts: 2, 199 }, 200 } 201 202 for _, tc := range testCases { 203 t.Run(tc.Name, func(t *testing.T) { 204 postInfos, err := ss.FileInfo().GetForPost( 205 tc.PostId, 206 tc.ReadFromMaster, 207 tc.IncludeDeleted, 208 tc.AllowFromCache, 209 ) 210 require.NoError(t, err) 211 assert.Len(t, postInfos, tc.ExpectedPosts) 212 213 }) 214 } 215 } 216 217 func testFileInfoGetForUser(t *testing.T, ss store.Store) { 218 userId := model.NewId() 219 userId2 := model.NewId() 220 postId := model.NewId() 221 222 infos := []*model.FileInfo{ 223 { 224 PostId: postId, 225 CreatorId: userId, 226 Path: "file.txt", 227 }, 228 { 229 PostId: postId, 230 CreatorId: userId, 231 Path: "file.txt", 232 }, 233 { 234 PostId: postId, 235 CreatorId: userId, 236 Path: "file.txt", 237 }, 238 { 239 PostId: model.NewId(), 240 CreatorId: userId2, 241 Path: "file.txt", 242 }, 243 } 244 245 for i, info := range infos { 246 newInfo, err := ss.FileInfo().Save(info) 247 require.NoError(t, err) 248 infos[i] = newInfo 249 defer func(id string) { 250 ss.FileInfo().PermanentDelete(id) 251 }(newInfo.Id) 252 } 253 254 userPosts, err := ss.FileInfo().GetForUser(userId) 255 require.NoError(t, err) 256 assert.Len(t, userPosts, 3) 257 258 userPosts, err = ss.FileInfo().GetForUser(userId2) 259 require.NoError(t, err) 260 assert.Len(t, userPosts, 1) 261 } 262 263 func testFileInfoGetWithOptions(t *testing.T, ss store.Store) { 264 makePost := func(chId string, user string) *model.Post { 265 post := model.Post{} 266 post.ChannelId = chId 267 post.UserId = user 268 _, err := ss.Post().Save(&post) 269 require.NoError(t, err) 270 return &post 271 } 272 273 makeFile := func(post *model.Post, user string, createAt int64, idPrefix string) model.FileInfo { 274 id := model.NewId() 275 id = idPrefix + id[1:] // hacky way to get sortable Ids to confirm secondary Id sort works 276 fileInfo := model.FileInfo{ 277 Id: id, 278 CreatorId: user, 279 Path: "file.txt", 280 CreateAt: createAt, 281 } 282 if post.Id != "" { 283 fileInfo.PostId = post.Id 284 } 285 _, err := ss.FileInfo().Save(&fileInfo) 286 require.NoError(t, err) 287 return fileInfo 288 } 289 290 userId1 := model.NewId() 291 userId2 := model.NewId() 292 293 channelId1 := model.NewId() 294 channelId2 := model.NewId() 295 channelId3 := model.NewId() 296 297 post1_1 := makePost(channelId1, userId1) // post 1 by user 1 298 post1_2 := makePost(channelId3, userId1) // post 2 by user 1 299 post2_1 := makePost(channelId2, userId2) 300 post2_2 := makePost(channelId3, userId2) 301 302 epoch := time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC) 303 file1_1 := makeFile(post1_1, userId1, epoch.AddDate(0, 0, 1).Unix(), "a") // file 1 by user 1 304 file1_2 := makeFile(post1_2, userId1, epoch.AddDate(0, 0, 2).Unix(), "b") // file 2 by user 1 305 file1_3 := makeFile(&model.Post{}, userId1, epoch.AddDate(0, 0, 3).Unix(), "c") // file that is not attached to a post 306 file2_1 := makeFile(post2_1, userId2, epoch.AddDate(0, 0, 4).Unix(), "d") // file 2 by user 1 307 file2_2 := makeFile(post2_2, userId2, epoch.AddDate(0, 0, 5).Unix(), "e") 308 309 // delete a file 310 _, err := ss.FileInfo().DeleteForPost(file2_2.PostId) 311 require.NoError(t, err) 312 313 testCases := []struct { 314 Name string 315 Page, PerPage int 316 Opt *model.GetFileInfosOptions 317 ExpectedFileIds []string 318 }{ 319 { 320 Name: "Get files with nil option", 321 Page: 0, 322 PerPage: 10, 323 Opt: nil, 324 ExpectedFileIds: []string{file1_1.Id, file1_2.Id, file1_3.Id, file2_1.Id}, 325 }, 326 { 327 Name: "Get files including deleted", 328 Page: 0, 329 PerPage: 10, 330 Opt: &model.GetFileInfosOptions{IncludeDeleted: true}, 331 ExpectedFileIds: []string{file1_1.Id, file1_2.Id, file1_3.Id, file2_1.Id, file2_2.Id}, 332 }, 333 { 334 Name: "Get files including deleted filtered by channel", 335 Page: 0, 336 PerPage: 10, 337 Opt: &model.GetFileInfosOptions{ 338 IncludeDeleted: true, 339 ChannelIds: []string{channelId3}, 340 }, 341 ExpectedFileIds: []string{file1_2.Id, file2_2.Id}, 342 }, 343 { 344 Name: "Get files including deleted filtered by channel and user", 345 Page: 0, 346 PerPage: 10, 347 Opt: &model.GetFileInfosOptions{ 348 IncludeDeleted: true, 349 UserIds: []string{userId1}, 350 ChannelIds: []string{channelId3}, 351 }, 352 ExpectedFileIds: []string{file1_2.Id}, 353 }, 354 { 355 Name: "Get files including deleted sorted by created at", 356 Page: 0, 357 PerPage: 10, 358 Opt: &model.GetFileInfosOptions{ 359 IncludeDeleted: true, 360 SortBy: model.FILEINFO_SORT_BY_CREATED, 361 }, 362 ExpectedFileIds: []string{file1_1.Id, file1_2.Id, file1_3.Id, file2_1.Id, file2_2.Id}, 363 }, 364 { 365 Name: "Get files filtered by user ordered by created at descending", 366 Page: 0, 367 PerPage: 10, 368 Opt: &model.GetFileInfosOptions{ 369 UserIds: []string{userId1}, 370 SortBy: model.FILEINFO_SORT_BY_CREATED, 371 SortDescending: true, 372 }, 373 ExpectedFileIds: []string{file1_3.Id, file1_2.Id, file1_1.Id}, 374 }, 375 { 376 Name: "Get all files including deleted ordered by created descending 2nd page of 3 per page ", 377 Page: 1, 378 PerPage: 3, 379 Opt: &model.GetFileInfosOptions{ 380 IncludeDeleted: true, 381 SortBy: model.FILEINFO_SORT_BY_CREATED, 382 SortDescending: true, 383 }, 384 ExpectedFileIds: []string{file1_2.Id, file1_1.Id}, 385 }, 386 } 387 388 for _, tc := range testCases { 389 t.Run(tc.Name, func(t *testing.T) { 390 fileInfos, err := ss.FileInfo().GetWithOptions(tc.Page, tc.PerPage, tc.Opt) 391 require.NoError(t, err) 392 require.Len(t, fileInfos, len(tc.ExpectedFileIds)) 393 for i := range tc.ExpectedFileIds { 394 assert.Equal(t, tc.ExpectedFileIds[i], fileInfos[i].Id) 395 } 396 }) 397 } 398 } 399 400 type byFileInfoId []*model.FileInfo 401 402 func (a byFileInfoId) Len() int { return len(a) } 403 func (a byFileInfoId) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 404 func (a byFileInfoId) Less(i, j int) bool { return a[i].Id < a[j].Id } 405 406 func testFileInfoAttachToPost(t *testing.T, ss store.Store) { 407 t.Run("should attach files", func(t *testing.T) { 408 userId := model.NewId() 409 postId := model.NewId() 410 411 info1, err := ss.FileInfo().Save(&model.FileInfo{ 412 CreatorId: userId, 413 Path: "file.txt", 414 }) 415 require.NoError(t, err) 416 info2, err := ss.FileInfo().Save(&model.FileInfo{ 417 CreatorId: userId, 418 Path: "file2.txt", 419 }) 420 require.NoError(t, err) 421 422 require.Equal(t, "", info1.PostId) 423 require.Equal(t, "", info2.PostId) 424 425 err = ss.FileInfo().AttachToPost(info1.Id, postId, userId) 426 assert.NoError(t, err) 427 info1.PostId = postId 428 429 err = ss.FileInfo().AttachToPost(info2.Id, postId, userId) 430 assert.NoError(t, err) 431 info2.PostId = postId 432 433 data, err := ss.FileInfo().GetForPost(postId, true, false, false) 434 require.NoError(t, err) 435 436 expected := []*model.FileInfo{info1, info2} 437 sort.Sort(byFileInfoId(expected)) 438 sort.Sort(byFileInfoId(data)) 439 assert.EqualValues(t, expected, data) 440 }) 441 442 t.Run("should not attach files to multiple posts", func(t *testing.T) { 443 userId := model.NewId() 444 postId := model.NewId() 445 446 info, err := ss.FileInfo().Save(&model.FileInfo{ 447 CreatorId: userId, 448 Path: "file.txt", 449 }) 450 require.NoError(t, err) 451 452 require.Equal(t, "", info.PostId) 453 454 err = ss.FileInfo().AttachToPost(info.Id, model.NewId(), userId) 455 require.NoError(t, err) 456 457 err = ss.FileInfo().AttachToPost(info.Id, postId, userId) 458 require.Error(t, err) 459 }) 460 461 t.Run("should not attach files owned from a different user", func(t *testing.T) { 462 userId := model.NewId() 463 postId := model.NewId() 464 465 info, err := ss.FileInfo().Save(&model.FileInfo{ 466 CreatorId: model.NewId(), 467 Path: "file.txt", 468 }) 469 require.NoError(t, err) 470 471 require.Equal(t, "", info.PostId) 472 473 err = ss.FileInfo().AttachToPost(info.Id, postId, userId) 474 assert.Error(t, err) 475 }) 476 477 t.Run("should attach files uploaded by nouser", func(t *testing.T) { 478 postId := model.NewId() 479 480 info, err := ss.FileInfo().Save(&model.FileInfo{ 481 CreatorId: "nouser", 482 Path: "file.txt", 483 }) 484 require.NoError(t, err) 485 assert.Equal(t, "", info.PostId) 486 487 err = ss.FileInfo().AttachToPost(info.Id, postId, model.NewId()) 488 require.NoError(t, err) 489 490 data, err := ss.FileInfo().GetForPost(postId, true, false, false) 491 require.NoError(t, err) 492 info.PostId = postId 493 assert.EqualValues(t, []*model.FileInfo{info}, data) 494 }) 495 } 496 497 func testFileInfoDeleteForPost(t *testing.T, ss store.Store) { 498 userId := model.NewId() 499 postId := model.NewId() 500 501 infos := []*model.FileInfo{ 502 { 503 PostId: postId, 504 CreatorId: userId, 505 Path: "file.txt", 506 }, 507 { 508 PostId: postId, 509 CreatorId: userId, 510 Path: "file.txt", 511 }, 512 { 513 PostId: postId, 514 CreatorId: userId, 515 Path: "file.txt", 516 DeleteAt: 123, 517 }, 518 { 519 PostId: model.NewId(), 520 CreatorId: userId, 521 Path: "file.txt", 522 }, 523 } 524 525 for i, info := range infos { 526 newInfo, err := ss.FileInfo().Save(info) 527 require.NoError(t, err) 528 infos[i] = newInfo 529 defer func(id string) { 530 ss.FileInfo().PermanentDelete(id) 531 }(newInfo.Id) 532 } 533 534 _, err := ss.FileInfo().DeleteForPost(postId) 535 require.NoError(t, err) 536 537 infos, err = ss.FileInfo().GetForPost(postId, true, false, false) 538 require.NoError(t, err) 539 assert.Empty(t, infos) 540 } 541 542 func testFileInfoPermanentDelete(t *testing.T, ss store.Store) { 543 info, err := ss.FileInfo().Save(&model.FileInfo{ 544 PostId: model.NewId(), 545 CreatorId: model.NewId(), 546 Path: "file.txt", 547 }) 548 require.NoError(t, err) 549 550 err = ss.FileInfo().PermanentDelete(info.Id) 551 require.NoError(t, err) 552 } 553 554 func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) { 555 postId := model.NewId() 556 557 _, err := ss.FileInfo().Save(&model.FileInfo{ 558 PostId: postId, 559 CreatorId: model.NewId(), 560 Path: "file.txt", 561 CreateAt: 1000, 562 }) 563 require.NoError(t, err) 564 565 _, err = ss.FileInfo().Save(&model.FileInfo{ 566 PostId: postId, 567 CreatorId: model.NewId(), 568 Path: "file.txt", 569 CreateAt: 1200, 570 }) 571 require.NoError(t, err) 572 573 _, err = ss.FileInfo().Save(&model.FileInfo{ 574 PostId: postId, 575 CreatorId: model.NewId(), 576 Path: "file.txt", 577 CreateAt: 2000, 578 }) 579 require.NoError(t, err) 580 581 postFiles, err := ss.FileInfo().GetForPost(postId, true, false, false) 582 require.NoError(t, err) 583 assert.Len(t, postFiles, 3) 584 585 _, err = ss.FileInfo().PermanentDeleteBatch(1500, 1000) 586 require.NoError(t, err) 587 588 postFiles, err = ss.FileInfo().GetForPost(postId, true, false, false) 589 require.NoError(t, err) 590 assert.Len(t, postFiles, 1) 591 } 592 593 func testFileInfoPermanentDeleteByUser(t *testing.T, ss store.Store) { 594 userId := model.NewId() 595 postId := model.NewId() 596 597 _, err := ss.FileInfo().Save(&model.FileInfo{ 598 PostId: postId, 599 CreatorId: userId, 600 Path: "file.txt", 601 }) 602 require.NoError(t, err) 603 604 _, err = ss.FileInfo().PermanentDeleteByUser(userId) 605 require.NoError(t, err) 606 } 607 608 func testFileInfoStoreGetFilesBatchForIndexing(t *testing.T, ss store.Store) { 609 c1 := &model.Channel{} 610 c1.TeamId = model.NewId() 611 c1.DisplayName = "Channel1" 612 c1.Name = "zz" + model.NewId() + "b" 613 c1.Type = model.CHANNEL_OPEN 614 c1, _ = ss.Channel().Save(c1, -1) 615 616 c2 := &model.Channel{} 617 c2.TeamId = model.NewId() 618 c2.DisplayName = "Channel2" 619 c2.Name = "zz" + model.NewId() + "b" 620 c2.Type = model.CHANNEL_OPEN 621 c2, _ = ss.Channel().Save(c2, -1) 622 623 o1 := &model.Post{} 624 o1.ChannelId = c1.Id 625 o1.UserId = model.NewId() 626 o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA" 627 o1, err := ss.Post().Save(o1) 628 require.NoError(t, err) 629 f1, err := ss.FileInfo().Save(&model.FileInfo{ 630 PostId: o1.Id, 631 CreatorId: model.NewId(), 632 Path: "file1.txt", 633 }) 634 require.NoError(t, err) 635 defer func() { 636 ss.FileInfo().PermanentDelete(f1.Id) 637 }() 638 time.Sleep(1 * time.Millisecond) 639 640 o2 := &model.Post{} 641 o2.ChannelId = c2.Id 642 o2.UserId = model.NewId() 643 o2.Message = "zz" + model.NewId() + "CCCCCCCCC" 644 o2, err = ss.Post().Save(o2) 645 require.NoError(t, err) 646 647 f2, err := ss.FileInfo().Save(&model.FileInfo{ 648 PostId: o2.Id, 649 CreatorId: model.NewId(), 650 Path: "file2.txt", 651 }) 652 require.NoError(t, err) 653 defer func() { 654 ss.FileInfo().PermanentDelete(f2.Id) 655 }() 656 time.Sleep(1 * time.Millisecond) 657 658 o3 := &model.Post{} 659 o3.ChannelId = c1.Id 660 o3.UserId = model.NewId() 661 o3.ParentId = o1.Id 662 o3.RootId = o1.Id 663 o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ" 664 o3, err = ss.Post().Save(o3) 665 require.NoError(t, err) 666 667 f3, err := ss.FileInfo().Save(&model.FileInfo{ 668 PostId: o3.Id, 669 CreatorId: model.NewId(), 670 Path: "file3.txt", 671 }) 672 require.NoError(t, err) 673 defer func() { 674 ss.FileInfo().PermanentDelete(f3.Id) 675 }() 676 677 t.Run("get all files", func(t *testing.T) { 678 r, err := ss.FileInfo().GetFilesBatchForIndexing(f1.CreateAt, model.GetMillis()+100000, 100) 679 require.NoError(t, err) 680 require.Len(t, r, 3, "Expected 3 posts in results. Got %v", len(r)) 681 for _, f := range r { 682 if f.Id == f1.Id { 683 require.Equal(t, f.ChannelId, o1.ChannelId, "Unexpected channel ID") 684 require.Equal(t, f.Path, "file1.txt", "Unexpected filename") 685 } else if f.Id == f2.Id { 686 require.Equal(t, f.ChannelId, o2.ChannelId, "Unexpected channel ID") 687 require.Equal(t, f.Path, "file2.txt", "Unexpected filename") 688 } else if f.Id == f3.Id { 689 require.Equal(t, f.ChannelId, o3.ChannelId, "Unexpected channel ID") 690 require.Equal(t, f.Path, "file3.txt", "Unexpected filename") 691 } else { 692 require.Fail(t, "unexpected file returned") 693 } 694 } 695 }) 696 697 t.Run("get files after certain date", func(t *testing.T) { 698 r, err := ss.FileInfo().GetFilesBatchForIndexing(f1.CreateAt+1, model.GetMillis()+100000, 100) 699 require.NoError(t, err) 700 require.Len(t, r, 2, "Expected 2 posts in results. Got %v", len(r)) 701 for _, f := range r { 702 if f.Id == f2.Id { 703 require.Equal(t, f.ChannelId, o2.ChannelId, "Unexpected channel ID") 704 require.Equal(t, f.Path, "file2.txt", "Unexpected filename") 705 } else if f.Id == f3.Id { 706 require.Equal(t, f.ChannelId, o3.ChannelId, "Unexpected channel ID") 707 require.Equal(t, f.Path, "file3.txt", "Unexpected filename") 708 } else { 709 require.Fail(t, "unexpected file returned") 710 } 711 } 712 }) 713 } 714 715 func testFileInfoStoreCountAll(t *testing.T, ss store.Store) { 716 _, err := ss.FileInfo().PermanentDeleteBatch(model.GetMillis(), 100000) 717 require.NoError(t, err) 718 f1, err := ss.FileInfo().Save(&model.FileInfo{ 719 PostId: model.NewId(), 720 CreatorId: model.NewId(), 721 Path: "file1.txt", 722 }) 723 require.NoError(t, err) 724 725 _, err = ss.FileInfo().Save(&model.FileInfo{ 726 PostId: model.NewId(), 727 CreatorId: model.NewId(), 728 Path: "file2.txt", 729 }) 730 require.NoError(t, err) 731 _, err = ss.FileInfo().Save(&model.FileInfo{ 732 PostId: model.NewId(), 733 CreatorId: model.NewId(), 734 Path: "file3.txt", 735 }) 736 require.NoError(t, err) 737 738 count, err := ss.FileInfo().CountAll() 739 require.NoError(t, err) 740 require.Equal(t, int64(3), count) 741 742 _, err = ss.FileInfo().DeleteForPost(f1.PostId) 743 require.NoError(t, err) 744 count, err = ss.FileInfo().CountAll() 745 require.NoError(t, err) 746 require.Equal(t, int64(2), count) 747 }