github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/filesystem/hooks_test.go (about) 1 package filesystem 2 3 import ( 4 "context" 5 "errors" 6 "github.com/DATA-DOG/go-sqlmock" 7 "github.com/cloudreve/Cloudreve/v3/pkg/cache" 8 "github.com/cloudreve/Cloudreve/v3/pkg/conf" 9 "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/local" 10 "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx" 11 "github.com/cloudreve/Cloudreve/v3/pkg/mocks/requestmock" 12 "github.com/cloudreve/Cloudreve/v3/pkg/request" 13 "github.com/cloudreve/Cloudreve/v3/pkg/serializer" 14 "io/ioutil" 15 "net/http" 16 "strings" 17 "testing" 18 19 model "github.com/cloudreve/Cloudreve/v3/models" 20 "github.com/jinzhu/gorm" 21 "github.com/stretchr/testify/assert" 22 testMock "github.com/stretchr/testify/mock" 23 ) 24 25 func TestGenericBeforeUpload(t *testing.T) { 26 asserts := assert.New(t) 27 file := &fsctx.FileStream{ 28 Size: 5, 29 Name: "1.txt", 30 } 31 ctx := context.Background() 32 cache.Set("pack_size_0", uint64(0), 0) 33 fs := FileSystem{ 34 User: &model.User{ 35 Storage: 0, 36 Group: model.Group{ 37 MaxStorage: 11, 38 }, 39 }, 40 Policy: &model.Policy{ 41 MaxSize: 4, 42 OptionsSerialized: model.PolicyOption{ 43 FileType: []string{"txt"}, 44 }, 45 }, 46 } 47 48 asserts.Error(HookValidateFile(ctx, &fs, file)) 49 50 file.Size = 1 51 file.Name = "1" 52 asserts.Error(HookValidateFile(ctx, &fs, file)) 53 54 file.Name = "1.txt" 55 asserts.NoError(HookValidateFile(ctx, &fs, file)) 56 57 file.Name = "1.t/xt" 58 asserts.Error(HookValidateFile(ctx, &fs, file)) 59 } 60 61 func TestGenericAfterUploadCanceled(t *testing.T) { 62 asserts := assert.New(t) 63 file := &fsctx.FileStream{ 64 Size: 5, 65 Name: "TestGenericAfterUploadCanceled", 66 SavePath: "TestGenericAfterUploadCanceled", 67 } 68 ctx := context.Background() 69 fs := FileSystem{ 70 User: &model.User{}, 71 } 72 73 // 成功 74 { 75 mockHandler := &FileHeaderMock{} 76 fs.Handler = mockHandler 77 mockHandler.On("Delete", testMock.Anything, testMock.Anything).Return([]string{}, nil) 78 err := HookDeleteTempFile(ctx, &fs, file) 79 asserts.NoError(err) 80 mockHandler.AssertExpectations(t) 81 } 82 83 // 失败 84 { 85 mockHandler := &FileHeaderMock{} 86 fs.Handler = mockHandler 87 mockHandler.On("Delete", testMock.Anything, testMock.Anything).Return([]string{}, errors.New("")) 88 err := HookDeleteTempFile(ctx, &fs, file) 89 asserts.NoError(err) 90 mockHandler.AssertExpectations(t) 91 } 92 93 } 94 95 func TestGenericAfterUpload(t *testing.T) { 96 asserts := assert.New(t) 97 fs := FileSystem{ 98 User: &model.User{ 99 Model: gorm.Model{ 100 ID: 1, 101 }, 102 }, 103 Policy: &model.Policy{}, 104 } 105 106 ctx := context.Background() 107 file := &fsctx.FileStream{ 108 VirtualPath: "/我的文件", 109 Name: "test.txt", 110 } 111 112 // 正常 113 mock.ExpectQuery("SELECT(.+)"). 114 WithArgs(1). 115 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(1, 1)) 116 mock.ExpectQuery("SELECT(.+)files"). 117 WithArgs(1, "我的文件"). 118 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"})) 119 // 1 120 mock.ExpectQuery("SELECT(.+)"). 121 WithArgs("我的文件", 1, 1). 122 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(2, 1)) 123 mock.ExpectQuery("SELECT(.+)files(.+)").WillReturnError(errors.New("not found")) 124 mock.ExpectBegin() 125 mock.ExpectExec("INSERT(.+)files(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 126 mock.ExpectExec("UPDATE(.+)storage(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 127 mock.ExpectCommit() 128 129 err := GenericAfterUpload(ctx, &fs, file) 130 asserts.NoError(err) 131 asserts.NoError(mock.ExpectationsWereMet()) 132 133 // 文件已存在 134 mock.ExpectQuery("SELECT(.+)"). 135 WithArgs(1). 136 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(1, 1)) 137 mock.ExpectQuery("SELECT(.+)files"). 138 WithArgs(1, "我的文件"). 139 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"})) 140 // 1 141 mock.ExpectQuery("SELECT(.+)"). 142 WithArgs("我的文件", 1, 1). 143 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(2, 1)) 144 mock.ExpectQuery("SELECT(.+)files(.+)").WillReturnRows( 145 mock.NewRows([]string{"name"}).AddRow("test.txt"), 146 ) 147 err = GenericAfterUpload(ctx, &fs, file) 148 asserts.Equal(ErrFileExisted, err) 149 asserts.NoError(mock.ExpectationsWereMet()) 150 151 // 文件已存在, 且为上传占位符 152 mock.ExpectQuery("SELECT(.+)"). 153 WithArgs(1). 154 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(1, 1)) 155 mock.ExpectQuery("SELECT(.+)files"). 156 WithArgs(1, "我的文件"). 157 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"})) 158 // 1 159 mock.ExpectQuery("SELECT(.+)"). 160 WithArgs("我的文件", 1, 1). 161 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(2, 1)) 162 mock.ExpectQuery("SELECT(.+)files(.+)").WillReturnRows( 163 mock.NewRows([]string{"name", "upload_session_id"}).AddRow("test.txt", "1"), 164 ) 165 err = GenericAfterUpload(ctx, &fs, file) 166 asserts.Equal(ErrFileUploadSessionExisted, err) 167 asserts.NoError(mock.ExpectationsWereMet()) 168 169 // 插入失败 170 mock.ExpectQuery("SELECT(.+)"). 171 WithArgs(1). 172 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(1, 1)) 173 mock.ExpectQuery("SELECT(.+)files"). 174 WithArgs(1, "我的文件"). 175 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"})) 176 // 1 177 mock.ExpectQuery("SELECT(.+)"). 178 WithArgs("我的文件", 1, 1). 179 WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(2, 1)) 180 181 mock.ExpectQuery("SELECT(.+)files(.+)").WillReturnError(errors.New("not found")) 182 mock.ExpectBegin() 183 mock.ExpectExec("INSERT(.+)files(.+)").WillReturnError(errors.New("error")) 184 mock.ExpectRollback() 185 186 err = GenericAfterUpload(ctx, &fs, file) 187 asserts.Equal(ErrInsertFileRecord, err) 188 asserts.NoError(mock.ExpectationsWereMet()) 189 190 } 191 192 func TestFileSystem_Use(t *testing.T) { 193 asserts := assert.New(t) 194 fs := FileSystem{} 195 196 hook := func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error { 197 return nil 198 } 199 200 // 添加一个 201 fs.Use("BeforeUpload", hook) 202 asserts.Len(fs.Hooks["BeforeUpload"], 1) 203 204 // 添加一个 205 fs.Use("BeforeUpload", hook) 206 asserts.Len(fs.Hooks["BeforeUpload"], 2) 207 208 // 不存在 209 fs.Use("BeforeUpload2333", hook) 210 211 asserts.NotPanics(func() { 212 for _, hookName := range []string{ 213 "AfterUpload", 214 "AfterValidateFailed", 215 "AfterUploadCanceled", 216 "BeforeFileDownload", 217 } { 218 fs.Use(hookName, hook) 219 } 220 }) 221 222 } 223 224 func TestFileSystem_Trigger(t *testing.T) { 225 asserts := assert.New(t) 226 fs := FileSystem{ 227 User: &model.User{}, 228 } 229 ctx := context.Background() 230 231 hook := func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error { 232 fs.User.Storage++ 233 return nil 234 } 235 236 // 一个 237 fs.Use("BeforeUpload", hook) 238 err := fs.Trigger(ctx, "BeforeUpload", nil) 239 asserts.NoError(err) 240 asserts.Equal(uint64(1), fs.User.Storage) 241 242 // 多个 243 fs.Use("BeforeUpload", hook) 244 fs.Use("BeforeUpload", hook) 245 err = fs.Trigger(ctx, "BeforeUpload", nil) 246 asserts.NoError(err) 247 asserts.Equal(uint64(4), fs.User.Storage) 248 249 // 多个,有失败 250 fs.Use("BeforeUpload", func(ctx context.Context, fs *FileSystem, file fsctx.FileHeader) error { 251 return errors.New("error") 252 }) 253 fs.Use("BeforeUpload", func(ctx context.Context, fs *FileSystem, file fsctx.FileHeader) error { 254 asserts.Fail("following hooks executed") 255 return nil 256 }) 257 err = fs.Trigger(ctx, "BeforeUpload", nil) 258 asserts.Error(err) 259 } 260 261 func TestHookValidateCapacity(t *testing.T) { 262 asserts := assert.New(t) 263 cache.Set("pack_size_1", uint64(0), 0) 264 fs := &FileSystem{User: &model.User{ 265 Model: gorm.Model{ID: 1}, 266 Storage: 0, 267 Group: model.Group{ 268 MaxStorage: 11, 269 }, 270 }} 271 ctx := context.Background() 272 file := &fsctx.FileStream{Size: 11} 273 { 274 err := HookValidateCapacity(ctx, fs, file) 275 asserts.NoError(err) 276 } 277 { 278 file.Size = 12 279 err := HookValidateCapacity(ctx, fs, file) 280 asserts.Error(err) 281 } 282 } 283 284 func TestHookValidateCapacityDiff(t *testing.T) { 285 a := assert.New(t) 286 fs := &FileSystem{User: &model.User{ 287 Group: model.Group{ 288 MaxStorage: 11, 289 }, 290 }} 291 file := model.File{Size: 10} 292 ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, file) 293 294 // 无需操作 295 { 296 a.NoError(HookValidateCapacityDiff(ctx, fs, &fsctx.FileStream{Size: 10})) 297 } 298 299 // 需要验证 300 { 301 a.Error(HookValidateCapacityDiff(ctx, fs, &fsctx.FileStream{Size: 12})) 302 } 303 304 } 305 306 func TestHookResetPolicy(t *testing.T) { 307 asserts := assert.New(t) 308 fs := &FileSystem{User: &model.User{ 309 Model: gorm.Model{ID: 1}, 310 }} 311 312 // 成功 313 { 314 file := model.File{PolicyID: 2} 315 cache.Deletes([]string{"2"}, "policy_") 316 mock.ExpectQuery("SELECT(.+)policies(.+)"). 317 WillReturnRows(sqlmock.NewRows([]string{"id", "type"}).AddRow(2, "local")) 318 ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, file) 319 err := HookResetPolicy(ctx, fs, nil) 320 asserts.NoError(mock.ExpectationsWereMet()) 321 asserts.NoError(err) 322 } 323 324 // 上下文文件不存在 325 { 326 cache.Deletes([]string{"2"}, "policy_") 327 ctx := context.Background() 328 err := HookResetPolicy(ctx, fs, nil) 329 asserts.Error(err) 330 } 331 } 332 333 func TestHookCleanFileContent(t *testing.T) { 334 asserts := assert.New(t) 335 fs := &FileSystem{User: &model.User{ 336 Model: gorm.Model{ID: 1}, 337 }} 338 339 file := &fsctx.FileStream{SavePath: "123/123"} 340 handlerMock := FileHeaderMock{} 341 handlerMock.On("Put", testMock.Anything, testMock.Anything).Return(errors.New("error")) 342 fs.Handler = handlerMock 343 err := HookCleanFileContent(context.Background(), fs, file) 344 asserts.Error(err) 345 handlerMock.AssertExpectations(t) 346 } 347 348 func TestHookClearFileSize(t *testing.T) { 349 asserts := assert.New(t) 350 fs := &FileSystem{User: &model.User{ 351 Model: gorm.Model{ID: 1}, 352 }} 353 354 // 成功 355 { 356 ctx := context.WithValue( 357 context.Background(), 358 fsctx.FileModelCtx, 359 model.File{Model: gorm.Model{ID: 1}, Size: 10}, 360 ) 361 mock.ExpectBegin() 362 mock.ExpectExec("UPDATE(.+)files(.+)"). 363 WithArgs("", 0, sqlmock.AnyArg(), 1, 10). 364 WillReturnResult(sqlmock.NewResult(1, 1)) 365 mock.ExpectExec("UPDATE(.+)users(.+)"). 366 WithArgs(10, sqlmock.AnyArg()). 367 WillReturnResult(sqlmock.NewResult(1, 1)) 368 mock.ExpectCommit() 369 err := HookClearFileSize(ctx, fs, nil) 370 asserts.NoError(mock.ExpectationsWereMet()) 371 asserts.NoError(err) 372 } 373 374 // 上下文对象不存在 375 { 376 ctx := context.Background() 377 err := HookClearFileSize(ctx, fs, nil) 378 asserts.Error(err) 379 } 380 381 } 382 383 func TestHookUpdateSourceName(t *testing.T) { 384 asserts := assert.New(t) 385 fs := &FileSystem{User: &model.User{ 386 Model: gorm.Model{ID: 1}, 387 }} 388 389 // 成功 390 { 391 originFile := model.File{ 392 Model: gorm.Model{ID: 1}, 393 SourceName: "new.txt", 394 } 395 ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, originFile) 396 mock.ExpectBegin() 397 mock.ExpectExec("UPDATE(.+)").WithArgs("", "new.txt", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1)) 398 mock.ExpectCommit() 399 err := HookUpdateSourceName(ctx, fs, nil) 400 asserts.NoError(mock.ExpectationsWereMet()) 401 asserts.NoError(err) 402 } 403 404 // 上下文错误 405 { 406 ctx := context.Background() 407 err := HookUpdateSourceName(ctx, fs, nil) 408 asserts.Error(err) 409 } 410 } 411 412 func TestGenericAfterUpdate(t *testing.T) { 413 asserts := assert.New(t) 414 fs := &FileSystem{User: &model.User{ 415 Model: gorm.Model{ID: 1}, 416 }} 417 418 // 成功 是图像文件 419 { 420 originFile := model.File{ 421 Model: gorm.Model{ID: 1}, 422 PicInfo: "1,1", 423 } 424 newFile := &fsctx.FileStream{Size: 10} 425 ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, originFile) 426 427 handlerMock := FileHeaderMock{} 428 handlerMock.On("Delete", testMock.Anything, []string{"._thumb"}).Return([]string{}, nil) 429 fs.Handler = handlerMock 430 mock.ExpectBegin() 431 mock.ExpectExec("UPDATE(.+)files(.+)"). 432 WithArgs("", 10, sqlmock.AnyArg(), 1, 0). 433 WillReturnResult(sqlmock.NewResult(1, 1)) 434 mock.ExpectExec("UPDATE(.+)users(.+)"). 435 WithArgs(10, sqlmock.AnyArg()). 436 WillReturnResult(sqlmock.NewResult(1, 1)) 437 mock.ExpectCommit() 438 439 err := GenericAfterUpdate(ctx, fs, newFile) 440 441 asserts.NoError(mock.ExpectationsWereMet()) 442 asserts.NoError(err) 443 } 444 445 // 原始文件上下文不存在 446 { 447 newFile := &fsctx.FileStream{Size: 10} 448 ctx := context.Background() 449 err := GenericAfterUpdate(ctx, fs, newFile) 450 asserts.Error(err) 451 } 452 453 // 无法更新数据库容量 454 // 成功 是图像文件 455 { 456 originFile := model.File{ 457 Model: gorm.Model{ID: 1}, 458 PicInfo: "1,1", 459 } 460 newFile := &fsctx.FileStream{Size: 10} 461 ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, originFile) 462 463 mock.ExpectBegin() 464 mock.ExpectExec("UPDATE(.+)"). 465 WithArgs("", 10, sqlmock.AnyArg(), 1, 0). 466 WillReturnError(errors.New("error")) 467 mock.ExpectRollback() 468 469 err := GenericAfterUpdate(ctx, fs, newFile) 470 471 asserts.NoError(mock.ExpectationsWereMet()) 472 asserts.Error(err) 473 } 474 } 475 476 func TestSlaveAfterUpload(t *testing.T) { 477 asserts := assert.New(t) 478 conf.SystemConfig.Mode = "slave" 479 fs, err := NewAnonymousFileSystem() 480 conf.SystemConfig.Mode = "master" 481 asserts.NoError(err) 482 483 // 成功 484 { 485 clientMock := requestmock.RequestMock{} 486 clientMock.On( 487 "Request", 488 "POST", 489 "http://test/callbakc", 490 testMock.Anything, 491 testMock.Anything, 492 ).Return(&request.Response{ 493 Err: nil, 494 Response: &http.Response{ 495 StatusCode: 200, 496 Body: ioutil.NopCloser(strings.NewReader(`{"code":0}`)), 497 }, 498 }) 499 request.GeneralClient = clientMock 500 file := &fsctx.FileStream{ 501 Size: 10, 502 VirtualPath: "/my", 503 Name: "test.txt", 504 SavePath: "/not_exist", 505 } 506 err := SlaveAfterUpload(&serializer.UploadSession{Callback: "http://test/callbakc"})(context.Background(), fs, file) 507 clientMock.AssertExpectations(t) 508 asserts.NoError(err) 509 } 510 511 // 跳过回调 512 { 513 file := &fsctx.FileStream{ 514 Size: 10, 515 VirtualPath: "/my", 516 Name: "test.txt", 517 SavePath: "/not_exist", 518 } 519 err := SlaveAfterUpload(&serializer.UploadSession{})(context.Background(), fs, file) 520 asserts.NoError(err) 521 } 522 } 523 524 func TestFileSystem_CleanHooks(t *testing.T) { 525 asserts := assert.New(t) 526 fs := &FileSystem{ 527 User: &model.User{ 528 Model: gorm.Model{ID: 1}, 529 }, 530 Hooks: map[string][]Hook{ 531 "hook1": []Hook{}, 532 "hook2": []Hook{}, 533 "hook3": []Hook{}, 534 }, 535 } 536 537 // 清理一个 538 { 539 fs.CleanHooks("hook2") 540 asserts.Len(fs.Hooks, 2) 541 asserts.Contains(fs.Hooks, "hook1") 542 asserts.Contains(fs.Hooks, "hook3") 543 } 544 545 // 清理全部 546 { 547 fs.CleanHooks("") 548 asserts.Len(fs.Hooks, 0) 549 } 550 } 551 552 func TestHookCancelContext(t *testing.T) { 553 asserts := assert.New(t) 554 fs := &FileSystem{} 555 ctx, cancel := context.WithCancel(context.Background()) 556 557 // empty ctx 558 { 559 asserts.NoError(HookCancelContext(ctx, fs, nil)) 560 select { 561 case <-ctx.Done(): 562 t.Errorf("Channel should not be closed") 563 default: 564 565 } 566 } 567 568 // with cancel ctx 569 { 570 ctx = context.WithValue(ctx, fsctx.CancelFuncCtx, cancel) 571 asserts.NoError(HookCancelContext(ctx, fs, nil)) 572 _, ok := <-ctx.Done() 573 asserts.False(ok) 574 } 575 } 576 577 func TestHookClearFileHeaderSize(t *testing.T) { 578 a := assert.New(t) 579 fs := &FileSystem{} 580 file := &fsctx.FileStream{Size: 10} 581 a.NoError(HookClearFileHeaderSize(context.Background(), fs, file)) 582 a.EqualValues(0, file.Size) 583 } 584 585 func TestHookTruncateFileTo(t *testing.T) { 586 a := assert.New(t) 587 fs := &FileSystem{} 588 file := &fsctx.FileStream{} 589 a.NoError(HookTruncateFileTo(0)(context.Background(), fs, file)) 590 591 fs.Handler = local.Driver{} 592 a.Error(HookTruncateFileTo(0)(context.Background(), fs, file)) 593 } 594 595 func TestHookChunkUploaded(t *testing.T) { 596 a := assert.New(t) 597 fs := &FileSystem{} 598 file := &fsctx.FileStream{ 599 AppendStart: 10, 600 Size: 10, 601 Model: &model.File{ 602 Model: gorm.Model{ID: 1}, 603 }, 604 } 605 606 mock.ExpectBegin() 607 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 20, sqlmock.AnyArg(), 1, 0).WillReturnResult(sqlmock.NewResult(1, 1)) 608 mock.ExpectExec("UPDATE(.+)users(.+)"). 609 WithArgs(20, sqlmock.AnyArg()). 610 WillReturnResult(sqlmock.NewResult(1, 1)) 611 mock.ExpectCommit() 612 a.NoError(HookChunkUploaded(context.Background(), fs, file)) 613 a.NoError(mock.ExpectationsWereMet()) 614 } 615 616 func TestHookChunkUploadFailed(t *testing.T) { 617 a := assert.New(t) 618 fs := &FileSystem{} 619 file := &fsctx.FileStream{ 620 AppendStart: 10, 621 Size: 10, 622 Model: &model.File{ 623 Model: gorm.Model{ID: 1}, 624 }, 625 } 626 627 mock.ExpectBegin() 628 mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 10, sqlmock.AnyArg(), 1, 0).WillReturnResult(sqlmock.NewResult(1, 1)) 629 mock.ExpectExec("UPDATE(.+)users(.+)"). 630 WithArgs(10, sqlmock.AnyArg()). 631 WillReturnResult(sqlmock.NewResult(1, 1)) 632 mock.ExpectCommit() 633 a.NoError(HookChunkUploadFailed(context.Background(), fs, file)) 634 a.NoError(mock.ExpectationsWereMet()) 635 } 636 637 func TestHookPopPlaceholderToFile(t *testing.T) { 638 a := assert.New(t) 639 fs := &FileSystem{} 640 file := &fsctx.FileStream{ 641 Model: &model.File{ 642 Model: gorm.Model{ID: 1}, 643 }, 644 } 645 646 mock.ExpectBegin() 647 mock.ExpectExec("UPDATE(.+)files(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 648 mock.ExpectCommit() 649 a.NoError(HookPopPlaceholderToFile("1,1")(context.Background(), fs, file)) 650 a.NoError(mock.ExpectationsWereMet()) 651 } 652 653 func TestHookPopPlaceholderToFileBySuffix(t *testing.T) { 654 a := assert.New(t) 655 fs := &FileSystem{ 656 Policy: &model.Policy{Type: "cos"}, 657 } 658 file := &fsctx.FileStream{ 659 Name: "1.png", 660 Model: &model.File{ 661 Model: gorm.Model{ID: 1}, 662 }, 663 } 664 665 mock.ExpectBegin() 666 mock.ExpectExec("UPDATE(.+)files(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 667 mock.ExpectCommit() 668 a.NoError(HookPopPlaceholderToFile("")(context.Background(), fs, file)) 669 a.NoError(mock.ExpectationsWereMet()) 670 } 671 672 func TestHookDeleteUploadSession(t *testing.T) { 673 a := assert.New(t) 674 fs := &FileSystem{} 675 file := &fsctx.FileStream{ 676 Model: &model.File{ 677 Model: gorm.Model{ID: 1}, 678 }, 679 } 680 681 cache.Set(UploadSessionCachePrefix+"TestHookDeleteUploadSession", "", 0) 682 a.NoError(HookDeleteUploadSession("TestHookDeleteUploadSession")(context.Background(), fs, file)) 683 _, ok := cache.Get(UploadSessionCachePrefix + "TestHookDeleteUploadSession") 684 a.False(ok) 685 } 686 func TestNewWebdavAfterUploadHook(t *testing.T) { 687 a := assert.New(t) 688 fs := &FileSystem{} 689 file := &fsctx.FileStream{ 690 Model: &model.File{ 691 Model: gorm.Model{ID: 1}, 692 }, 693 } 694 695 req, _ := http.NewRequest("get", "http://localhost", nil) 696 req.Header.Add("X-Oc-Mtime", "1681521402") 697 req.Header.Add("OC-Checksum", "checksum") 698 mock.ExpectBegin() 699 mock.ExpectExec("UPDATE(.+)files(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 700 mock.ExpectCommit() 701 mock.ExpectBegin() 702 mock.ExpectExec("UPDATE(.+)files(.+)").WillReturnResult(sqlmock.NewResult(1, 1)) 703 mock.ExpectCommit() 704 err := NewWebdavAfterUploadHook(req)(context.Background(), fs, file) 705 a.NoError(err) 706 a.NoError(mock.ExpectationsWereMet()) 707 708 }