mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-01 22:46:38 +08:00
refactor(core): align with cordis spatiotemporal composability architecture
- Purify core micro-kernel by removing context hardcoded helpers and reverse dependencies - Eliminate init() side effects in infra plugins with reversible lifecycle disposal - Completely isolate plugins by removing cross-plugin imports and using core/contracts - Introduce TaskService and RiskControlService contracts for unified cross-plugin APIs - Regenerate Swagger documentation and update developer guide matrix - Achieve 0 violations in check_cordis_architecture.sh and 100% test pass
This commit is contained in:
@@ -12,12 +12,12 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"Wavelet/core/contracts"
|
||||
"Wavelet/pkg/testhelper"
|
||||
"Wavelet/plugins/domain/upload/models"
|
||||
"Wavelet/plugins/domain/upload/shared"
|
||||
)
|
||||
|
||||
func TestGetDistinctUploadTypes(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
user := contracts.UserDTO{ID: 2222, Username: "test_user_2"}
|
||||
@@ -61,6 +61,6 @@ func TestGetDistinctUploadTypes(t *testing.T) {
|
||||
}
|
||||
|
||||
if len(resp.Data) != 1 || resp.Data[0] != "custom_type_xyz" {
|
||||
t.Errorf("expected only custom_type_xyz in types list, got: %v", resp.Data)
|
||||
t.Fatalf("expected ['custom_type_xyz'], got %v", resp.Data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"Wavelet/core/contracts"
|
||||
"Wavelet/pkg/logger"
|
||||
"Wavelet/pkg/response"
|
||||
@@ -31,8 +34,6 @@ import (
|
||||
"Wavelet/plugins/domain/upload/shared"
|
||||
uploadstorage "Wavelet/plugins/domain/upload/storage"
|
||||
"Wavelet/plugins/domain/upload/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type batchDownloadRequest struct {
|
||||
|
||||
@@ -13,20 +13,21 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"Wavelet/core/contracts"
|
||||
"Wavelet/pkg/response"
|
||||
"Wavelet/pkg/testhelper"
|
||||
"Wavelet/pkg/util"
|
||||
"Wavelet/plugins/domain/upload/models"
|
||||
"Wavelet/plugins/domain/upload/shared"
|
||||
uploadstats "Wavelet/plugins/domain/upload/stats"
|
||||
"Wavelet/plugins/infra/storage/objectstore"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type testResponse struct {
|
||||
@@ -86,9 +87,6 @@ func createMultipartRequest(t *testing.T, fieldName, fileName string, fileConten
|
||||
|
||||
for k, v := range extraFields {
|
||||
err = writer.WriteField(k, v)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to write form field: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = writer.Close()
|
||||
@@ -99,51 +97,76 @@ func createMultipartRequest(t *testing.T, fieldName, fileName string, fileConten
|
||||
return writer.FormDataContentType(), body
|
||||
}
|
||||
|
||||
type handlerTestStorage struct {
|
||||
mu sync.RWMutex
|
||||
mockFiles map[string][]byte
|
||||
putCount *int
|
||||
}
|
||||
|
||||
func (s *handlerTestStorage) Put(_ context.Context, key string, body io.Reader, _ int64, _ string) (contracts.StoragePutResult, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
data, _ := io.ReadAll(body)
|
||||
s.mockFiles[key] = data
|
||||
if s.putCount != nil {
|
||||
*s.putCount++
|
||||
}
|
||||
if strings.HasPrefix(key, "uploads/") {
|
||||
_ = os.MkdirAll(filepath.Dir(key), 0755)
|
||||
_ = os.WriteFile(key, data, 0644)
|
||||
}
|
||||
return contracts.StoragePutResult{Key: key, Bucket: "test-bucket"}, nil
|
||||
}
|
||||
|
||||
func (s *handlerTestStorage) Get(_ context.Context, key string) (*contracts.StorageObject, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
data, ok := s.mockFiles[key]
|
||||
if ok {
|
||||
return &contracts.StorageObject{
|
||||
Key: key,
|
||||
Body: io.NopCloser(bytes.NewReader(data)),
|
||||
ContentLength: int64(len(data)),
|
||||
ContentType: "application/octet-stream",
|
||||
}, nil
|
||||
}
|
||||
if f, err := os.Open(key); err == nil {
|
||||
info, _ := f.Stat()
|
||||
return &contracts.StorageObject{
|
||||
Key: key,
|
||||
Body: f,
|
||||
ContentLength: info.Size(),
|
||||
ContentType: "application/octet-stream",
|
||||
}, nil
|
||||
}
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
|
||||
func (s *handlerTestStorage) Delete(_ context.Context, key string) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
delete(s.mockFiles, key)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *handlerTestStorage) Ingest(_ context.Context, _ io.Reader, _ contracts.IngestOptions) (*contracts.IngestResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestUploadFile(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
defer func() { _ = os.RemoveAll("uploads") }() // Clean up local files created during tests
|
||||
|
||||
authUser := &contracts.UserDTO{ID: 1001, Username: "test_user"}
|
||||
router := setupTestRouter(authUser)
|
||||
|
||||
// Mock Storage Client
|
||||
mockFiles := make(map[string][]byte)
|
||||
var putCount int
|
||||
|
||||
restoreStorage := objectstore.MockStorage(
|
||||
func(ctx context.Context, key string, body io.Reader, size int64, contentType string) error {
|
||||
data, err := io.ReadAll(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mockFiles[key] = data
|
||||
putCount++
|
||||
return nil
|
||||
},
|
||||
func(ctx context.Context, key string) (*objectstore.Object, error) {
|
||||
data, ok := mockFiles[key]
|
||||
if !ok {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return &objectstore.Object{
|
||||
Body: io.NopCloser(bytes.NewReader(data)),
|
||||
ContentLength: int64(len(data)),
|
||||
ContentType: "application/octet-stream",
|
||||
}, nil
|
||||
},
|
||||
func(ctx context.Context, key string) error {
|
||||
delete(mockFiles, key)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
defer restoreStorage()
|
||||
|
||||
// 开启 S3 Storage
|
||||
objectstore.IsEnabledFunc = func() bool { return true }
|
||||
defer func() {
|
||||
objectstore.IsEnabledFunc = func() bool { return false }
|
||||
}()
|
||||
mockStorage := &handlerTestStorage{
|
||||
mockFiles: make(map[string][]byte),
|
||||
putCount: &putCount,
|
||||
}
|
||||
shared.SetStorageService(mockStorage)
|
||||
|
||||
t.Run("upload allowed image file successfully", func(t *testing.T) {
|
||||
putCount = 0
|
||||
@@ -283,9 +306,6 @@ func TestUploadFile(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("upload in local storage fallback mode", func(t *testing.T) {
|
||||
// Turn off S3
|
||||
objectstore.IsEnabledFunc = func() bool { return false }
|
||||
|
||||
// Seed allowed extensions configuration to allow txt files
|
||||
dbConn.Table("w_system_configs").Where("key = ?", "upload_allowed_extensions").Update("value", "jpg,png,webp,txt")
|
||||
|
||||
@@ -327,7 +347,7 @@ func TestUploadFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDownloadFile(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
defer func() { _ = os.RemoveAll("uploads") }()
|
||||
|
||||
@@ -395,7 +415,7 @@ func TestDownloadFile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestListFiles(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
authUser := &contracts.UserDTO{ID: 1001, Username: "test_user"}
|
||||
@@ -535,7 +555,7 @@ func TestListFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBatchDownloadFiles(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
defer func() { _ = os.RemoveAll("uploads") }()
|
||||
|
||||
@@ -647,7 +667,7 @@ func TestBatchDownloadFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUploadAccessModeAccessControl(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
defer func() { _ = os.RemoveAll("uploads") }()
|
||||
|
||||
@@ -734,7 +754,7 @@ func TestUploadAccessModeAccessControl(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetFileStats(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
authUser := &contracts.UserDTO{ID: 1001, Username: "test_user"}
|
||||
@@ -844,7 +864,7 @@ func TestGetFileStats(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUserUploadManagement(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
dbConn, cleanup := shared.SetupTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
user1 := &contracts.UserDTO{ID: 1001, Username: "user1"}
|
||||
|
||||
Reference in New Issue
Block a user