- C1-01: Create CloudService with CRUD folders/files, quota, ownership - C1-02: Create CloudHandler with 11 REST endpoints - C1-03: Register cloud routes in Go router - C1-04: Implement file streaming with HTTP Range support - C1-05: Add publish cloud file as track endpoint - C1-06: Add MSW mock handlers for cloud API - C1-07: Auto-init 5GB storage quota on user registration - C1-08: Add 12 unit tests for CloudService
205 lines
6.6 KiB
Go
205 lines
6.6 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
|
|
"veza-backend-api/internal/models"
|
|
)
|
|
|
|
func setupTestCloudDB(t *testing.T) *gorm.DB {
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
require.NoError(t, db.AutoMigrate(
|
|
&models.User{},
|
|
&models.UserFolder{},
|
|
&models.UserFile{},
|
|
&models.StorageQuota{},
|
|
))
|
|
return db
|
|
}
|
|
|
|
func createCloudTestUser(t *testing.T, db *gorm.DB) uuid.UUID {
|
|
userID := uuid.New()
|
|
user := models.User{ID: userID, Email: userID.String() + "@test.com", Username: "user_" + userID.String()[:8]}
|
|
require.NoError(t, db.Create(&user).Error)
|
|
return userID
|
|
}
|
|
|
|
func createCloudTestQuota(t *testing.T, db *gorm.DB, userID uuid.UUID, maxBytes, usedBytes int64) {
|
|
quota := models.StorageQuota{UserID: userID, MaxBytes: maxBytes, UsedBytes: usedBytes}
|
|
require.NoError(t, db.Create("a).Error)
|
|
}
|
|
|
|
func TestCloudService_CreateFolder(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
|
|
folder, err := svc.CreateFolder(context.Background(), userID, "My Music", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "My Music", folder.Name)
|
|
assert.Equal(t, userID, folder.UserID)
|
|
assert.Nil(t, folder.ParentID)
|
|
}
|
|
|
|
func TestCloudService_CreateSubfolder(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
|
|
parent, err := svc.CreateFolder(context.Background(), userID, "Root", nil)
|
|
require.NoError(t, err)
|
|
|
|
child, err := svc.CreateFolder(context.Background(), userID, "Sub", &parent.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, &parent.ID, child.ParentID)
|
|
}
|
|
|
|
func TestCloudService_CreateFolder_WrongParentOwner(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
user1 := createCloudTestUser(t, db)
|
|
user2 := createCloudTestUser(t, db)
|
|
|
|
folder, err := svc.CreateFolder(context.Background(), user1, "Folder", nil)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.CreateFolder(context.Background(), user2, "Sub", &folder.ID)
|
|
assert.ErrorIs(t, err, ErrFolderNotFound)
|
|
}
|
|
|
|
func TestCloudService_ListFolders(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
|
|
_, _ = svc.CreateFolder(context.Background(), userID, "A", nil)
|
|
_, _ = svc.CreateFolder(context.Background(), userID, "B", nil)
|
|
|
|
folders, err := svc.ListFolders(context.Background(), userID, nil)
|
|
require.NoError(t, err)
|
|
assert.Len(t, folders, 2)
|
|
assert.Equal(t, "A", folders[0].Name)
|
|
}
|
|
|
|
func TestCloudService_RenameFolder(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
|
|
folder, _ := svc.CreateFolder(context.Background(), userID, "Old", nil)
|
|
err := svc.RenameFolder(context.Background(), userID, folder.ID, "New")
|
|
require.NoError(t, err)
|
|
|
|
folders, _ := svc.ListFolders(context.Background(), userID, nil)
|
|
assert.Equal(t, "New", folders[0].Name)
|
|
}
|
|
|
|
func TestCloudService_DeleteFolder(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, userID, 5*1024*1024*1024, 0)
|
|
|
|
folder, _ := svc.CreateFolder(context.Background(), userID, "ToDelete", nil)
|
|
err := svc.DeleteFolder(context.Background(), userID, folder.ID)
|
|
require.NoError(t, err)
|
|
|
|
folders, _ := svc.ListFolders(context.Background(), userID, nil)
|
|
assert.Len(t, folders, 0)
|
|
}
|
|
|
|
func TestCloudService_UploadFile(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, userID, 5*1024*1024*1024, 0)
|
|
|
|
data := []byte("fake audio data")
|
|
file, err := svc.UploadFile(context.Background(), userID, nil, "test.mp3", data, "audio/mpeg")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "test.mp3", file.Filename)
|
|
assert.Equal(t, "audio/mpeg", file.MimeType)
|
|
assert.Equal(t, int64(len(data)), file.SizeBytes)
|
|
}
|
|
|
|
func TestCloudService_UploadFile_QuotaExceeded(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, userID, 100, 90)
|
|
|
|
data := make([]byte, 50)
|
|
_, err := svc.UploadFile(context.Background(), userID, nil, "big.mp3", data, "audio/mpeg")
|
|
assert.ErrorIs(t, err, ErrQuotaExceeded)
|
|
}
|
|
|
|
func TestCloudService_UploadFile_InvalidMimeType(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, userID, 5*1024*1024*1024, 0)
|
|
|
|
_, err := svc.UploadFile(context.Background(), userID, nil, "test.exe", []byte("data"), "application/x-executable")
|
|
assert.ErrorIs(t, err, ErrInvalidMimeType)
|
|
}
|
|
|
|
func TestCloudService_DeleteFile(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, userID, 5*1024*1024*1024, 0)
|
|
|
|
file, _ := svc.UploadFile(context.Background(), userID, nil, "test.mp3", []byte("data"), "audio/mpeg")
|
|
err := svc.DeleteFile(context.Background(), userID, file.ID)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetFileByID(context.Background(), userID, file.ID)
|
|
assert.ErrorIs(t, err, ErrFileNotFound)
|
|
}
|
|
|
|
func TestCloudService_GetQuota(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, userID, 5*1024*1024*1024, 1000)
|
|
|
|
quota, err := svc.GetQuota(context.Background(), userID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5*1024*1024*1024), quota.MaxBytes)
|
|
assert.Equal(t, int64(1000), quota.UsedBytes)
|
|
}
|
|
|
|
func TestCloudService_InitQuota(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
userID := createCloudTestUser(t, db)
|
|
|
|
err := svc.InitQuota(context.Background(), userID)
|
|
require.NoError(t, err)
|
|
|
|
quota, err := svc.GetQuota(context.Background(), userID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5*1024*1024*1024), quota.MaxBytes)
|
|
assert.Equal(t, int64(0), quota.UsedBytes)
|
|
}
|
|
|
|
func TestCloudService_Ownership(t *testing.T) {
|
|
db := setupTestCloudDB(t)
|
|
svc := NewCloudService(db, zap.NewNop(), nil)
|
|
user1 := createCloudTestUser(t, db)
|
|
user2 := createCloudTestUser(t, db)
|
|
createCloudTestQuota(t, db, user1, 5*1024*1024*1024, 0)
|
|
|
|
file, _ := svc.UploadFile(context.Background(), user1, nil, "secret.mp3", []byte("data"), "audio/mpeg")
|
|
_, err := svc.GetFileByID(context.Background(), user2, file.ID)
|
|
assert.ErrorIs(t, err, ErrFileNotFound)
|
|
}
|