mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-10-31 08:39:10 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			354 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package oss
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"io"
 | |
| 	"io/ioutil"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 
 | |
| 	model "github.com/cloudreve/Cloudreve/v3/models"
 | |
| 	"github.com/cloudreve/Cloudreve/v3/pkg/cache"
 | |
| 	"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
 | |
| 	"github.com/cloudreve/Cloudreve/v3/pkg/request"
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	testMock "github.com/stretchr/testify/mock"
 | |
| )
 | |
| 
 | |
| func TestDriver_InitOSSClient(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "test.com",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 成功
 | |
| 	{
 | |
| 		asserts.NoError(handler.InitOSSClient(false))
 | |
| 	}
 | |
| 
 | |
| 	// 使用内网Endpoint
 | |
| 	{
 | |
| 		handler.Policy.OptionsSerialized.ServerSideEndpoint = "endpoint2"
 | |
| 		asserts.NoError(handler.InitOSSClient(false))
 | |
| 	}
 | |
| 
 | |
| 	// 未指定存储策略
 | |
| 	{
 | |
| 		handler := Driver{}
 | |
| 		asserts.Error(handler.InitOSSClient(false))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDriver_CORS(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "test.com",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 失败
 | |
| 	{
 | |
| 		asserts.NotPanics(func() {
 | |
| 			handler.CORS()
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDriver_Token(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "test.com",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 成功
 | |
| 	{
 | |
| 		ctx := context.WithValue(context.Background(), fsctx.SavePathCtx, "/123")
 | |
| 		cache.Set("setting_siteURL", "http://test.cloudreve.org", 0)
 | |
| 		res, err := handler.Token(ctx, 10, "key")
 | |
| 		asserts.NoError(err)
 | |
| 		asserts.NotEmpty(res.Policy)
 | |
| 		asserts.NotEmpty(res.Token)
 | |
| 		asserts.Equal(handler.Policy.AccessKey, res.AccessKey)
 | |
| 		asserts.Equal("/123", res.Path)
 | |
| 	}
 | |
| 
 | |
| 	// 上下文错误
 | |
| 	{
 | |
| 		ctx := context.Background()
 | |
| 		_, err := handler.Token(ctx, 10, "key")
 | |
| 		asserts.Error(err)
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| func TestDriver_Source(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "test.com",
 | |
| 			IsPrivate:  true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 正常 非下载 无限速
 | |
| 	{
 | |
| 		res, err := handler.Source(context.Background(), "/123", url.URL{}, 10, false, 0)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.NotEmpty(query.Get("Signature"))
 | |
| 		asserts.NotEmpty(query.Get("Expires"))
 | |
| 		asserts.Equal("ak", query.Get("OSSAccessKeyId"))
 | |
| 	}
 | |
| 
 | |
| 	// 限速 + 下载
 | |
| 	{
 | |
| 		ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Name: "123.txt"})
 | |
| 		res, err := handler.Source(ctx, "/123", url.URL{}, 10, true, 102401)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.NotEmpty(query.Get("Signature"))
 | |
| 		asserts.NotEmpty(query.Get("Expires"))
 | |
| 		asserts.Equal("ak", query.Get("OSSAccessKeyId"))
 | |
| 		asserts.EqualValues("819208", query.Get("x-oss-traffic-limit"))
 | |
| 		asserts.NotEmpty(query.Get("response-content-disposition"))
 | |
| 	}
 | |
| 
 | |
| 	// 限速超出范围 + 下载
 | |
| 	{
 | |
| 		ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Name: "123.txt"})
 | |
| 		res, err := handler.Source(ctx, "/123", url.URL{}, 10, true, 10)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.NotEmpty(query.Get("Signature"))
 | |
| 		asserts.NotEmpty(query.Get("Expires"))
 | |
| 		asserts.Equal("ak", query.Get("OSSAccessKeyId"))
 | |
| 		asserts.EqualValues("819200", query.Get("x-oss-traffic-limit"))
 | |
| 		asserts.NotEmpty(query.Get("response-content-disposition"))
 | |
| 	}
 | |
| 
 | |
| 	// 限速超出范围 + 下载
 | |
| 	{
 | |
| 		ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Name: "123.txt"})
 | |
| 		res, err := handler.Source(ctx, "/123", url.URL{}, 10, true, 838860801)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.NotEmpty(query.Get("Signature"))
 | |
| 		asserts.NotEmpty(query.Get("Expires"))
 | |
| 		asserts.Equal("ak", query.Get("OSSAccessKeyId"))
 | |
| 		asserts.EqualValues("838860800", query.Get("x-oss-traffic-limit"))
 | |
| 		asserts.NotEmpty(query.Get("response-content-disposition"))
 | |
| 	}
 | |
| 
 | |
| 	// 公共空间
 | |
| 	{
 | |
| 		handler.Policy.IsPrivate = false
 | |
| 		res, err := handler.Source(context.Background(), "/123", url.URL{}, 10, false, 0)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.Empty(query.Get("Signature"))
 | |
| 	}
 | |
| 
 | |
| 	// 正常 指定了CDN域名
 | |
| 	{
 | |
| 		handler.Policy.BaseURL = "https://cqu.edu.cn"
 | |
| 		res, err := handler.Source(context.Background(), "/123", url.URL{}, 10, false, 0)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.Empty(query.Get("Signature"))
 | |
| 		asserts.Contains(resURL.String(), handler.Policy.BaseURL)
 | |
| 	}
 | |
| 
 | |
| 	// 强制使用公网 Endpoint
 | |
| 	{
 | |
| 		handler.Policy.BaseURL = ""
 | |
| 		handler.Policy.OptionsSerialized.ServerSideEndpoint = "endpoint.com"
 | |
| 		res, err := handler.Source(context.WithValue(context.Background(), fsctx.ForceUsePublicEndpoint, false), "/123", url.URL{}, 10, false, 0)
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res)
 | |
| 		asserts.NoError(err)
 | |
| 		query := resURL.Query()
 | |
| 		asserts.Empty(query.Get("Signature"))
 | |
| 		asserts.Contains(resURL.String(), "endpoint.com")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDriver_Thumb(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "test.com",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 上下文不存在
 | |
| 	{
 | |
| 		ctx := context.Background()
 | |
| 		res, err := handler.Thumb(ctx, "/123.txt")
 | |
| 		asserts.Error(err)
 | |
| 		asserts.Nil(res)
 | |
| 	}
 | |
| 
 | |
| 	// 成功
 | |
| 	{
 | |
| 		cache.Set("setting_preview_timeout", "60", 0)
 | |
| 		ctx := context.WithValue(context.Background(), fsctx.ThumbSizeCtx, [2]uint{10, 20})
 | |
| 		res, err := handler.Thumb(ctx, "/123.jpg")
 | |
| 		asserts.NoError(err)
 | |
| 		resURL, err := url.Parse(res.URL)
 | |
| 		asserts.NoError(err)
 | |
| 		urlQuery := resURL.Query()
 | |
| 		asserts.Equal("image/resize,m_lfit,h_20,w_10", urlQuery.Get("x-oss-process"))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDriver_Delete(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "oss-cn-shanghai.aliyuncs.com",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 失败
 | |
| 	{
 | |
| 		res, err := handler.Delete(context.Background(), []string{"1", "2", "3"})
 | |
| 		asserts.Error(err)
 | |
| 		asserts.Equal([]string{"1", "2", "3"}, res)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDriver_Put(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "oss-cn-shanghai.aliyuncs.com",
 | |
| 		},
 | |
| 	}
 | |
| 	cache.Set("setting_upload_credential_timeout", "3600", 0)
 | |
| 
 | |
| 	// 失败
 | |
| 	{
 | |
| 		err := handler.Put(context.Background(), ioutil.NopCloser(strings.NewReader("123")), "/123.txt", 3)
 | |
| 		asserts.Error(err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type ClientMock struct {
 | |
| 	testMock.Mock
 | |
| }
 | |
| 
 | |
| func (m ClientMock) Request(method, target string, body io.Reader, opts ...request.Option) *request.Response {
 | |
| 	args := m.Called(method, target, body, opts)
 | |
| 	return args.Get(0).(*request.Response)
 | |
| }
 | |
| 
 | |
| func TestDriver_Get(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "oss-cn-shanghai.aliyuncs.com",
 | |
| 		},
 | |
| 		HTTPClient: request.HTTPClient{},
 | |
| 	}
 | |
| 	cache.Set("setting_preview_timeout", "3600", 0)
 | |
| 
 | |
| 	// 响应失败
 | |
| 	{
 | |
| 		res, err := handler.Get(context.Background(), "123.txt")
 | |
| 		asserts.Error(err)
 | |
| 		asserts.Nil(res)
 | |
| 	}
 | |
| 
 | |
| 	// 响应成功
 | |
| 	{
 | |
| 		ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Size: 3})
 | |
| 		clientMock := ClientMock{}
 | |
| 		clientMock.On(
 | |
| 			"Request",
 | |
| 			"GET",
 | |
| 			testMock.Anything,
 | |
| 			testMock.Anything,
 | |
| 			testMock.Anything,
 | |
| 		).Return(&request.Response{
 | |
| 			Err: nil,
 | |
| 			Response: &http.Response{
 | |
| 				StatusCode: 200,
 | |
| 				Body:       ioutil.NopCloser(strings.NewReader(`123`)),
 | |
| 			},
 | |
| 		})
 | |
| 		handler.HTTPClient = clientMock
 | |
| 		res, err := handler.Get(ctx, "123.txt")
 | |
| 		clientMock.AssertExpectations(t)
 | |
| 		asserts.NoError(err)
 | |
| 		n, err := res.Seek(0, io.SeekEnd)
 | |
| 		asserts.NoError(err)
 | |
| 		asserts.EqualValues(3, n)
 | |
| 		content, err := ioutil.ReadAll(res)
 | |
| 		asserts.NoError(err)
 | |
| 		asserts.Equal("123", string(content))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestDriver_List(t *testing.T) {
 | |
| 	asserts := assert.New(t)
 | |
| 	handler := Driver{
 | |
| 		Policy: &model.Policy{
 | |
| 			AccessKey:  "ak",
 | |
| 			SecretKey:  "sk",
 | |
| 			BucketName: "test",
 | |
| 			Server:     "test.com",
 | |
| 			IsPrivate:  true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// 连接失败
 | |
| 	{
 | |
| 		res, err := handler.List(context.Background(), "/", true)
 | |
| 		asserts.Error(err)
 | |
| 		asserts.Empty(res)
 | |
| 	}
 | |
| }
 | 
