package filesystem import ( "github.com/cloudreve/Cloudreve/v3/pkg/cluster" "github.com/cloudreve/Cloudreve/v3/pkg/conf" "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/shadow/masterinslave" "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/shadow/slaveinmaster" "github.com/cloudreve/Cloudreve/v3/pkg/serializer" "net/http/httptest" "github.com/DATA-DOG/go-sqlmock" model "github.com/cloudreve/Cloudreve/v3/models" "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/local" "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/remote" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "testing" ) func TestNewFileSystem(t *testing.T) { asserts := assert.New(t) user := model.User{ Policy: model.Policy{ Type: "local", }, } // 本地 成功 fs, err := NewFileSystem(&user) asserts.NoError(err) asserts.NotNil(fs.Handler) asserts.IsType(local.Driver{}, fs.Handler) // 远程 user.Policy.Type = "remote" fs, err = NewFileSystem(&user) asserts.NoError(err) asserts.NotNil(fs.Handler) asserts.IsType(&remote.Driver{}, fs.Handler) user.Policy.Type = "unknown" fs, err = NewFileSystem(&user) asserts.Error(err) } func TestNewFileSystemFromContext(t *testing.T) { asserts := assert.New(t) c, _ := gin.CreateTestContext(httptest.NewRecorder()) c.Set("user", &model.User{ Policy: model.Policy{ Type: "local", }, }) fs, err := NewFileSystemFromContext(c) asserts.NotNil(fs) asserts.NoError(err) c, _ = gin.CreateTestContext(httptest.NewRecorder()) fs, err = NewFileSystemFromContext(c) asserts.Nil(fs) asserts.Error(err) } func TestDispatchHandler(t *testing.T) { asserts := assert.New(t) fs := &FileSystem{ User: &model.User{}, Policy: &model.Policy{ Type: "local", }, } // 未指定,使用用户默认 err := fs.DispatchHandler() asserts.NoError(err) asserts.IsType(local.Driver{}, fs.Handler) // 已指定,发生错误 fs.Policy = &model.Policy{Type: "unknown"} err = fs.DispatchHandler() asserts.Error(err) fs.Policy = &model.Policy{Type: "mock"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "local"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "remote"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "qiniu"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "oss", Server: "https://s.com", BucketName: "1234"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "upyun"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "onedrive"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "cos"} err = fs.DispatchHandler() asserts.NoError(err) fs.Policy = &model.Policy{Type: "s3"} err = fs.DispatchHandler() asserts.NoError(err) } func TestNewFileSystemFromCallback(t *testing.T) { asserts := assert.New(t) // 用户上下文不存在 { c, _ := gin.CreateTestContext(httptest.NewRecorder()) fs, err := NewFileSystemFromCallback(c) asserts.Nil(fs) asserts.Error(err) } // 找不到回调会话 { c, _ := gin.CreateTestContext(httptest.NewRecorder()) c.Set("user", &model.User{ Policy: model.Policy{ Type: "local", }, }) fs, err := NewFileSystemFromCallback(c) asserts.Nil(fs) asserts.Error(err) } // 成功 { c, _ := gin.CreateTestContext(httptest.NewRecorder()) c.Set("user", &model.User{ Policy: model.Policy{ Type: "local", }, }) c.Set(UploadSessionCtx, &serializer.UploadSession{Policy: model.Policy{Type: "local"}}) fs, err := NewFileSystemFromCallback(c) asserts.NotNil(fs) asserts.NoError(err) } } func TestFileSystem_SetTargetFileByIDs(t *testing.T) { asserts := assert.New(t) // 成功 { fs := &FileSystem{} mock.ExpectQuery("SELECT(.+)"). WithArgs(1, 2). WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "1.txt")) err := fs.SetTargetFileByIDs([]uint{1, 2}) asserts.NoError(mock.ExpectationsWereMet()) asserts.Len(fs.FileTarget, 1) asserts.NoError(err) } // 未找到 { fs := &FileSystem{} mock.ExpectQuery("SELECT(.+)").WithArgs(1, 2).WillReturnRows(sqlmock.NewRows([]string{"id", "name"})) err := fs.SetTargetFileByIDs([]uint{1, 2}) asserts.NoError(mock.ExpectationsWereMet()) asserts.Len(fs.FileTarget, 0) asserts.Error(err) } } func TestFileSystem_CleanTargets(t *testing.T) { asserts := assert.New(t) fs := &FileSystem{ FileTarget: []model.File{{}, {}}, DirTarget: []model.Folder{{}, {}}, } fs.CleanTargets() asserts.Len(fs.FileTarget, 0) asserts.Len(fs.DirTarget, 0) } func TestNewAnonymousFileSystem(t *testing.T) { asserts := assert.New(t) // 正常 { mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id", "name", "policies"}).AddRow(3, "游客", "[]")) fs, err := NewAnonymousFileSystem() asserts.NoError(mock.ExpectationsWereMet()) asserts.NoError(err) asserts.Equal("游客", fs.User.Group.Name) } // 游客用户组不存在 { mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id", "name", "policies"})) fs, err := NewAnonymousFileSystem() asserts.NoError(mock.ExpectationsWereMet()) asserts.Error(err) asserts.Nil(fs) } // 从机 { conf.SystemConfig.Mode = "slave" fs, err := NewAnonymousFileSystem() asserts.NoError(mock.ExpectationsWereMet()) asserts.NoError(err) asserts.NotNil(fs) asserts.NotNil(fs.Handler) } } func TestFileSystem_Recycle(t *testing.T) { fs := &FileSystem{ User: &model.User{}, Policy: &model.Policy{}, FileTarget: []model.File{model.File{}}, DirTarget: []model.Folder{model.Folder{}}, Hooks: map[string][]Hook{"AfterUpload": []Hook{GenericAfterUpdate}}, } fs.Recycle() newFS := getEmptyFS() if fs != newFS { t.Error("指针不一致") } } func TestFileSystem_SetTargetByInterface(t *testing.T) { asserts := assert.New(t) fs := FileSystem{} // 目录 { asserts.NoError(fs.SetTargetByInterface(&model.Folder{})) asserts.Len(fs.DirTarget, 1) asserts.Len(fs.FileTarget, 0) } // 文件 { asserts.NoError(fs.SetTargetByInterface(&model.File{})) asserts.Len(fs.DirTarget, 1) asserts.Len(fs.FileTarget, 1) } } func TestFileSystem_SwitchToSlaveHandler(t *testing.T) { a := assert.New(t) fs := FileSystem{ User: &model.User{}, } mockNode := &cluster.MasterNode{ Model: &model.Node{}, } fs.SwitchToSlaveHandler(mockNode) a.IsType(&slaveinmaster.Driver{}, fs.Handler) } func TestFileSystem_SwitchToShadowHandler(t *testing.T) { a := assert.New(t) fs := FileSystem{ User: &model.User{}, Policy: &model.Policy{}, } mockNode := &cluster.MasterNode{ Model: &model.Node{}, } // local to remote { fs.Policy.Type = "local" fs.SwitchToShadowHandler(mockNode, "", "") a.IsType(&masterinslave.Driver{}, fs.Handler) } // onedrive { fs.Policy.Type = "onedrive" fs.SwitchToShadowHandler(mockNode, "", "") a.IsType(&masterinslave.Driver{}, fs.Handler) } }