107 lines
3.7 KiB
Go
107 lines
3.7 KiB
Go
package oss
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
aliyunoss "github.com/aliyun/aliyun-oss-go-sdk/oss"
|
|
|
|
"github.com/tinode/chat/server/store"
|
|
"github.com/tinode/chat/server/store/types"
|
|
)
|
|
|
|
type fakeThirdPartyConfig map[string]string
|
|
|
|
func (f fakeThirdPartyConfig) Get(group string, keys ...string) (map[string]string, error) {
|
|
result := map[string]string{}
|
|
for _, key := range keys {
|
|
if value, ok := f[key]; ok {
|
|
result[key] = value
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func TestTenantObjectKey(t *testing.T) {
|
|
got, err := tenantObjectKey(types.TenantID(42), "abc123", time.Date(2026, 8, 11, 9, 0, 0, 0, time.UTC))
|
|
if err != nil {
|
|
t.Fatalf("tenantObjectKey failed: %v", err)
|
|
}
|
|
if want := "tenants/42/2026/08/abc123"; got != want {
|
|
t.Fatalf("tenantObjectKey = %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestTenantObjectKeyRejectsZeroTenant(t *testing.T) {
|
|
if _, err := tenantObjectKey(types.ZeroTenantID, "abc123", time.Time{}); err != types.ErrMalformed {
|
|
t.Fatalf("tenantObjectKey err = %v, want malformed", err)
|
|
}
|
|
}
|
|
|
|
func TestGetIdFromUrl(t *testing.T) {
|
|
handler := ossHandler{conf: ossConfig{ServeURL: "/v0/file/s/"}}
|
|
|
|
fid := types.Uid(123456)
|
|
got := handler.GetIdFromUrl("/v0/file/s/" + fid.String() + ".jpg")
|
|
if got != fid {
|
|
t.Fatalf("GetIdFromUrl = %v, want %v", got, fid)
|
|
}
|
|
}
|
|
|
|
func TestIsOSSObjectNotFound(t *testing.T) {
|
|
if !isOSSObjectNotFound(aliyunoss.ServiceError{StatusCode: http.StatusNotFound, Code: "NoSuchKey"}) {
|
|
t.Fatal("NoSuchKey should be treated as missing object")
|
|
}
|
|
if isOSSObjectNotFound(aliyunoss.ServiceError{StatusCode: http.StatusForbidden, Code: "AccessDenied"}) {
|
|
t.Fatal("AccessDenied must not be treated as missing object")
|
|
}
|
|
}
|
|
|
|
func TestNormalizeSignedRedirectURL(t *testing.T) {
|
|
rawURL := "http://im-oss-t1.oss-cn-shenzhen.aliyuncs.com/tenants/1/avatar.jpg?Expires=1&OSSAccessKeyId=ak&Signature=sig"
|
|
want := "https://im-oss-t1.oss-cn-shenzhen.aliyuncs.com/tenants/1/avatar.jpg?Expires=1&OSSAccessKeyId=ak&Signature=sig"
|
|
if got := normalizeSignedRedirectURL(rawURL); got != want {
|
|
t.Fatalf("normalizeSignedRedirectURL()=%q, want %q", got, want)
|
|
}
|
|
if got := normalizeSignedRedirectURL("/v0/file/s/avatar.jpg"); got != "/v0/file/s/avatar.jpg" {
|
|
t.Fatalf("relative URL must be unchanged, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestLoadSysConfig(t *testing.T) {
|
|
original := store.ThirdPartyConfig
|
|
store.ThirdPartyConfig = fakeThirdPartyConfig{
|
|
"oss_enabled": "1",
|
|
"oss_provider": "oss",
|
|
"oss_endpoint": "oss-cn-shenzhen.aliyuncs.com",
|
|
"oss_bucket": "im-files",
|
|
"oss_region_id": "cn-shenzhen",
|
|
"oss_access_key_id": "ak",
|
|
"oss_access_key_secret": "sk",
|
|
"oss_presign_ttl": "300",
|
|
"oss_serve_url": "/files/",
|
|
"oss_cache_control": "private",
|
|
"oss_cors_origins": `["https://example.com"]`,
|
|
"oss_verify_bucket": "true",
|
|
}
|
|
defer func() { store.ThirdPartyConfig = original }()
|
|
|
|
handler := ossHandler{conf: ossConfig{UseSysConfig: true}}
|
|
if err := handler.loadSysConfig(); err != nil {
|
|
t.Fatalf("loadSysConfig failed: %v", err)
|
|
}
|
|
if handler.conf.Endpoint != "oss-cn-shenzhen.aliyuncs.com" || handler.conf.BucketName != "im-files" {
|
|
t.Fatalf("unexpected OSS config: %+v", handler.conf)
|
|
}
|
|
if handler.conf.RegionID != "cn-shenzhen" || handler.conf.PresignTTL != 300 {
|
|
t.Fatalf("unexpected OSS region or ttl: %+v", handler.conf)
|
|
}
|
|
if handler.conf.ServeURL != "/files/" || handler.conf.CacheControl != "private" || !handler.conf.VerifyBucket {
|
|
t.Fatalf("unexpected OSS serve settings: %+v", handler.conf)
|
|
}
|
|
if len(handler.conf.CorsOrigins) != 1 || handler.conf.CorsOrigins[0] != "https://example.com" {
|
|
t.Fatalf("unexpected OSS cors origins: %+v", handler.conf.CorsOrigins)
|
|
}
|
|
}
|