github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/models/file_test.go (about) 1 package model 2 3 import ( 4 "errors" 5 "testing" 6 "time" 7 8 "github.com/DATA-DOG/go-sqlmock" 9 "github.com/jinzhu/gorm" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestFile_Create(t *testing.T) { 14 asserts := assert.New(t) 15 file := File{ 16 Name: "123", 17 } 18 19 // 无法插入文件记录 20 { 21 mock.ExpectBegin() 22 mock.ExpectExec("INSERT(.+)").WillReturnError(errors.New("error")) 23 mock.ExpectRollback() 24 err := file.Create() 25 asserts.Error(err) 26 asserts.NoError(mock.ExpectationsWereMet()) 27 } 28 29 // 无法更新用户容量 30 { 31 mock.ExpectBegin() 32 mock.ExpectExec("INSERT(.+)").WillReturnResult(sqlmock.NewResult(5, 1)) 33 mock.ExpectExec("UPDATE(.+)").WillReturnError(errors.New("error")) 34 mock.ExpectRollback() 35 err := file.Create() 36 asserts.Error(err) 37 asserts.NoError(mock.ExpectationsWereMet()) 38 } 39 40 // 成功 41 { 42 mock.ExpectBegin() 43 mock.ExpectExec("INSERT(.+)").WillReturnResult(sqlmock.NewResult(5, 1)) 44 mock.ExpectExec("UPDATE(.+)storage(.+)").WillReturnResult(sqlmock.NewResult(0, 1)) 45 mock.ExpectCommit() 46 err := file.Create() 47 asserts.NoError(err) 48 asserts.Equal(uint(5), file.ID) 49 asserts.NoError(mock.ExpectationsWereMet()) 50 } 51 } 52 53 func TestFile_AfterFind(t *testing.T) { 54 a := assert.New(t) 55 56 // metadata not empty 57 { 58 file := File{ 59 Name: "123", 60 Metadata: "{\"name\":\"123\"}", 61 } 62 63 a.NoError(file.AfterFind()) 64 a.Equal("123", file.MetadataSerialized["name"]) 65 } 66 67 // metadata empty 68 { 69 file := File{ 70 Name: "123", 71 Metadata: "", 72 } 73 a.Nil(file.MetadataSerialized) 74 a.NoError(file.AfterFind()) 75 a.NotNil(file.MetadataSerialized) 76 } 77 } 78 79 func TestFile_BeforeSave(t *testing.T) { 80 a := assert.New(t) 81 82 // metadata not empty 83 { 84 file := File{ 85 Name: "123", 86 MetadataSerialized: map[string]string{ 87 "name": "123", 88 }, 89 } 90 91 a.NoError(file.BeforeSave()) 92 a.Equal("{\"name\":\"123\"}", file.Metadata) 93 } 94 95 // metadata empty 96 { 97 file := File{ 98 Name: "123", 99 } 100 a.NoError(file.BeforeSave()) 101 a.Equal("", file.Metadata) 102 } 103 } 104 105 func TestFolder_GetChildFile(t *testing.T) { 106 asserts := assert.New(t) 107 folder := Folder{Model: gorm.Model{ID: 1}, Name: "/"} 108 // 存在 109 { 110 mock.ExpectQuery("SELECT(.+)"). 111 WithArgs(1, "1.txt"). 112 WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "1.txt")) 113 file, err := folder.GetChildFile("1.txt") 114 asserts.NoError(mock.ExpectationsWereMet()) 115 asserts.NoError(err) 116 asserts.Equal("1.txt", file.Name) 117 asserts.Equal("/", file.Position) 118 } 119 120 // 不存在 121 { 122 mock.ExpectQuery("SELECT(.+)"). 123 WithArgs(1, "1.txt"). 124 WillReturnRows(sqlmock.NewRows([]string{"id", "name"})) 125 _, err := folder.GetChildFile("1.txt") 126 asserts.NoError(mock.ExpectationsWereMet()) 127 asserts.Error(err) 128 } 129 } 130 131 func TestFolder_GetChildFiles(t *testing.T) { 132 asserts := assert.New(t) 133 folder := &Folder{ 134 Model: gorm.Model{ 135 ID: 1, 136 }, 137 Position: "/123", 138 Name: "456", 139 } 140 141 // 找不到 142 mock.ExpectQuery("SELECT(.+)folder_id(.+)").WithArgs(1).WillReturnError(errors.New("error")) 143 files, err := folder.GetChildFiles() 144 asserts.Error(err) 145 asserts.Len(files, 0) 146 asserts.NoError(mock.ExpectationsWereMet()) 147 148 // 找到了 149 mock.ExpectQuery("SELECT(.+)folder_id(.+)").WithArgs(1).WillReturnRows(sqlmock.NewRows([]string{"name", "id"}).AddRow("1.txt", 1).AddRow("2.txt", 2)) 150 files, err = folder.GetChildFiles() 151 asserts.NoError(err) 152 asserts.Len(files, 2) 153 asserts.Equal("/123/456", files[0].Position) 154 asserts.NoError(mock.ExpectationsWereMet()) 155 156 } 157 158 func TestGetFilesByIDs(t *testing.T) { 159 asserts := assert.New(t) 160 161 // 出错 162 { 163 mock.ExpectQuery("SELECT(.+)"). 164 WithArgs(1, 2, 3, 1). 165 WillReturnError(errors.New("error")) 166 folders, err := GetFilesByIDs([]uint{1, 2, 3}, 1) 167 asserts.NoError(mock.ExpectationsWereMet()) 168 asserts.Error(err) 169 asserts.Len(folders, 0) 170 } 171 172 // 部分找到 173 { 174 mock.ExpectQuery("SELECT(.+)"). 175 WithArgs(1, 2, 3, 1). 176 WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "1")) 177 folders, err := GetFilesByIDs([]uint{1, 2, 3}, 1) 178 asserts.NoError(mock.ExpectationsWereMet()) 179 asserts.NoError(err) 180 asserts.Len(folders, 1) 181 } 182 183 // 忽略UID查找 184 { 185 mock.ExpectQuery("SELECT(.+)"). 186 WithArgs(1, 2, 3). 187 WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "1")) 188 folders, err := GetFilesByIDs([]uint{1, 2, 3}, 0) 189 asserts.NoError(mock.ExpectationsWereMet()) 190 asserts.NoError(err) 191 asserts.Len(folders, 1) 192 } 193 } 194 195 func TestGetChildFilesOfFolders(t *testing.T) { 196 asserts := assert.New(t) 197 testFolder := []Folder{ 198 Folder{ 199 Model: gorm.Model{ID: 3}, 200 }, 201 Folder{ 202 Model: gorm.Model{ID: 4}, 203 }, Folder{ 204 Model: gorm.Model{ID: 5}, 205 }, 206 } 207 208 // 出错 209 { 210 mock.ExpectQuery("SELECT(.+)folder_id").WithArgs(3, 4, 5).WillReturnError(errors.New("not found")) 211 files, err := GetChildFilesOfFolders(&testFolder) 212 asserts.Error(err) 213 asserts.Len(files, 0) 214 asserts.NoError(mock.ExpectationsWereMet()) 215 } 216 217 // 找到2个 218 { 219 mock.ExpectQuery("SELECT(.+)folder_id"). 220 WithArgs(3, 4, 5). 221 WillReturnRows(sqlmock.NewRows([]string{"id", "name"}). 222 AddRow(3, "3"). 223 AddRow(4, "4"), 224 ) 225 files, err := GetChildFilesOfFolders(&testFolder) 226 asserts.NoError(err) 227 asserts.Len(files, 2) 228 asserts.NoError(mock.ExpectationsWereMet()) 229 } 230 231 // 全部找到 232 { 233 mock.ExpectQuery("SELECT(.+)folder_id"). 234 WithArgs(3, 4, 5). 235 WillReturnRows(sqlmock.NewRows([]string{"id", "name"}). 236 AddRow(3, "3"). 237 AddRow(4, "4"). 238 AddRow(5, "5"), 239 ) 240 files, err := GetChildFilesOfFolders(&testFolder) 241 asserts.NoError(err) 242 asserts.Len(files, 3) 243 asserts.NoError(mock.ExpectationsWereMet()) 244 } 245 } 246 247 func TestGetUploadPlaceholderFiles(t *testing.T) { 248 a := assert.New(t) 249 250 mock.ExpectQuery("SELECT(.+)upload_session_id(.+)"). 251 WithArgs(1). 252 WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "1")) 253 files := GetUploadPlaceholderFiles(1) 254 a.NoError(mock.ExpectationsWereMet()) 255 a.Len(files, 1) 256 } 257 258 func TestFile_GetPolicy(t *testing.T) { 259 asserts := assert.New(t) 260 261 // 空策略 262 { 263 file := File{ 264 PolicyID: 23, 265 } 266 mock.ExpectQuery("SELECT(.+)policies(.+)"). 267 WillReturnRows( 268 sqlmock.NewRows([]string{"id", "name"}). 269 AddRow(23, "name"), 270 ) 271 file.GetPolicy() 272 asserts.NoError(mock.ExpectationsWereMet()) 273 asserts.Equal(uint(23), file.Policy.ID) 274 } 275 276 // 非空策略 277 { 278 file := File{ 279 PolicyID: 23, 280 Policy: Policy{Model: gorm.Model{ID: 24}}, 281 } 282 file.GetPolicy() 283 asserts.NoError(mock.ExpectationsWereMet()) 284 asserts.Equal(uint(24), file.Policy.ID) 285 } 286 } 287 288 func TestRemoveFilesWithSoftLinks_EmptyArg(t *testing.T) { 289 asserts := assert.New(t) 290 // 传入空 291 { 292 mock.ExpectQuery("SELECT(.+)files(.+)") 293 file, err := RemoveFilesWithSoftLinks([]File{}) 294 asserts.Error(mock.ExpectationsWereMet()) 295 asserts.NoError(err) 296 asserts.Equal(len(file), 0) 297 DB.Find(&File{}) 298 } 299 } 300 301 func TestRemoveFilesWithSoftLinks(t *testing.T) { 302 asserts := assert.New(t) 303 files := []File{ 304 File{ 305 Model: gorm.Model{ID: 1}, 306 SourceName: "1.txt", 307 PolicyID: 23, 308 }, 309 File{ 310 Model: gorm.Model{ID: 2}, 311 SourceName: "2.txt", 312 PolicyID: 24, 313 }, 314 } 315 316 // 传入空文件列表 317 { 318 file, err := RemoveFilesWithSoftLinks([]File{}) 319 asserts.NoError(err) 320 asserts.Empty(file) 321 } 322 323 // 全都没有 324 { 325 mock.ExpectQuery("SELECT(.+)files(.+)"). 326 WithArgs("1.txt", 23, 1). 327 WillReturnRows(sqlmock.NewRows([]string{"id", "policy_id", "source_name"})) 328 mock.ExpectQuery("SELECT(.+)files(.+)"). 329 WithArgs("2.txt", 24, 2). 330 WillReturnRows(sqlmock.NewRows([]string{"id", "policy_id", "source_name"})) 331 file, err := RemoveFilesWithSoftLinks(files) 332 asserts.NoError(mock.ExpectationsWereMet()) 333 asserts.NoError(err) 334 asserts.Equal(files, file) 335 } 336 337 // 第二个是软链 338 { 339 mock.ExpectQuery("SELECT(.+)files(.+)"). 340 WithArgs("1.txt", 23, 1). 341 WillReturnRows(sqlmock.NewRows([]string{"id", "policy_id", "source_name"})) 342 mock.ExpectQuery("SELECT(.+)files(.+)"). 343 WithArgs("2.txt", 24, 2). 344 WillReturnRows( 345 sqlmock.NewRows([]string{"id", "policy_id", "source_name"}). 346 AddRow(3, 24, "2.txt"), 347 ) 348 file, err := RemoveFilesWithSoftLinks(files) 349 asserts.NoError(mock.ExpectationsWereMet()) 350 asserts.NoError(err) 351 asserts.Equal(files[:1], file) 352 } 353 354 // 第一个是软链 355 { 356 mock.ExpectQuery("SELECT(.+)files(.+)"). 357 WithArgs("1.txt", 23, 1). 358 WillReturnRows( 359 sqlmock.NewRows([]string{"id", "policy_id", "source_name"}). 360 AddRow(3, 23, "1.txt"), 361 ) 362 mock.ExpectQuery("SELECT(.+)files(.+)"). 363 WithArgs("2.txt", 24, 2). 364 WillReturnRows(sqlmock.NewRows([]string{"id", "policy_id", "source_name"})) 365 file, err := RemoveFilesWithSoftLinks(files) 366 asserts.NoError(mock.ExpectationsWereMet()) 367 asserts.NoError(err) 368 asserts.Equal(files[1:], file) 369 } 370 // 全部是软链 371 { 372 mock.ExpectQuery("SELECT(.+)files(.+)"). 373 WithArgs("1.txt", 23, 1). 374 WillReturnRows( 375 sqlmock.NewRows([]string{"id", "policy_id", "source_name"}). 376 AddRow(3, 23, "1.txt"), 377 ) 378 mock.ExpectQuery("SELECT(.+)files(.+)"). 379 WithArgs("2.txt", 24, 2). 380 WillReturnRows( 381 sqlmock.NewRows([]string{"id", "policy_id", "source_name"}). 382 AddRow(3, 24, "2.txt"), 383 ) 384 file, err := RemoveFilesWithSoftLinks(files) 385 asserts.NoError(mock.ExpectationsWereMet()) 386 asserts.NoError(err) 387 asserts.Len(file, 0) 388 } 389 } 390 391 func TestDeleteFiles(t *testing.T) { 392 a := assert.New(t) 393 394 // uid 不一致 395 { 396 err := DeleteFiles([]*File{{UserID: 2}}, 1) 397 a.Contains("user id not consistent", err.Error()) 398 } 399 400 // 删除失败 401 { 402 mock.ExpectBegin() 403 mock.ExpectExec("DELETE(.+)"). 404 WillReturnError(errors.New("error")) 405 mock.ExpectRollback() 406 err := DeleteFiles([]*File{{UserID: 1}}, 1) 407 a.NoError(mock.ExpectationsWereMet()) 408 a.Error(err) 409 } 410 411 // 无法变更用户容量 412 { 413 mock.ExpectBegin() 414 mock.ExpectExec("DELETE(.+)"). 415 WillReturnResult(sqlmock.NewResult(1, 1)) 416 mock.ExpectExec("UPDATE(.+)storage(.+)").WillReturnError(errors.New("error")) 417 mock.ExpectRollback() 418 err := DeleteFiles([]*File{{UserID: 1}}, 1) 419 a.NoError(mock.ExpectationsWereMet()) 420 a.Error(err) 421 } 422 423 // 文件脏读 424 { 425 mock.ExpectBegin() 426 mock.ExpectExec("DELETE(.+)"). 427 WillReturnResult(sqlmock.NewResult(1, 0)) 428 mock.ExpectRollback() 429 err := DeleteFiles([]*File{{Size: 1, UserID: 1}, {Size: 2, UserID: 1}}, 1) 430 a.NoError(mock.ExpectationsWereMet()) 431 a.Error(err) 432 a.Contains("file size is dirty", err.Error()) 433 } 434 435 // 成功 436 { 437 mock.ExpectBegin() 438 mock.ExpectExec("DELETE(.+)"). 439 WillReturnResult(sqlmock.NewResult(2, 1)) 440 mock.ExpectExec("DELETE(.+)"). 441 WillReturnResult(sqlmock.NewResult(2, 1)) 442 mock.ExpectExec("UPDATE(.+)storage(.+)").WithArgs(uint64(3), sqlmock.AnyArg(), uint(1)).WillReturnResult(sqlmock.NewResult(1, 1)) 443 mock.ExpectCommit() 444 err := DeleteFiles([]*File{{Size: 1, UserID: 1}, {Size: 2, UserID: 1}}, 1) 445 a.NoError(mock.ExpectationsWereMet()) 446 a.NoError(err) 447 } 448 449 // 成功, 关联用户不存在 450 { 451 mock.ExpectBegin() 452 mock.ExpectExec("DELETE(.+)"). 453 WillReturnResult(sqlmock.NewResult(2, 1)) 454 mock.ExpectExec("DELETE(.+)"). 455 WillReturnResult(sqlmock.NewResult(2, 1)) 456 mock.ExpectCommit() 457 err := DeleteFiles([]*File{{Size: 1, UserID: 1}, {Size: 2, UserID: 1}}, 0) 458 a.NoError(mock.ExpectationsWereMet()) 459 a.NoError(err) 460 } 461 } 462 463 func TestGetFilesByParentIDs(t *testing.T) { 464 asserts := assert.New(t) 465 466 mock.ExpectQuery("SELECT(.+)"). 467 WithArgs(1, 4, 5, 6). 468 WillReturnRows( 469 sqlmock.NewRows([]string{"id", "name"}). 470 AddRow(4, "4.txt"). 471 AddRow(5, "5.txt"). 472 AddRow(6, "6.txt"), 473 ) 474 files, err := GetFilesByParentIDs([]uint{4, 5, 6}, 1) 475 asserts.NoError(err) 476 asserts.NoError(mock.ExpectationsWereMet()) 477 asserts.Len(files, 3) 478 } 479 480 func TestGetFilesByUploadSession(t *testing.T) { 481 a := assert.New(t) 482 483 mock.ExpectQuery("SELECT(.+)"). 484 WithArgs(1, "sessionID"). 485 WillReturnRows( 486 sqlmock.NewRows([]string{"id", "name"}).AddRow(4, "4.txt")) 487 files, err := GetFilesByUploadSession("sessionID", 1) 488 a.NoError(err) 489 a.NoError(mock.ExpectationsWereMet()) 490 a.Equal("4.txt", files.Name) 491 } 492 493 func TestFile_Updates(t *testing.T) { 494 asserts := assert.New(t) 495 file := File{Model: gorm.Model{ID: 1}} 496 497 // rename 498 { 499 // not reset thumb 500 { 501 file := File{Model: gorm.Model{ID: 1}} 502 mock.ExpectBegin() 503 mock.ExpectExec("UPDATE(.+)files(.+)SET(.+)").WithArgs("", "newName", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1)) 504 mock.ExpectCommit() 505 err := file.Rename("newName") 506 asserts.NoError(mock.ExpectationsWereMet()) 507 asserts.NoError(err) 508 } 509 510 // thumb not available, rename base name only 511 { 512 file := File{Model: gorm.Model{ID: 1}, Name: "1.txt", MetadataSerialized: map[string]string{ 513 ThumbStatusMetadataKey: ThumbStatusNotAvailable, 514 }, 515 Metadata: "{}"} 516 mock.ExpectBegin() 517 mock.ExpectExec("UPDATE(.+)files(.+)SET(.+)").WithArgs("{}", "newName.txt", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1)) 518 mock.ExpectCommit() 519 err := file.Rename("newName.txt") 520 asserts.NoError(mock.ExpectationsWereMet()) 521 asserts.NoError(err) 522 asserts.Equal(ThumbStatusNotAvailable, file.MetadataSerialized[ThumbStatusMetadataKey]) 523 } 524 525 // thumb not available, rename base name only 526 { 527 file := File{Model: gorm.Model{ID: 1}, Name: "1.txt", MetadataSerialized: map[string]string{ 528 ThumbStatusMetadataKey: ThumbStatusNotAvailable, 529 }} 530 mock.ExpectBegin() 531 mock.ExpectExec("UPDATE(.+)files(.+)SET(.+)").WithArgs("{}", "newName.jpg", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1)) 532 mock.ExpectCommit() 533 err := file.Rename("newName.jpg") 534 asserts.NoError(mock.ExpectationsWereMet()) 535 asserts.NoError(err) 536 asserts.Empty(file.MetadataSerialized[ThumbStatusMetadataKey]) 537 } 538 } 539 540 // UpdatePicInfo 541 { 542 mock.ExpectBegin() 543 mock.ExpectExec("UPDATE(.+)").WithArgs("1,1", 1).WillReturnResult(sqlmock.NewResult(1, 1)) 544 mock.ExpectCommit() 545 err := file.UpdatePicInfo("1,1") 546 asserts.NoError(mock.ExpectationsWereMet()) 547 asserts.NoError(err) 548 } 549 550 // UpdateSourceName 551 { 552 mock.ExpectBegin() 553 mock.ExpectExec("UPDATE(.+)").WithArgs("", "newName", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1)) 554 mock.ExpectCommit() 555 err := file.UpdateSourceName("newName") 556 asserts.NoError(mock.ExpectationsWereMet()) 557 asserts.NoError(err) 558 } 559 } 560 561 func TestFile_UpdateSize(t *testing.T) { 562 a := assert.New(t) 563 564 // 增加成功 565 { 566 file := File{Size: 10} 567 mock.ExpectBegin() 568 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 11, sqlmock.AnyArg(), 10).WillReturnResult(sqlmock.NewResult(1, 1)) 569 mock.ExpectExec("UPDATE(.+)storage(.+)+(.+)").WithArgs(uint64(1), sqlmock.AnyArg()).WillReturnResult(sqlmock.NewResult(1, 1)) 570 mock.ExpectCommit() 571 572 a.NoError(file.UpdateSize(11)) 573 a.NoError(mock.ExpectationsWereMet()) 574 } 575 576 // 减少成功 577 { 578 file := File{Size: 10} 579 mock.ExpectBegin() 580 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 8, sqlmock.AnyArg(), 10).WillReturnResult(sqlmock.NewResult(1, 1)) 581 mock.ExpectExec("UPDATE(.+)storage(.+)-(.+)").WithArgs(uint64(2), sqlmock.AnyArg()).WillReturnResult(sqlmock.NewResult(1, 1)) 582 mock.ExpectCommit() 583 584 a.NoError(file.UpdateSize(8)) 585 a.NoError(mock.ExpectationsWereMet()) 586 } 587 588 // 文件更新失败 589 { 590 file := File{Size: 10} 591 mock.ExpectBegin() 592 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 8, sqlmock.AnyArg(), 10).WillReturnError(errors.New("error")) 593 mock.ExpectRollback() 594 595 a.Error(file.UpdateSize(8)) 596 a.NoError(mock.ExpectationsWereMet()) 597 } 598 599 // 用户容量更新失败 600 { 601 file := File{Size: 10} 602 mock.ExpectBegin() 603 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 8, sqlmock.AnyArg(), 10).WillReturnResult(sqlmock.NewResult(1, 1)) 604 mock.ExpectExec("UPDATE(.+)storage(.+)-(.+)").WithArgs(uint64(2), sqlmock.AnyArg()).WillReturnError(errors.New("error")) 605 mock.ExpectRollback() 606 607 a.Error(file.UpdateSize(8)) 608 a.NoError(mock.ExpectationsWereMet()) 609 } 610 } 611 612 func TestFile_PopChunkToFile(t *testing.T) { 613 a := assert.New(t) 614 timeNow := time.Now() 615 file := File{} 616 mock.ExpectBegin() 617 mock.ExpectExec("UPDATE(.+)files(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 618 mock.ExpectCommit() 619 a.NoError(file.PopChunkToFile(&timeNow, "1,1")) 620 } 621 622 func TestFile_CanCopy(t *testing.T) { 623 a := assert.New(t) 624 file := File{} 625 a.True(file.CanCopy()) 626 file.UploadSessionID = &file.Name 627 a.False(file.CanCopy()) 628 } 629 630 func TestFile_FileInfoInterface(t *testing.T) { 631 asserts := assert.New(t) 632 file := File{ 633 Model: gorm.Model{ 634 UpdatedAt: time.Date(2019, 12, 21, 12, 40, 0, 0, time.UTC), 635 }, 636 Name: "test_name", 637 SourceName: "", 638 UserID: 0, 639 Size: 10, 640 PicInfo: "", 641 FolderID: 0, 642 PolicyID: 0, 643 Policy: Policy{}, 644 Position: "/test", 645 } 646 647 name := file.GetName() 648 asserts.Equal("test_name", name) 649 650 size := file.GetSize() 651 asserts.Equal(uint64(10), size) 652 653 asserts.Equal(time.Date(2019, 12, 21, 12, 40, 0, 0, time.UTC), file.ModTime()) 654 asserts.False(file.IsDir()) 655 asserts.Equal("/test", file.GetPosition()) 656 } 657 658 func TestGetFilesByKeywords(t *testing.T) { 659 asserts := assert.New(t) 660 661 // 未指定用户 662 { 663 mock.ExpectQuery("SELECT(.+)").WithArgs("k1", "k2").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1)) 664 res, err := GetFilesByKeywords(0, nil, "k1", "k2") 665 asserts.NoError(mock.ExpectationsWereMet()) 666 asserts.NoError(err) 667 asserts.Len(res, 1) 668 } 669 670 // 指定用户 671 { 672 mock.ExpectQuery("SELECT(.+)").WithArgs(1, "k1", "k2").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1)) 673 res, err := GetFilesByKeywords(1, nil, "k1", "k2") 674 asserts.NoError(mock.ExpectationsWereMet()) 675 asserts.NoError(err) 676 asserts.Len(res, 1) 677 } 678 679 // 指定父目录 680 { 681 mock.ExpectQuery("SELECT(.+)").WithArgs(1, 12, "k1", "k2").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1)) 682 res, err := GetFilesByKeywords(1, []uint{12}, "k1", "k2") 683 asserts.NoError(mock.ExpectationsWereMet()) 684 asserts.NoError(err) 685 asserts.Len(res, 1) 686 } 687 } 688 689 func TestFile_CreateOrGetSourceLink(t *testing.T) { 690 a := assert.New(t) 691 file := &File{} 692 file.ID = 1 693 694 // 已存在,返回老的 SourceLink 695 { 696 mock.ExpectQuery("SELECT(.+)source_links(.+)").WithArgs(1).WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(2)) 697 res, err := file.CreateOrGetSourceLink() 698 a.NoError(err) 699 a.EqualValues(2, res.ID) 700 a.NoError(mock.ExpectationsWereMet()) 701 } 702 703 // 不存在,插入失败 704 { 705 expectedErr := errors.New("error") 706 mock.ExpectQuery("SELECT(.+)source_links(.+)").WithArgs(1).WillReturnRows(sqlmock.NewRows([]string{"id"})) 707 mock.ExpectBegin() 708 mock.ExpectExec("INSERT(.+)source_links(.+)").WillReturnError(expectedErr) 709 mock.ExpectRollback() 710 res, err := file.CreateOrGetSourceLink() 711 a.Nil(res) 712 a.ErrorIs(err, expectedErr) 713 a.NoError(mock.ExpectationsWereMet()) 714 } 715 716 // 成功 717 { 718 mock.ExpectQuery("SELECT(.+)source_links(.+)").WithArgs(1).WillReturnRows(sqlmock.NewRows([]string{"id"})) 719 mock.ExpectBegin() 720 mock.ExpectExec("INSERT(.+)source_links(.+)").WillReturnResult(sqlmock.NewResult(2, 1)) 721 mock.ExpectCommit() 722 res, err := file.CreateOrGetSourceLink() 723 a.NoError(err) 724 a.EqualValues(2, res.ID) 725 a.EqualValues(file.ID, res.File.ID) 726 a.NoError(mock.ExpectationsWereMet()) 727 } 728 } 729 730 func TestFile_UpdateMetadata(t *testing.T) { 731 a := assert.New(t) 732 file := &File{} 733 file.ID = 1 734 735 // 更新失败 736 { 737 expectedErr := errors.New("error") 738 mock.ExpectBegin() 739 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs(sqlmock.AnyArg(), 1).WillReturnError(expectedErr) 740 mock.ExpectRollback() 741 a.ErrorIs(file.UpdateMetadata(map[string]string{"1": "1"}), expectedErr) 742 a.NoError(mock.ExpectationsWereMet()) 743 } 744 745 // 成功 746 { 747 mock.ExpectBegin() 748 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs(sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1)) 749 mock.ExpectCommit() 750 a.NoError(file.UpdateMetadata(map[string]string{"1": "1"})) 751 a.NoError(mock.ExpectationsWereMet()) 752 a.Equal("1", file.MetadataSerialized["1"]) 753 } 754 } 755 756 func TestFile_ShouldLoadThumb(t *testing.T) { 757 a := assert.New(t) 758 file := &File{ 759 MetadataSerialized: map[string]string{}, 760 } 761 file.ID = 1 762 763 // 无缩略图 764 { 765 file.MetadataSerialized[ThumbStatusMetadataKey] = ThumbStatusNotAvailable 766 a.False(file.ShouldLoadThumb()) 767 } 768 769 // 有缩略图 770 { 771 file.MetadataSerialized[ThumbStatusMetadataKey] = ThumbStatusExist 772 a.True(file.ShouldLoadThumb()) 773 } 774 } 775 776 func TestFile_ThumbFile(t *testing.T) { 777 a := assert.New(t) 778 file := &File{ 779 SourceName: "test", 780 MetadataSerialized: map[string]string{}, 781 } 782 file.ID = 1 783 784 a.Equal("test._thumb", file.ThumbFile()) 785 }