Files
easyai-ai-gateway/apps/api/internal/httpapi/system_settings_handlers_test.go
T
wangbo 6a64d3936a feat(storage): 完善对象存储配置与过期策略
补齐 OSS/S3 的 Endpoint、Region、Bucket、CDN、对象前缀和签名有效期配置,并为生成结果与请求素材自动维护分级生命周期规则。普通上传继续保持永久,私有资源按配置生成限时签名 URL,管理端连接测试覆盖生命周期、上传、读取和删除。\n\n新增可重复的真实 OSS 验收脚本,凭据仅从本地环境读取,接口响应继续保持脱敏。\n\n验证:Go 全量测试、迁移安全检查、pnpm lint、pnpm test、pnpm build、本地阿里云 OSS 真实上传下载删除验收。
2026-08-04 12:44:24 +08:00

87 lines
3.5 KiB
Go

package httpapi
import (
"strings"
"testing"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)
func TestValidateObjectStorageChannelAcceptsS3CredentialAliases(t *testing.T) {
accessKey := "access"
secretKey := "secret"
input := store.FileStorageChannelInput{
ChannelKey: "s3-primary", Name: "S3 primary", Provider: "s3", Status: "enabled",
AccessKey: &accessKey, SecretKey: &secretKey,
Config: map[string]any{
"endpoint": "https://s3.example.com", "region": "us-east-1", "bucket": "media",
},
}
if message := validateFileStorageChannelInput(input, nil); message != "" {
t.Fatalf("valid S3 channel rejected: %s", message)
}
}
func TestValidateObjectStorageChannelRejectsCredentialsInConfig(t *testing.T) {
accessKeyID := "access"
accessKeySecret := "secret"
input := store.FileStorageChannelInput{
ChannelKey: "oss-primary", Name: "OSS primary", Provider: "aliyun_oss", Status: "enabled",
AccessKeyID: &accessKeyID, AccessKeySecret: &accessKeySecret,
Config: map[string]any{
"endpoint": "https://oss-cn-hangzhou.aliyuncs.com", "region": "cn-hangzhou", "bucket": "media",
"nested": map[string]any{"session_token": "must-not-be-public"},
},
}
message := validateFileStorageChannelInput(input, nil)
if !strings.Contains(message, "write-only credential fields") {
t.Fatalf("credential-bearing config was accepted: %q", message)
}
}
func TestValidateObjectStorageChannelRejectsCredentialedEndpoint(t *testing.T) {
accessKeyID := "access"
accessKeySecret := "secret"
input := store.FileStorageChannelInput{
ChannelKey: "s3-primary", Name: "S3 primary", Provider: "s3", Status: "enabled",
AccessKeyID: &accessKeyID, AccessKeySecret: &accessKeySecret,
Config: map[string]any{
"endpoint": "https://user:password@s3.example.com", "region": "us-east-1", "bucket": "media",
},
}
if message := validateFileStorageChannelInput(input, nil); !strings.Contains(message, "without embedded credentials") {
t.Fatalf("credentialed endpoint was accepted: %q", message)
}
}
func TestValidateObjectStorageChannelAcceptsExpirationAndCDNAliases(t *testing.T) {
input := store.FileStorageChannelInput{
ChannelKey: "oss-expiring", Name: "OSS expiring", Provider: "aliyun_oss", Status: "disabled",
Config: map[string]any{
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "region": "cn-shanghai", "bucket": "media",
"cdnDomain": "https://cdn.example.com", "temporaryFileExpirePolicy": "3m", "signedUrlExpiresSeconds": float64(3600),
},
}
if message := validateFileStorageChannelInput(input, nil); message != "" {
t.Fatalf("valid object storage expiration config rejected: %s", message)
}
}
func TestValidateObjectStorageChannelRejectsInvalidExpiration(t *testing.T) {
base := store.FileStorageChannelInput{
ChannelKey: "oss-expiring", Name: "OSS expiring", Provider: "aliyun_oss", Status: "disabled",
Config: map[string]any{
"endpoint": "https://oss-cn-shanghai.aliyuncs.com", "region": "cn-shanghai", "bucket": "media",
"temporaryFileExpirePolicy": "7d", "signedUrlExpiresSeconds": float64(3600),
},
}
if message := validateFileStorageChannelInput(base, nil); !strings.Contains(message, "temporaryFileExpirePolicy") {
t.Fatalf("invalid expiration policy was accepted: %q", message)
}
base.Config["temporaryFileExpirePolicy"] = "1d"
base.Config["signedUrlExpiresSeconds"] = float64(30)
if message := validateFileStorageChannelInput(base, nil); !strings.Contains(message, "signedUrlExpiresSeconds") {
t.Fatalf("invalid signed URL TTL was accepted: %q", message)
}
}