diff --git a/pkg/conf/conf_test.go b/pkg/conf/conf_test.go index 3a30578..2048d0c 100644 --- a/pkg/conf/conf_test.go +++ b/pkg/conf/conf_test.go @@ -41,7 +41,12 @@ TablePrefix = v3_` // TestInitNoPanic 日志路径存在且合法时 func TestInitNoPanic(t *testing.T) { asserts := assert.New(t) - testCase := `[Database] + testCase := ` +[System] +Listen = 3000 +HashIDSalt = 1 + +[Database] Type = mysql User = root Password = root @@ -62,7 +67,12 @@ func TestMapSection(t *testing.T) { asserts := assert.New(t) //正常情况 - testCase := `[Database] + testCase := ` +[System] +Listen = 3000 +HashIDSalt = 1 + +[Database] Type = mysql User = root Password:root diff --git a/pkg/filesystem/archive_test.go b/pkg/filesystem/archive_test.go index 9547aa3..e814213 100644 --- a/pkg/filesystem/archive_test.go +++ b/pkg/filesystem/archive_test.go @@ -5,6 +5,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" model "github.com/HFO4/cloudreve/models" "github.com/HFO4/cloudreve/pkg/cache" + "github.com/HFO4/cloudreve/pkg/filesystem/fsctx" "github.com/jinzhu/gorm" "github.com/stretchr/testify/assert" "testing" @@ -79,4 +80,30 @@ func TestFileSystem_Compress(t *testing.T) { asserts.Error(err) asserts.Empty(zipFile) } + + // 限制父目录 + { + ctx := context.WithValue(context.Background(), fsctx.LimitParentCtx, &model.Folder{ + Model: gorm.Model{ID: 3}, + }) + // 查找压缩父目录 + mock.ExpectQuery("SELECT(.+)folders(.+)"). + WithArgs(1, 1). + WillReturnRows(sqlmock.NewRows([]string{"id", "name", "parent_id"}).AddRow(1, "parent", 3)) + // 查找顶级待压缩文件 + mock.ExpectQuery("SELECT(.+)files(.+)"). + WithArgs(1, 1). + WillReturnRows( + sqlmock.NewRows( + []string{"id", "name", "source_name", "policy_id"}). + AddRow(1, "1.txt", "tests/file1.txt", 1), + ) + asserts.NoError(cache.Set("setting_temp_path", "tests", -1)) + + zipFile, err := fs.Compress(ctx, []uint{1}, []uint{1}) + asserts.Error(err) + asserts.Equal(ErrObjectNotExist, err) + asserts.Empty(zipFile) + } + } diff --git a/pkg/filesystem/file_test.go b/pkg/filesystem/file_test.go index a669725..6a3646e 100644 --- a/pkg/filesystem/file_test.go +++ b/pkg/filesystem/file_test.go @@ -601,3 +601,16 @@ func TestFileSystem_Preview(t *testing.T) { asserts.Nil(resp) } } + +func TestFileSystem_ResetFileIDIfNotExist(t *testing.T) { + asserts := assert.New(t) + ctx := context.WithValue(context.Background(), fsctx.LimitParentCtx, &model.Folder{Model: gorm.Model{ID: 1}}) + fs := FileSystem{ + FileTarget: []model.File{ + { + FolderID: 2, + }, + }, + } + asserts.Equal(ErrObjectNotExist, fs.resetFileIDIfNotExist(ctx, 1)) +} diff --git a/pkg/filesystem/filesystem.go b/pkg/filesystem/filesystem.go index 398f7ef..e718f79 100644 --- a/pkg/filesystem/filesystem.go +++ b/pkg/filesystem/filesystem.go @@ -227,7 +227,6 @@ func NewFileSystemFromContext(c *gin.Context) (*FileSystem, error) { } // NewFileSystemFromCallback 从gin.Context创建回调用文件系统 -// TODO 测试 func NewFileSystemFromCallback(c *gin.Context) (*FileSystem, error) { fs, err := NewFileSystemFromContext(c) if err != nil { diff --git a/pkg/filesystem/filesystem_test.go b/pkg/filesystem/filesystem_test.go index ee326d8..f699b6d 100644 --- a/pkg/filesystem/filesystem_test.go +++ b/pkg/filesystem/filesystem_test.go @@ -238,3 +238,22 @@ func TestFileSystem_Recycle(t *testing.T) { 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) + } +} diff --git a/pkg/filesystem/manage_test.go b/pkg/filesystem/manage_test.go index c54ce56..6196fd9 100644 --- a/pkg/filesystem/manage_test.go +++ b/pkg/filesystem/manage_test.go @@ -7,6 +7,7 @@ import ( model "github.com/HFO4/cloudreve/models" "github.com/HFO4/cloudreve/pkg/cache" "github.com/HFO4/cloudreve/pkg/conf" + "github.com/HFO4/cloudreve/pkg/filesystem/fsctx" "github.com/HFO4/cloudreve/pkg/serializer" "github.com/jinzhu/gorm" "github.com/stretchr/testify/assert" @@ -40,6 +41,25 @@ func TestFileSystem_List(t *testing.T) { asserts.NoError(err) asserts.NoError(mock.ExpectationsWereMet()) + // 成功,子目录包含文件和路径,不使用路径处理钩子,包含分享key + // 根目录 + mock.ExpectQuery("SELECT(.+)"). + WithArgs(1). + WillReturnRows(sqlmock.NewRows([]string{"id", "name", "owner_id"}).AddRow(1, "/", 1)) + // folder + mock.ExpectQuery("SELECT(.+)"). + WithArgs(1, 1, "folder"). + WillReturnRows(sqlmock.NewRows([]string{"id", "name", "owner_id"}).AddRow(5, "folder", 1)) + + mock.ExpectQuery("SELECT(.+)folder(.+)").WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(6, "sub_folder1").AddRow(7, "sub_folder2")) + mock.ExpectQuery("SELECT(.+)file(.+)").WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(6, "sub_file1.txt").AddRow(7, "sub_file2.txt")) + ctxWithKey := context.WithValue(ctx, fsctx.ShareKeyCtx, "share") + objects, err = fs.List(ctxWithKey, "/folder", nil) + asserts.Len(objects, 4) + asserts.Equal("share", objects[3].Key) + asserts.NoError(err) + asserts.NoError(mock.ExpectationsWereMet()) + // 成功,子目录包含文件和路径,使用路径处理钩子 mock.ExpectQuery("SELECT(.+)"). WithArgs(1). @@ -585,3 +605,49 @@ func TestFileSystem_Rename(t *testing.T) { asserts.Equal(ErrIllegalObjectName, err) } } + +func TestFileSystem_SaveTo(t *testing.T) { + asserts := assert.New(t) + fs := &FileSystem{User: &model.User{ + Model: gorm.Model{ + ID: 1, + }, + }} + ctx := context.Background() + + // 单文件 失败 + { + // 根目录 + mock.ExpectQuery("SELECT(.+)"). + WithArgs(1). + WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(1, 1)) + mock.ExpectQuery("SELECT(.+)").WillReturnError(errors.New("error")) + fs.SetTargetFile(&[]model.File{{Name: "test.txt"}}) + err := fs.SaveTo(ctx, "/") + asserts.NoError(mock.ExpectationsWereMet()) + asserts.Error(err) + } + // 目录 成功 + { + // 根目录 + mock.ExpectQuery("SELECT(.+)"). + WithArgs(1). + WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(1, 1)) + mock.ExpectQuery("SELECT(.+)").WillReturnError(errors.New("error")) + fs.SetTargetDir(&[]model.Folder{{Name: "folder"}}) + err := fs.SaveTo(ctx, "/") + asserts.NoError(mock.ExpectationsWereMet()) + asserts.Error(err) + } + // 父目录不存在 + { + // 根目录 + mock.ExpectQuery("SELECT(.+)"). + WithArgs(1). + WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"})) + fs.SetTargetDir(&[]model.Folder{{Name: "folder"}}) + err := fs.SaveTo(ctx, "/") + asserts.NoError(mock.ExpectationsWereMet()) + asserts.Error(err) + } +} diff --git a/pkg/filesystem/path_test.go b/pkg/filesystem/path_test.go index 704ae20..57d8e6d 100644 --- a/pkg/filesystem/path_test.go +++ b/pkg/filesystem/path_test.go @@ -102,6 +102,25 @@ func TestFileSystem_IsPathExist(t *testing.T) { asserts.Equal(uint(4), folder.ID) } + // 深层路径 重设根目录为/1 + { + path := "/2/3" + fs.Root = &model.Folder{Name: "1", Model: gorm.Model{ID: 2}, OwnerID: 1} + // 2 + mock.ExpectQuery("SELECT(.+)"). + WithArgs(2, 1, "2"). + WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(3, 1)) + // 3 + mock.ExpectQuery("SELECT(.+)"). + WithArgs(3, 1, "3"). + WillReturnRows(sqlmock.NewRows([]string{"id", "owner_id"}).AddRow(4, 1)) + exist, folder := fs.IsPathExist(path) + asserts.NoError(mock.ExpectationsWereMet()) + asserts.True(exist) + asserts.Equal(uint(4), folder.ID) + fs.Root = nil + } + // 深层 不存在 { path := "/1/2/3" diff --git a/pkg/hashid/hash.go b/pkg/hashid/hash.go index 04a5a28..cd27167 100644 --- a/pkg/hashid/hash.go +++ b/pkg/hashid/hash.go @@ -54,7 +54,6 @@ func HashID(id uint, t int) string { } // DecodeHashID 计算HashID对应的数据库ID -// TODO 测试 func DecodeHashID(id string, t int) (uint, error) { v, _ := HashDecode(id) if len(v) != 2 || v[1] != t { diff --git a/pkg/hashid/hash_test.go b/pkg/hashid/hash_test.go index 5e8716c..5471d9e 100644 --- a/pkg/hashid/hash_test.go +++ b/pkg/hashid/hash_test.go @@ -30,3 +30,40 @@ func TestHashID(t *testing.T) { asserts.NotEmpty(res) } } + +func TestHashDecode(t *testing.T) { + asserts := assert.New(t) + + // 正常 + { + res, _ := HashEncode([]int{1, 2, 3}) + decodeRes, err := HashDecode(res) + asserts.NoError(err) + asserts.Equal([]int{1, 2, 3}, decodeRes) + } + + // 出错 + { + decodeRes, err := HashDecode("233") + asserts.Error(err) + asserts.Len(decodeRes, 0) + } +} + +func TestDecodeHashID(t *testing.T) { + asserts := assert.New(t) + + // 成功 + { + uid, err := DecodeHashID(HashID(1, ShareID), ShareID) + asserts.NoError(err) + asserts.EqualValues(1, uid) + } + + // 类型不匹配 + { + uid, err := DecodeHashID(HashID(1, ShareID), UserID) + asserts.Error(err) + asserts.EqualValues(0, uid) + } +} diff --git a/pkg/serializer/share_test.go b/pkg/serializer/share_test.go new file mode 100644 index 0000000..78c8d9c --- /dev/null +++ b/pkg/serializer/share_test.go @@ -0,0 +1,64 @@ +package serializer + +import ( + model "github.com/HFO4/cloudreve/models" + "github.com/jinzhu/gorm" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestBuildShareResponse(t *testing.T) { + asserts := assert.New(t) + + // 未解锁 + { + share := &model.Share{ + User: model.User{Model: gorm.Model{ID: 1}}, + Downloads: 1, + } + res := BuildShareResponse(share, false) + asserts.EqualValues(0, res.Downloads) + asserts.True(res.Locked) + asserts.NotNil(res.Creator) + } + + // 已解锁,非目录 + { + expires := time.Now().Add(time.Duration(10) * time.Second) + share := &model.Share{ + User: model.User{Model: gorm.Model{ID: 1}}, + Downloads: 1, + Expires: &expires, + File: model.File{ + Model: gorm.Model{ID: 1}, + }, + } + res := BuildShareResponse(share, true) + asserts.EqualValues(1, res.Downloads) + asserts.False(res.Locked) + asserts.NotEmpty(res.Expire) + asserts.NotNil(res.Creator) + asserts.NotNil(res.Score) + } + + // 已解锁,是目录 + { + expires := time.Now().Add(time.Duration(10) * time.Second) + share := &model.Share{ + User: model.User{Model: gorm.Model{ID: 1}}, + Downloads: 1, + Expires: &expires, + Folder: model.Folder{ + Model: gorm.Model{ID: 1}, + }, + IsDir: true, + } + res := BuildShareResponse(share, true) + asserts.EqualValues(1, res.Downloads) + asserts.False(res.Locked) + asserts.NotEmpty(res.Expire) + asserts.NotNil(res.Creator) + asserts.NotNil(res.Score) + } +}