244 lines
6.3 KiB
Go
244 lines
6.3 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"veza-backend-api/internal/models"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func setupTestTrackShareService(t *testing.T) (*TrackShareService, *gorm.DB, uuid.UUID, func()) {
|
|
// Setup in-memory SQLite database
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
|
|
// Auto-migrate
|
|
err = db.AutoMigrate(&models.TrackShare{}, &models.Track{}, &models.User{})
|
|
require.NoError(t, err)
|
|
|
|
// Create test user
|
|
userID := uuid.New()
|
|
user := &models.User{
|
|
ID: userID,
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
IsActive: true,
|
|
}
|
|
err = db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
// Setup service
|
|
// TrackShareService might need logger too?
|
|
// The original test didn't pass one, assuming NewTrackShareService(db) only.
|
|
// Checking the file content, it was: NewTrackShareService(db)
|
|
service := NewTrackShareService(db)
|
|
|
|
// Cleanup function
|
|
cleanup := func() {
|
|
// Database will be closed automatically
|
|
}
|
|
|
|
return service, db, userID, cleanup
|
|
}
|
|
|
|
func TestTrackShareService_CreateShare(t *testing.T) {
|
|
service, db, userID, cleanup := setupTestTrackShareService(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
FileSize: 5 * 1024 * 1024,
|
|
Format: "MP3",
|
|
Duration: 180,
|
|
IsPublic: true,
|
|
Status: models.TrackStatusCompleted,
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
|
|
// Create share
|
|
share, err := service.CreateShare(ctx, track.ID, userID, "read,download", nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, share)
|
|
assert.Equal(t, track.ID, share.TrackID)
|
|
assert.Equal(t, userID, share.UserID)
|
|
assert.Equal(t, "read,download", share.Permissions)
|
|
assert.NotEmpty(t, share.ShareToken)
|
|
}
|
|
|
|
func TestTrackShareService_CreateShare_NotOwner(t *testing.T) {
|
|
service, db, userID, cleanup := setupTestTrackShareService(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
FileSize: 5 * 1024 * 1024,
|
|
Format: "MP3",
|
|
Duration: 180,
|
|
IsPublic: true,
|
|
Status: models.TrackStatusCompleted,
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
|
|
// Try to create share as different user
|
|
share, err := service.CreateShare(ctx, track.ID, uuid.New(), "read,download", nil)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, share)
|
|
assert.Equal(t, ErrForbidden, err)
|
|
}
|
|
|
|
func TestTrackShareService_ValidateShareToken(t *testing.T) {
|
|
service, db, userID, cleanup := setupTestTrackShareService(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
FileSize: 5 * 1024 * 1024,
|
|
Format: "MP3",
|
|
Duration: 180,
|
|
IsPublic: true,
|
|
Status: models.TrackStatusCompleted,
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
|
|
// Create share
|
|
share, err := service.CreateShare(ctx, track.ID, userID, "read,download", nil)
|
|
require.NoError(t, err)
|
|
|
|
// Validate token
|
|
validatedShare, err := service.ValidateShareToken(ctx, share.ShareToken)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, validatedShare)
|
|
assert.Equal(t, share.ID, validatedShare.ID)
|
|
assert.Equal(t, int64(1), validatedShare.AccessCount) // Should be incremented
|
|
}
|
|
|
|
func TestTrackShareService_ValidateShareToken_Expired(t *testing.T) {
|
|
service, db, userID, cleanup := setupTestTrackShareService(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
FileSize: 5 * 1024 * 1024,
|
|
Format: "MP3",
|
|
Duration: 180,
|
|
IsPublic: true,
|
|
Status: models.TrackStatusCompleted,
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
|
|
// Create share with expiration in the past
|
|
expiredTime := time.Now().Add(-1 * time.Hour)
|
|
share := &models.TrackShare{
|
|
TrackID: track.ID,
|
|
UserID: userID,
|
|
ShareToken: "test-token-123",
|
|
Permissions: "read,download",
|
|
ExpiresAt: &expiredTime,
|
|
AccessCount: 0,
|
|
}
|
|
err = db.Create(share).Error
|
|
require.NoError(t, err)
|
|
|
|
// Try to validate expired token
|
|
validatedShare, err := service.ValidateShareToken(ctx, share.ShareToken)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, validatedShare)
|
|
assert.Equal(t, ErrShareExpired, err)
|
|
}
|
|
|
|
func TestTrackShareService_CheckPermission(t *testing.T) {
|
|
service, _, _, cleanup := setupTestTrackShareService(t)
|
|
defer cleanup()
|
|
|
|
// Test with read permission
|
|
share := &models.TrackShare{
|
|
Permissions: "read",
|
|
ExpiresAt: nil,
|
|
}
|
|
assert.True(t, service.CheckPermission(share, "read"))
|
|
assert.False(t, service.CheckPermission(share, "download"))
|
|
|
|
// Test with download permission
|
|
share.Permissions = "download"
|
|
assert.False(t, service.CheckPermission(share, "read"))
|
|
assert.True(t, service.CheckPermission(share, "download"))
|
|
|
|
// Test with both permissions
|
|
share.Permissions = "read,download"
|
|
assert.True(t, service.CheckPermission(share, "read"))
|
|
assert.True(t, service.CheckPermission(share, "download"))
|
|
|
|
// Test with expired share
|
|
expiredTime := time.Now().Add(-1 * time.Hour)
|
|
share.ExpiresAt = &expiredTime
|
|
assert.False(t, service.CheckPermission(share, "read"))
|
|
assert.False(t, service.CheckPermission(share, "download"))
|
|
}
|
|
|
|
func TestTrackShareService_RevokeShare(t *testing.T) {
|
|
service, db, userID, cleanup := setupTestTrackShareService(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
FileSize: 5 * 1024 * 1024,
|
|
Format: "MP3",
|
|
Duration: 180,
|
|
IsPublic: true,
|
|
Status: models.TrackStatusCompleted,
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
|
|
// Create share
|
|
share, err := service.CreateShare(ctx, track.ID, userID, "read,download", nil)
|
|
require.NoError(t, err)
|
|
|
|
// Revoke share
|
|
err = service.RevokeShare(ctx, share.ID, userID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify share is deleted
|
|
var deletedShare models.TrackShare
|
|
err = db.First(&deletedShare, "id = ?", share.ID).Error
|
|
assert.Error(t, err)
|
|
assert.True(t, errors.Is(err, gorm.ErrRecordNotFound))
|
|
}
|