Files
NianAIGC/backend/internal/assets/oss_test.go

96 lines
3.5 KiB
Go

package assets
import (
"bytes"
"context"
"errors"
"io"
"testing"
)
type ossClientStub struct {
puts []OSSPutRequest
acls []OSSACLRequest
gets []OSSObjectRequest
deletes []OSSObjectRequest
body []byte
contentType string
getErr, errorToReturn error
}
func (s *ossClientStub) Put(_ context.Context, r OSSPutRequest) error {
s.puts = append(s.puts, r)
_, _ = io.ReadAll(r.Body)
return s.errorToReturn
}
func (s *ossClientStub) SetACL(_ context.Context, r OSSACLRequest) error {
s.acls = append(s.acls, r)
return s.errorToReturn
}
func (s *ossClientStub) Get(_ context.Context, r OSSObjectRequest) (Blob, error) {
s.gets = append(s.gets, r)
if s.getErr != nil {
return Blob{}, s.getErr
}
return Blob{Body: io.NopCloser(bytes.NewReader(s.body)), ContentType: s.contentType, Size: int64(len(s.body))}, nil
}
func (s *ossClientStub) Delete(_ context.Context, r OSSObjectRequest) error {
s.deletes = append(s.deletes, r)
return s.errorToReturn
}
func TestOSSPutUsesConfiguredAddressContentTypeAndPublicACL(t *testing.T) {
client := &ossClientStub{}
store, err := NewOSS(OSSConfig{Endpoint: "https://oss-cn.test", Bucket: "bucket-a", PublicBaseURL: "https://cdn.test/root", PublicRead: true}, client)
if err != nil {
t.Fatal(err)
}
got, err := store.Put(context.Background(), "uploads/a b.png", bytes.NewReader([]byte("png")), 3, "image/png")
if err != nil {
t.Fatal(err)
}
if got.Key != "uploads/a b.png" || got.URL != "https://cdn.test/root/uploads/a%20b.png" {
t.Fatalf("stored=%#v", got)
}
if len(client.puts) != 1 || client.puts[0].Endpoint != "https://oss-cn.test" || client.puts[0].Bucket != "bucket-a" || client.puts[0].ContentType != "image/png" || client.puts[0].Size != 3 {
t.Fatalf("puts=%#v", client.puts)
}
if len(client.acls) != 1 || client.acls[0].ACL != OSSACLPublicRead {
t.Fatalf("acls=%#v", client.acls)
}
}
func TestOSSReadDeleteAndMissingMapping(t *testing.T) {
client := &ossClientStub{body: []byte("x"), contentType: "image/png"}
store, _ := NewOSS(OSSConfig{Endpoint: "e", Bucket: "b", PublicBaseURL: "https://cdn.test"}, client)
blob, err := store.Read(context.Background(), "generated-results/x.png")
if err != nil {
t.Fatal(err)
}
_ = blob.Body.Close()
if len(client.gets) != 1 || client.gets[0].Key != "generated-results/x.png" {
t.Fatalf("gets=%#v", client.gets)
}
if err = store.Delete(context.Background(), "generated-results/x.png"); err != nil || len(client.deletes) != 1 {
t.Fatalf("delete=%v %#v", err, client.deletes)
}
client.getErr = &OSSError{Status: 404, Code: "NoSuchKey", Err: errors.New("secret response")}
if _, err = store.Read(context.Background(), "missing"); !errors.Is(err, ErrBlobNotFound) {
t.Fatalf("missing=%v", err)
}
client.errorToReturn = &OSSError{Status: 404, Code: "NoSuchKey"}
if err = store.Delete(context.Background(), "missing"); err != nil {
t.Fatalf("delete missing=%v", err)
}
}
func TestOSSRejectsUnsafeKeysAndIncompleteConfiguration(t *testing.T) {
if _, err := NewOSS(OSSConfig{Endpoint: "e", Bucket: "b"}, &ossClientStub{}); err == nil {
t.Fatal("expected config error")
}
store, _ := NewOSS(OSSConfig{Endpoint: "e", Bucket: "b", PublicBaseURL: "https://cdn.test"}, &ossClientStub{})
for _, key := range []string{"", "../secret", "/absolute", "a\\b"} {
if _, err := store.Put(context.Background(), key, bytes.NewReader(nil), 0, "x"); !errors.Is(err, ErrUnsafeBlobKey) {
t.Errorf("key %q: %v", key, err)
}
}
}