mirror of https://github.com/cloudreve/Cloudreve
test(thumb): new changes in filesystem pkg
parent
408733a974
commit
8e2fc1a8f6
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||||
|
@ -141,17 +142,34 @@ func TestHandler_Thumb(t *testing.T) {
|
||||||
asserts.NoError(err)
|
asserts.NoError(err)
|
||||||
file.Close()
|
file.Close()
|
||||||
|
|
||||||
|
f := &model.File{
|
||||||
|
SourceName: "TestHandler_Thumb",
|
||||||
|
MetadataSerialized: map[string]string{
|
||||||
|
model.ThumbStatusMetadataKey: model.ThumbStatusExist,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// 正常
|
// 正常
|
||||||
{
|
{
|
||||||
thumb, err := handler.Thumb(ctx, "TestHandler_Thumb")
|
thumb, err := handler.Thumb(ctx, f)
|
||||||
asserts.NoError(err)
|
asserts.NoError(err)
|
||||||
asserts.NotNil(thumb.Content)
|
asserts.NotNil(thumb.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不存在
|
// file 不存在
|
||||||
{
|
{
|
||||||
_, err := handler.Thumb(ctx, "not_exist")
|
f.SourceName = "not_exist"
|
||||||
|
_, err := handler.Thumb(ctx, f)
|
||||||
asserts.Error(err)
|
asserts.Error(err)
|
||||||
|
asserts.ErrorIs(err, driver.ErrorThumbNotExist)
|
||||||
|
}
|
||||||
|
|
||||||
|
// thumb not exist
|
||||||
|
{
|
||||||
|
f.MetadataSerialized[model.ThumbStatusMetadataKey] = model.ThumbStatusNotExist
|
||||||
|
_, err := handler.Thumb(ctx, f)
|
||||||
|
asserts.Error(err)
|
||||||
|
asserts.ErrorIs(err, driver.ErrorThumbNotExist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,19 +246,19 @@ func TestDriver_Thumb(t *testing.T) {
|
||||||
}
|
}
|
||||||
handler.Client, _ = NewClient(&model.Policy{})
|
handler.Client, _ = NewClient(&model.Policy{})
|
||||||
handler.Client.Credential.ExpiresIn = time.Now().Add(time.Duration(100) * time.Hour).Unix()
|
handler.Client.Credential.ExpiresIn = time.Now().Add(time.Duration(100) * time.Hour).Unix()
|
||||||
|
file := &model.File{PicInfo: "1,1", Model: gorm.Model{ID: 1}}
|
||||||
|
|
||||||
// 失败
|
// 失败
|
||||||
{
|
{
|
||||||
ctx := context.WithValue(context.Background(), fsctx.ThumbSizeCtx, [2]uint{10, 20})
|
ctx := context.WithValue(context.Background(), fsctx.ThumbSizeCtx, [2]uint{10, 20})
|
||||||
ctx = context.WithValue(ctx, fsctx.FileModelCtx, model.File{PicInfo: "1,1", Model: gorm.Model{ID: 1}})
|
res, err := handler.Thumb(ctx, file)
|
||||||
res, err := handler.Thumb(ctx, "123.jpg")
|
|
||||||
asserts.Error(err)
|
asserts.Error(err)
|
||||||
asserts.Empty(res.URL)
|
asserts.Empty(res.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上下文错误
|
// 上下文错误
|
||||||
{
|
{
|
||||||
_, err := handler.Thumb(context.Background(), "123.jpg")
|
_, err := handler.Thumb(context.Background(), file)
|
||||||
asserts.Error(err)
|
asserts.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package remote
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/mocks/remoteclientmock"
|
"github.com/cloudreve/Cloudreve/v3/pkg/mocks/remoteclientmock"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
||||||
"io"
|
"io"
|
||||||
|
@ -373,14 +374,33 @@ func TestHandler_Thumb(t *testing.T) {
|
||||||
Type: "remote",
|
Type: "remote",
|
||||||
SecretKey: "test",
|
SecretKey: "test",
|
||||||
Server: "http://test.com",
|
Server: "http://test.com",
|
||||||
|
OptionsSerialized: model.PolicyOption{
|
||||||
|
ThumbExts: []string{"txt"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
AuthInstance: auth.HMACAuth{},
|
AuthInstance: auth.HMACAuth{},
|
||||||
}
|
}
|
||||||
|
file := &model.File{
|
||||||
|
Name: "1.txt",
|
||||||
|
SourceName: "1.txt",
|
||||||
|
}
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
asserts.NoError(cache.Set("setting_preview_timeout", "60", 0))
|
asserts.NoError(cache.Set("setting_preview_timeout", "60", 0))
|
||||||
resp, err := handler.Thumb(ctx, "/1.txt")
|
|
||||||
asserts.NoError(err)
|
// no error
|
||||||
asserts.True(resp.Redirect)
|
{
|
||||||
|
resp, err := handler.Thumb(ctx, file)
|
||||||
|
asserts.NoError(err)
|
||||||
|
asserts.True(resp.Redirect)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ext not support
|
||||||
|
{
|
||||||
|
file.Name = "1.jpg"
|
||||||
|
resp, err := handler.Thumb(ctx, file)
|
||||||
|
asserts.ErrorIs(err, driver.ErrorThumbNotSupported)
|
||||||
|
asserts.Nil(resp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandler_Token(t *testing.T) {
|
func TestHandler_Token(t *testing.T) {
|
||||||
|
|
|
@ -58,7 +58,6 @@ func TestFileSystem_AddFile(t *testing.T) {
|
||||||
asserts.NoError(err)
|
asserts.NoError(err)
|
||||||
asserts.NoError(mock.ExpectationsWereMet())
|
asserts.NoError(mock.ExpectationsWereMet())
|
||||||
asserts.Equal("/Uploads/1_sad.png", f.SourceName)
|
asserts.Equal("/Uploads/1_sad.png", f.SourceName)
|
||||||
asserts.NotEmpty(f.PicInfo)
|
|
||||||
|
|
||||||
// 前置钩子执行失败
|
// 前置钩子执行失败
|
||||||
{
|
{
|
||||||
|
@ -312,6 +311,19 @@ func TestFileSystem_deleteGroupedFile(t *testing.T) {
|
||||||
_, ok := cache.Get(UploadSessionCachePrefix + sessionID)
|
_, ok := cache.Get(UploadSessionCachePrefix + sessionID)
|
||||||
asserts.False(ok)
|
asserts.False(ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 包含缩略图
|
||||||
|
{
|
||||||
|
files[0].MetadataSerialized = map[string]string{
|
||||||
|
model.ThumbSidecarMetadataKey: "1",
|
||||||
|
}
|
||||||
|
failed := fs.deleteGroupedFile(ctx, fs.GroupFileByPolicy(ctx, files))
|
||||||
|
asserts.Equal(map[uint][]string{
|
||||||
|
1: {},
|
||||||
|
2: {},
|
||||||
|
3: {},
|
||||||
|
}, failed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFileSystem_GetSource(t *testing.T) {
|
func TestFileSystem_GetSource(t *testing.T) {
|
||||||
|
|
|
@ -360,7 +360,7 @@ func TestHookClearFileSize(t *testing.T) {
|
||||||
)
|
)
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectExec("UPDATE(.+)files(.+)").
|
mock.ExpectExec("UPDATE(.+)files(.+)").
|
||||||
WithArgs(0, sqlmock.AnyArg(), 1, 10).
|
WithArgs("", 0, sqlmock.AnyArg(), 1, 10).
|
||||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
mock.ExpectExec("UPDATE(.+)users(.+)").
|
mock.ExpectExec("UPDATE(.+)users(.+)").
|
||||||
WithArgs(10, sqlmock.AnyArg()).
|
WithArgs(10, sqlmock.AnyArg()).
|
||||||
|
@ -394,7 +394,7 @@ func TestHookUpdateSourceName(t *testing.T) {
|
||||||
}
|
}
|
||||||
ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, originFile)
|
ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, originFile)
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectExec("UPDATE(.+)").WithArgs("new.txt", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1))
|
mock.ExpectExec("UPDATE(.+)").WithArgs("", "new.txt", sqlmock.AnyArg(), 1).WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
mock.ExpectCommit()
|
mock.ExpectCommit()
|
||||||
err := HookUpdateSourceName(ctx, fs, nil)
|
err := HookUpdateSourceName(ctx, fs, nil)
|
||||||
asserts.NoError(mock.ExpectationsWereMet())
|
asserts.NoError(mock.ExpectationsWereMet())
|
||||||
|
@ -429,7 +429,7 @@ func TestGenericAfterUpdate(t *testing.T) {
|
||||||
fs.Handler = handlerMock
|
fs.Handler = handlerMock
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectExec("UPDATE(.+)files(.+)").
|
mock.ExpectExec("UPDATE(.+)files(.+)").
|
||||||
WithArgs(10, sqlmock.AnyArg(), 1, 0).
|
WithArgs("", 10, sqlmock.AnyArg(), 1, 0).
|
||||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
mock.ExpectExec("UPDATE(.+)users(.+)").
|
mock.ExpectExec("UPDATE(.+)users(.+)").
|
||||||
WithArgs(10, sqlmock.AnyArg()).
|
WithArgs(10, sqlmock.AnyArg()).
|
||||||
|
@ -462,7 +462,7 @@ func TestGenericAfterUpdate(t *testing.T) {
|
||||||
|
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectExec("UPDATE(.+)").
|
mock.ExpectExec("UPDATE(.+)").
|
||||||
WithArgs(10, sqlmock.AnyArg(), 1, 0).
|
WithArgs("", 10, sqlmock.AnyArg(), 1, 0).
|
||||||
WillReturnError(errors.New("error"))
|
WillReturnError(errors.New("error"))
|
||||||
mock.ExpectRollback()
|
mock.ExpectRollback()
|
||||||
|
|
||||||
|
@ -473,27 +473,6 @@ func TestGenericAfterUpdate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHookGenerateThumb(t *testing.T) {
|
|
||||||
a := assert.New(t)
|
|
||||||
mockHandler := &FileHeaderMock{}
|
|
||||||
fs := &FileSystem{
|
|
||||||
User: &model.User{
|
|
||||||
Model: gorm.Model{ID: 1},
|
|
||||||
},
|
|
||||||
Handler: mockHandler,
|
|
||||||
Policy: &model.Policy{Type: "local"},
|
|
||||||
}
|
|
||||||
|
|
||||||
mockHandler.On("Delete", testMock.Anything, []string{"1.txt._thumb"}).Return([]string{}, nil)
|
|
||||||
a.NoError(HookGenerateThumb(context.Background(), fs, &fsctx.FileStream{
|
|
||||||
Model: &model.File{
|
|
||||||
SourceName: "1.txt",
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
fs.Recycle()
|
|
||||||
mockHandler.AssertExpectations(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSlaveAfterUpload(t *testing.T) {
|
func TestSlaveAfterUpload(t *testing.T) {
|
||||||
asserts := assert.New(t)
|
asserts := assert.New(t)
|
||||||
conf.SystemConfig.Mode = "slave"
|
conf.SystemConfig.Mode = "slave"
|
||||||
|
@ -625,7 +604,7 @@ func TestHookChunkUploaded(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs(20, sqlmock.AnyArg(), 1, 0).WillReturnResult(sqlmock.NewResult(1, 1))
|
mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 20, sqlmock.AnyArg(), 1, 0).WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
mock.ExpectExec("UPDATE(.+)users(.+)").
|
mock.ExpectExec("UPDATE(.+)users(.+)").
|
||||||
WithArgs(20, sqlmock.AnyArg()).
|
WithArgs(20, sqlmock.AnyArg()).
|
||||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
|
@ -646,7 +625,7 @@ func TestHookChunkUploadFailed(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mock.ExpectBegin()
|
mock.ExpectBegin()
|
||||||
mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs(10, sqlmock.AnyArg(), 1, 0).WillReturnResult(sqlmock.NewResult(1, 1))
|
mock.ExpectExec("UPDATE(.+)files(.+)").WithArgs("", 10, sqlmock.AnyArg(), 1, 0).WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
mock.ExpectExec("UPDATE(.+)users(.+)").
|
mock.ExpectExec("UPDATE(.+)users(.+)").
|
||||||
WithArgs(10, sqlmock.AnyArg()).
|
WithArgs(10, sqlmock.AnyArg()).
|
||||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
|
|
|
@ -28,9 +28,7 @@ func (fs *FileSystem) GetThumb(ctx context.Context, id uint) (*response.ContentR
|
||||||
// 根据 ID 查找文件
|
// 根据 ID 查找文件
|
||||||
err := fs.resetFileIDIfNotExist(ctx, id)
|
err := fs.resetFileIDIfNotExist(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &response.ContentResponse{
|
return nil, ErrObjectNotExist
|
||||||
Redirect: false,
|
|
||||||
}, ErrObjectNotExist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file := fs.FileTarget[0]
|
file := fs.FileTarget[0]
|
||||||
|
@ -44,7 +42,7 @@ func (fs *FileSystem) GetThumb(ctx context.Context, id uint) (*response.ContentR
|
||||||
res, err := fs.Handler.Thumb(ctx, &file)
|
res, err := fs.Handler.Thumb(ctx, &file)
|
||||||
if errors.Is(err, driver.ErrorThumbNotExist) {
|
if errors.Is(err, driver.ErrorThumbNotExist) {
|
||||||
// Regenerate thumb if the thumb is not initialized yet
|
// Regenerate thumb if the thumb is not initialized yet
|
||||||
if generateErr := fs.GenerateThumbnail(ctx, &file); generateErr == nil {
|
if generateErr := fs.generateThumbnail(ctx, &file); generateErr == nil {
|
||||||
res, err = fs.Handler.Thumb(ctx, &file)
|
res, err = fs.Handler.Thumb(ctx, &file)
|
||||||
} else {
|
} else {
|
||||||
err = generateErr
|
err = generateErr
|
||||||
|
@ -69,7 +67,7 @@ func (fs *FileSystem) GetThumb(ctx context.Context, id uint) (*response.ContentR
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// if not exist, generate and upload the sidecar thumb.
|
// if not exist, generate and upload the sidecar thumb.
|
||||||
if err = fs.GenerateThumbnail(ctx, &file); err == nil {
|
if err = fs.generateThumbnail(ctx, &file); err == nil {
|
||||||
return fs.GetThumb(ctx, id)
|
return fs.GetThumb(ctx, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,8 +117,8 @@ func (pool *Pool) releaseWorker() {
|
||||||
<-pool.worker
|
<-pool.worker
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateThumbnail generates thumb for given file, upload the thumb file back with given suffix
|
// generateThumbnail generates thumb for given file, upload the thumb file back with given suffix
|
||||||
func (fs *FileSystem) GenerateThumbnail(ctx context.Context, file *model.File) error {
|
func (fs *FileSystem) generateThumbnail(ctx context.Context, file *model.File) error {
|
||||||
// 新建上下文
|
// 新建上下文
|
||||||
newCtx, cancel := context.WithCancel(context.Background())
|
newCtx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -164,13 +162,13 @@ func (fs *FileSystem) GenerateThumbnail(ctx context.Context, file *model.File) e
|
||||||
|
|
||||||
thumbFile, err := os.Open(thumbRes.Path)
|
thumbFile, err := os.Open(thumbRes.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open temp thumb %q: %w", thumbFile, err)
|
return fmt.Errorf("failed to open temp thumb %q: %w", thumbRes.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer thumbFile.Close()
|
defer thumbFile.Close()
|
||||||
fileInfo, err := thumbFile.Stat()
|
fileInfo, err := thumbFile.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to stat temp thumb %q: %w", thumbFile, err)
|
return fmt.Errorf("failed to stat temp thumb %q: %w", thumbRes.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = fs.Handler.Put(newCtx, &fsctx.FileStream{
|
if err = fs.Handler.Put(newCtx, &fsctx.FileStream{
|
||||||
|
@ -184,7 +182,7 @@ func (fs *FileSystem) GenerateThumbnail(ctx context.Context, file *model.File) e
|
||||||
}
|
}
|
||||||
|
|
||||||
if model.IsTrueVal(model.GetSettingByName("thumb_gc_after_gen")) {
|
if model.IsTrueVal(model.GetSettingByName("thumb_gc_after_gen")) {
|
||||||
util.Log().Debug("GenerateThumbnail runtime.GC")
|
util.Log().Debug("generateThumbnail runtime.GC")
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/mocks/thumbmock"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/request"
|
"github.com/cloudreve/Cloudreve/v3/pkg/request"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/thumb"
|
||||||
testMock "github.com/stretchr/testify/mock"
|
testMock "github.com/stretchr/testify/mock"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -14,30 +17,104 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFileSystem_GetThumb(t *testing.T) {
|
func TestFileSystem_GetThumb(t *testing.T) {
|
||||||
asserts := assert.New(t)
|
a := assert.New(t)
|
||||||
fs := &FileSystem{User: &model.User{}}
|
fs := &FileSystem{User: &model.User{}}
|
||||||
|
|
||||||
// 非图像文件
|
// file not found
|
||||||
{
|
{
|
||||||
fs.SetTargetFile(&[]model.File{{}})
|
mock.ExpectQuery("SELECT(.+)").WillReturnError(errors.New("error"))
|
||||||
_, err := fs.GetThumb(context.Background(), 1)
|
res, err := fs.GetThumb(context.Background(), 1)
|
||||||
asserts.Equal(err, ErrObjectNotExist)
|
a.ErrorIs(err, ErrObjectNotExist)
|
||||||
|
a.Nil(res)
|
||||||
|
a.NoError(mock.ExpectationsWereMet())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 成功
|
// thumb not exist
|
||||||
{
|
{
|
||||||
cache.Set("setting_thumb_width", "10", 0)
|
fs.SetTargetFile(&[]model.File{{
|
||||||
cache.Set("setting_thumb_height", "10", 0)
|
MetadataSerialized: map[string]string{
|
||||||
cache.Set("setting_preview_timeout", "50", 0)
|
model.ThumbStatusMetadataKey: model.ThumbStatusNotAvailable,
|
||||||
testHandller2 := new(FileHeaderMock)
|
},
|
||||||
testHandller2.On("Thumb", testMock.Anything, "").Return(&response.ContentResponse{}, nil)
|
Policy: model.Policy{Type: "mock"},
|
||||||
fs.CleanTargets()
|
}})
|
||||||
fs.SetTargetFile(&[]model.File{{PicInfo: "1,1", Policy: model.Policy{Type: "mock"}}})
|
|
||||||
fs.FileTarget[0].Policy.ID = 1
|
fs.FileTarget[0].Policy.ID = 1
|
||||||
fs.Handler = testHandller2
|
|
||||||
res, err := fs.GetThumb(context.Background(), 1)
|
res, err := fs.GetThumb(context.Background(), 1)
|
||||||
asserts.NoError(err)
|
a.ErrorIs(err, ErrObjectNotExist)
|
||||||
asserts.EqualValues(50, res.MaxAge)
|
a.Nil(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// thumb not initialized, also failed to generate
|
||||||
|
{
|
||||||
|
fs.CleanTargets()
|
||||||
|
fs.SetTargetFile(&[]model.File{{
|
||||||
|
Policy: model.Policy{Type: "mock"},
|
||||||
|
Size: 31457281,
|
||||||
|
}})
|
||||||
|
testHandller2 := new(FileHeaderMock)
|
||||||
|
testHandller2.On("Thumb", testMock.Anything, &fs.FileTarget[0]).Return(&response.ContentResponse{}, driver.ErrorThumbNotExist)
|
||||||
|
fs.Handler = testHandller2
|
||||||
|
fs.FileTarget[0].Policy.ID = 1
|
||||||
|
res, err := fs.GetThumb(context.Background(), 1)
|
||||||
|
a.Contains(err.Error(), "file too large")
|
||||||
|
a.Nil(res.Content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// thumb not initialized, failed to get source
|
||||||
|
{
|
||||||
|
fs.CleanTargets()
|
||||||
|
fs.SetTargetFile(&[]model.File{{
|
||||||
|
Policy: model.Policy{Type: "mock"},
|
||||||
|
}})
|
||||||
|
testHandller2 := new(FileHeaderMock)
|
||||||
|
testHandller2.On("Thumb", testMock.Anything, &fs.FileTarget[0]).Return(&response.ContentResponse{}, driver.ErrorThumbNotExist)
|
||||||
|
testHandller2.On("Get", testMock.Anything, "").Return(MockRSC{}, errors.New("error"))
|
||||||
|
fs.Handler = testHandller2
|
||||||
|
fs.FileTarget[0].Policy.ID = 1
|
||||||
|
res, err := fs.GetThumb(context.Background(), 1)
|
||||||
|
a.Contains(err.Error(), "error")
|
||||||
|
a.Nil(res.Content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// thumb not initialized, no available generators
|
||||||
|
{
|
||||||
|
thumb.Generators = []thumb.Generator{}
|
||||||
|
fs.CleanTargets()
|
||||||
|
fs.SetTargetFile(&[]model.File{{
|
||||||
|
Policy: model.Policy{Type: "local"},
|
||||||
|
}})
|
||||||
|
testHandller2 := new(FileHeaderMock)
|
||||||
|
testHandller2.On("Thumb", testMock.Anything, &fs.FileTarget[0]).Return(&response.ContentResponse{}, driver.ErrorThumbNotExist)
|
||||||
|
testHandller2.On("Get", testMock.Anything, "").Return(MockRSC{}, nil)
|
||||||
|
fs.Handler = testHandller2
|
||||||
|
fs.FileTarget[0].Policy.ID = 1
|
||||||
|
res, err := fs.GetThumb(context.Background(), 1)
|
||||||
|
a.ErrorIs(err, thumb.ErrNotAvailable)
|
||||||
|
a.Nil(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// thumb not initialized, thumb generated but cannot be open
|
||||||
|
{
|
||||||
|
mockGenerator := &thumbmock.GeneratorMock{}
|
||||||
|
thumb.Generators = []thumb.Generator{mockGenerator}
|
||||||
|
fs.CleanTargets()
|
||||||
|
fs.SetTargetFile(&[]model.File{{
|
||||||
|
Policy: model.Policy{Type: "mock"},
|
||||||
|
}})
|
||||||
|
cache.Set("setting_thumb_vips_enabled", "1", 0)
|
||||||
|
testHandller2 := new(FileHeaderMock)
|
||||||
|
testHandller2.On("Thumb", testMock.Anything, &fs.FileTarget[0]).Return(&response.ContentResponse{}, driver.ErrorThumbNotExist)
|
||||||
|
testHandller2.On("Get", testMock.Anything, "").Return(MockRSC{}, nil)
|
||||||
|
mockGenerator.On("Generate", testMock.Anything, testMock.Anything, testMock.Anything, testMock.Anything, testMock.Anything).
|
||||||
|
Return(&thumb.Result{Path: "not_exit_thumb"}, nil)
|
||||||
|
|
||||||
|
fs.Handler = testHandller2
|
||||||
|
fs.FileTarget[0].Policy.ID = 1
|
||||||
|
res, err := fs.GetThumb(context.Background(), 1)
|
||||||
|
a.Contains(err.Error(), "failed to open temp thumb")
|
||||||
|
a.Nil(res.Content)
|
||||||
|
testHandller2.AssertExpectations(t)
|
||||||
|
mockGenerator.AssertExpectations(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +133,7 @@ func TestFileSystem_GenerateThumbnail(t *testing.T) {
|
||||||
// 无法生成缩略图
|
// 无法生成缩略图
|
||||||
{
|
{
|
||||||
fs.SetTargetFile(&[]model.File{{}})
|
fs.SetTargetFile(&[]model.File{{}})
|
||||||
fs.GenerateThumbnail(context.Background(), &model.File{})
|
fs.generateThumbnail(context.Background(), &model.File{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 无法获取文件数据
|
// 无法获取文件数据
|
||||||
|
@ -64,7 +141,7 @@ func TestFileSystem_GenerateThumbnail(t *testing.T) {
|
||||||
testHandller := new(FileHeaderMock)
|
testHandller := new(FileHeaderMock)
|
||||||
testHandller.On("Get", testMock.Anything, "").Return(request.NopRSCloser{}, errors.New("error"))
|
testHandller.On("Get", testMock.Anything, "").Return(request.NopRSCloser{}, errors.New("error"))
|
||||||
fs.Handler = testHandller
|
fs.Handler = testHandller
|
||||||
fs.GenerateThumbnail(context.Background(), &model.File{Name: "test.png"})
|
fs.generateThumbnail(context.Background(), &model.File{Name: "test.png"})
|
||||||
testHandller.AssertExpectations(t)
|
testHandller.AssertExpectations(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ func (m FileHeaderMock) Delete(ctx context.Context, files []string) ([]string, e
|
||||||
return args.Get(0).([]string), args.Error(1)
|
return args.Get(0).([]string), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FileHeaderMock) Thumb(ctx context.Context, files string) (*response.ContentResponse, error) {
|
func (m FileHeaderMock) Thumb(ctx context.Context, files *model.File) (*response.ContentResponse, error) {
|
||||||
args := m.Called(ctx, files)
|
args := m.Called(ctx, files)
|
||||||
return args.Get(0).(*response.ContentResponse), args.Error(1)
|
return args.Get(0).(*response.ContentResponse), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package thumbmock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/thumb"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GeneratorMock struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GeneratorMock) Generate(ctx context.Context, file io.Reader, src string, name string, options map[string]string) (*thumb.Result, error) {
|
||||||
|
res := g.Called(ctx, file, src, name, options)
|
||||||
|
return res.Get(0).(*thumb.Result), res.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GeneratorMock) Priority() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GeneratorMock) EnableFlag() string {
|
||||||
|
return "thumb_vips_enabled"
|
||||||
|
}
|
|
@ -1,146 +0,0 @@
|
||||||
package thumb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"image"
|
|
||||||
"image/jpeg"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CreateTestImage() *os.File {
|
|
||||||
file, err := os.Create("TestNewThumbFromFile.jpeg")
|
|
||||||
alpha := image.NewAlpha(image.Rect(0, 0, 500, 200))
|
|
||||||
jpeg.Encode(file, alpha, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
_, _ = file.Seek(0, 0)
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewThumbFromFile(t *testing.T) {
|
|
||||||
asserts := assert.New(t)
|
|
||||||
file := CreateTestImage()
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// 无扩展名时
|
|
||||||
{
|
|
||||||
thumb, err := NewThumbFromFile(file, "123")
|
|
||||||
asserts.Error(err)
|
|
||||||
asserts.Nil(thumb)
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.jpg")
|
|
||||||
asserts.NoError(err)
|
|
||||||
asserts.NotNil(thumb)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.jpeg")
|
|
||||||
asserts.Error(err)
|
|
||||||
asserts.Nil(thumb)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.png")
|
|
||||||
asserts.Error(err)
|
|
||||||
asserts.Nil(thumb)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.gif")
|
|
||||||
asserts.Error(err)
|
|
||||||
asserts.Nil(thumb)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.3211")
|
|
||||||
asserts.Error(err)
|
|
||||||
asserts.Nil(thumb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThumb_GetSize(t *testing.T) {
|
|
||||||
asserts := assert.New(t)
|
|
||||||
file := CreateTestImage()
|
|
||||||
defer file.Close()
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.jpg")
|
|
||||||
asserts.NoError(err)
|
|
||||||
|
|
||||||
w, h := thumb.GetSize()
|
|
||||||
asserts.Equal(500, w)
|
|
||||||
asserts.Equal(200, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThumb_GetThumb(t *testing.T) {
|
|
||||||
asserts := assert.New(t)
|
|
||||||
file := CreateTestImage()
|
|
||||||
defer file.Close()
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.jpg")
|
|
||||||
asserts.NoError(err)
|
|
||||||
|
|
||||||
asserts.NotPanics(func() {
|
|
||||||
thumb.GetThumb(10, 10)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThumb_Thumbnail(t *testing.T) {
|
|
||||||
asserts := assert.New(t)
|
|
||||||
{
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, 500, 200))
|
|
||||||
thumb := Thumbnail(100, 100, img)
|
|
||||||
asserts.Equal(thumb.Bounds(), image.Rect(0, 0, 100, 40))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, 200, 200))
|
|
||||||
thumb := Thumbnail(100, 100, img)
|
|
||||||
asserts.Equal(thumb.Bounds(), image.Rect(0, 0, 100, 100))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, 500, 500))
|
|
||||||
thumb := Thumbnail(100, 100, img)
|
|
||||||
asserts.Equal(thumb.Bounds(), image.Rect(0, 0, 100, 100))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, 200, 500))
|
|
||||||
thumb := Thumbnail(100, 100, img)
|
|
||||||
asserts.Equal(thumb.Bounds(), image.Rect(0, 0, 40, 100))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThumb_Save(t *testing.T) {
|
|
||||||
asserts := assert.New(t)
|
|
||||||
file := CreateTestImage()
|
|
||||||
defer file.Close()
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.jpg")
|
|
||||||
asserts.NoError(err)
|
|
||||||
|
|
||||||
err = thumb.Save("/:noteexist/")
|
|
||||||
asserts.Error(err)
|
|
||||||
|
|
||||||
err = thumb.Save("TestThumb_Save.png")
|
|
||||||
asserts.NoError(err)
|
|
||||||
asserts.True(util.Exists("TestThumb_Save.png"))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThumb_CreateAvatar(t *testing.T) {
|
|
||||||
asserts := assert.New(t)
|
|
||||||
file := CreateTestImage()
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
thumb, err := NewThumbFromFile(file, "123.jpg")
|
|
||||||
asserts.NoError(err)
|
|
||||||
|
|
||||||
cache.Set("setting_avatar_path", "tests", 0)
|
|
||||||
cache.Set("setting_avatar_size_s", "50", 0)
|
|
||||||
cache.Set("setting_avatar_size_m", "130", 0)
|
|
||||||
cache.Set("setting_avatar_size_l", "200", 0)
|
|
||||||
|
|
||||||
asserts.NoError(thumb.CreateAvatar(1))
|
|
||||||
asserts.True(util.Exists(util.RelativePath("tests/avatar_1_1.png")))
|
|
||||||
asserts.True(util.Exists(util.RelativePath("tests/avatar_1_2.png")))
|
|
||||||
asserts.True(util.Exists(util.RelativePath("tests/avatar_1_0.png")))
|
|
||||||
}
|
|
Loading…
Reference in New Issue