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) }