Files
ttstd-infinite-canvas/backend/internal/service/resource_oss_fallback_test.go

108 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"bytes"
"os"
"path/filepath"
"testing"
"infinite-canvas/backend/internal/model"
"infinite-canvas/backend/internal/repository"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func newResourceFallbackTestService(t *testing.T) (*Service, *gorm.DB) {
t.Helper()
db, err := gorm.Open(sqlite.Open("file:"+newID()+"?mode=memory&cache=shared"), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
if err := db.AutoMigrate(
&model.Resource{},
&model.UserOSSSetting{},
&model.SystemSetting{},
&model.StorageLocation{},
&model.UserDailyActivity{},
); err != nil {
t.Fatal(err)
}
return &Service{repo: repository.New(db), dataDir: t.TempDir()}, db
}
// TestStoreResourceDegradesToLocalWhenOSSUnavailable 覆盖对象存储不可用时的降级:
// 配置了 OSS(enabled=1、endpoint 不可达)时上传应回退本地存储成功,
// 而不是把上传标记为失败——本地媒体导入不应因外部存储故障整体失败。
func TestStoreResourceDegradesToLocalWhenOSSUnavailable(t *testing.T) {
service, db := newResourceFallbackTestService(t)
seedOSSEnabled(t, db, "user-1", "http://127.0.0.1:1")
resource, created, err := service.storeResource(
"user-1", "video", "intro.mp4", "video/mp4", 1024,
1920, 1080, 0, bytes.NewReader([]byte("fake-mp4-bytes")), nil, false,
)
if err != nil {
t.Fatalf("storeResource: %v", err)
}
if !created {
t.Fatal("storeResource returned created=false, want true")
}
if resource.Status != model.ResourceStatusReady {
t.Fatalf("resource.Status = %q, want %q", resource.Status, model.ResourceStatusReady)
}
if resource.Provider != "local" {
t.Fatalf("resource.Provider = %q, want local (degraded from OSS)", resource.Provider)
}
if resource.Endpoint != "" || resource.Bucket != "" || resource.StorageSettingID != "" {
t.Fatalf("resource storage binding not cleared after degrade: endpoint=%q bucket=%q setting=%q",
resource.Endpoint, resource.Bucket, resource.StorageSettingID)
}
payload, err := os.ReadFile(filepath.Join(service.dataDir, "resources", filepath.FromSlash(resource.ObjectKey)))
if err != nil {
t.Fatalf("local object not written: %v", err)
}
if string(payload) != "fake-mp4-bytes" {
t.Fatalf("local object content = %q, want fake-mp4-bytes", payload)
}
}
// TestStoreResourceLocalPathUnaffectedByOSS 未启用 OSS 时上传仍走本地存储,不受其他用户 OSS 设置影响。
func TestStoreResourceLocalPathUnaffectedByOSS(t *testing.T) {
service, db := newResourceFallbackTestService(t)
seedOSSEnabled(t, db, "user-other", "http://127.0.0.1:1")
resource, created, err := service.storeResource(
"user-2", "video", "local.mp4", "video/mp4", 512,
1280, 720, 0, bytes.NewReader([]byte("local-bytes")), nil, false,
)
if err != nil {
t.Fatalf("storeResource: %v", err)
}
if !created {
t.Fatal("storeResource returned created=false, want true")
}
if resource.Provider != "local" {
t.Fatalf("resource.Provider = %q, want local", resource.Provider)
}
payload, err := os.ReadFile(filepath.Join(service.dataDir, "resources", filepath.FromSlash(resource.ObjectKey)))
if err != nil {
t.Fatalf("local object not written: %v", err)
}
if string(payload) != "local-bytes" {
t.Fatalf("local object content = %q, want local-bytes", payload)
}
}
func seedOSSEnabled(t *testing.T, db *gorm.DB, userID string, endpoint string) {
t.Helper()
setting := model.UserOSSSetting{
UserID: userID,
Enabled: true,
ValueJSON: `{"provider":"aliyun","endpoint":"` + endpoint + `","bucket":"test-bucket","accessKeyId":"ak-test","accessKeySecret":"sk-plaintext","region":"cn-shenzhen"}`,
}
if err := db.Create(&setting).Error; err != nil {
t.Fatal(err)
}
}