Files
im_server/server/media/oss/oss_tenant_test.go
T

148 lines
4.8 KiB
Go

package oss
import (
"bytes"
"io"
"net/http"
"strings"
"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 TestOSSReadSeekCloser(t *testing.T) {
data := []byte("0123456789")
reader := &ossReadSeekCloser{
size: int64(len(data)),
open: func(offset int64) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(data[offset:])), nil
},
}
defer reader.Close()
buf := make([]byte, 3)
if n, err := reader.Read(buf); err != nil || n != 3 || string(buf) != "012" {
t.Fatalf("initial read = %q, %d, %v", buf, n, err)
}
if pos, err := reader.Seek(-2, io.SeekEnd); err != nil || pos != 8 {
t.Fatalf("seek end = %d, %v", pos, err)
}
if n, err := reader.Read(buf); err != nil && err != io.EOF || n != 2 || string(buf[:n]) != "89" {
t.Fatalf("ranged read = %q, %d, %v", buf[:n], n, err)
}
if pos, err := reader.Seek(4, io.SeekStart); err != nil || pos != 4 {
t.Fatalf("seek start = %d, %v", pos, err)
}
if n, err := reader.Read(buf[:2]); err != nil || n != 2 || string(buf[:2]) != "45" {
t.Fatalf("second ranged read = %q, %d, %v", buf[:2], n, err)
}
}
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)
}
}
func TestOSSEndpointUsesHTTPS(t *testing.T) {
for _, endpoint := range []string{
"oss-cn-shenzhen.aliyuncs.com",
"http://oss-cn-shenzhen.aliyuncs.com",
"https://oss-cn-shenzhen.aliyuncs.com",
} {
handler := &ossHandler{}
config := `{"endpoint":"` + endpoint + `","access_key_id":"ak","access_key_secret":"sk","bucket":"im-files"}`
if err := handler.Init(config); err != nil {
t.Fatalf("Init(%q): %v", endpoint, err)
}
signedURL, err := handler.bucket.SignURL("test.txt", aliyunoss.HTTPGet, 60)
if err != nil {
t.Fatalf("SignURL(%q): %v", endpoint, err)
}
if !strings.HasPrefix(signedURL, "https://") {
t.Fatalf("endpoint %q produced non-HTTPS URL %q", endpoint, signedURL)
}
}
}