- docs: SCOPE_CONTROL, CONTRIBUTING, README, .github templates - frontend: DeveloperDashboardView, Player components, MSW handlers, auth, reactQuerySync - backend: playback_analytics, playlist_service, testutils, integration README Excluded (artifacts): .auth, playwright-report, test-results, storybook_audit_detailed.json
650 lines
25 KiB
Go
650 lines
25 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"veza-backend-api/internal/models"
|
|
"veza-backend-api/internal/repositories"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// setupTestPlaylistServiceDB crée une base de données de test en mémoire
|
|
func setupTestPlaylistServiceDB(t *testing.T) *gorm.DB {
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err, "Failed to open test database")
|
|
|
|
// Enable foreign keys for SQLite to ensure data integrity constraints
|
|
db.Exec("PRAGMA foreign_keys = ON")
|
|
|
|
// Auto-migrate tous les modèles nécessaires
|
|
err = db.AutoMigrate(
|
|
&models.User{},
|
|
&models.Playlist{},
|
|
&models.Track{},
|
|
&models.PlaylistCollaborator{},
|
|
)
|
|
require.NoError(t, err, "Failed to migrate test database")
|
|
|
|
// Drop and recreate playlist_tracks table manually to ensure all columns exist (AutoMigrate might miss some in SQLite)
|
|
db.Exec(`DROP TABLE IF EXISTS playlist_tracks`)
|
|
db.Exec(`
|
|
CREATE TABLE playlist_tracks (
|
|
id TEXT PRIMARY KEY,
|
|
playlist_id TEXT NOT NULL,
|
|
track_id TEXT NOT NULL,
|
|
position INTEGER NOT NULL,
|
|
added_by TEXT NOT NULL,
|
|
added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(playlist_id, track_id)
|
|
)
|
|
`)
|
|
|
|
return db
|
|
}
|
|
|
|
// createTestUser crée un utilisateur de test
|
|
func createTestUserForService(t *testing.T, db *gorm.DB, username string) *models.User {
|
|
user := &models.User{
|
|
Username: username,
|
|
Slug: username,
|
|
Email: username + "@example.com",
|
|
PasswordHash: "hashed_password",
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
return user
|
|
}
|
|
|
|
// createTestPlaylist crée une playlist de test
|
|
func createTestPlaylistForService(t *testing.T, db *gorm.DB, userID uuid.UUID) *models.Playlist {
|
|
playlist := &models.Playlist{
|
|
UserID: userID,
|
|
Title: "Test Playlist",
|
|
Description: "Test Description",
|
|
IsPublic: true,
|
|
TrackCount: 0,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
err := db.Create(playlist).Error
|
|
require.NoError(t, err)
|
|
return playlist
|
|
}
|
|
|
|
// createTestTrackForService crée un track de test
|
|
func createTestTrackForService(t *testing.T, db *gorm.DB, userID uuid.UUID) *models.Track {
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
FilePath: "/tmp/test.mp3",
|
|
Format: "mp3",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
return track
|
|
}
|
|
|
|
func TestPlaylistService_CreatePlaylist(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
user := createTestUserForService(t, db, "testuser")
|
|
|
|
// Test creation
|
|
playlist, err := service.CreatePlaylist(ctx, user.ID, "My Playlist", "Desc", true)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, playlist)
|
|
assert.Equal(t, "My Playlist", playlist.Title)
|
|
assert.Equal(t, user.ID, playlist.UserID)
|
|
|
|
// Test user not found
|
|
_, err = service.CreatePlaylist(ctx, uuid.New(), "Title", "Desc", true)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "user not found")
|
|
}
|
|
|
|
func TestPlaylistService_AddTrackToPlaylist(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
user := createTestUserForService(t, db, "testuser")
|
|
playlist := createTestPlaylistForService(t, db, user.ID)
|
|
track := createTestTrackForService(t, db, user.ID)
|
|
|
|
// Add track
|
|
err := service.AddTrackToPlaylist(ctx, playlist.ID, track.ID, user.ID, 0)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify track added
|
|
p, err := service.GetPlaylist(ctx, playlist.ID, &user.ID)
|
|
assert.NoError(t, err)
|
|
require.Len(t, p.Tracks, 1)
|
|
assert.Equal(t, track.ID, p.Tracks[0].TrackID)
|
|
|
|
// Test ownership (other user cannot add track)
|
|
otherUser := createTestUserForService(t, db, "other")
|
|
err = service.AddTrackToPlaylist(ctx, playlist.ID, track.ID, otherUser.ID, 0)
|
|
assert.Error(t, err)
|
|
assert.Equal(t, "forbidden", err.Error())
|
|
}
|
|
|
|
func TestPlaylistService_RemoveTrackFromPlaylist(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
user := createTestUserForService(t, db, "testuser")
|
|
playlist := createTestPlaylistForService(t, db, user.ID)
|
|
track := createTestTrackForService(t, db, user.ID)
|
|
|
|
// Add track first
|
|
err := service.AddTrackToPlaylist(ctx, playlist.ID, track.ID, user.ID, 0)
|
|
assert.NoError(t, err)
|
|
|
|
// Remove track
|
|
err = service.RemoveTrackFromPlaylist(ctx, playlist.ID, track.ID, user.ID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify removed
|
|
p, err := service.GetPlaylist(ctx, playlist.ID, &user.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, p.Tracks, 0)
|
|
}
|
|
|
|
func TestPlaylistService_AddCollaborator(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
collaborator := createTestUserForService(t, db, "collaborator")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Test AddCollaborator avec permission read
|
|
collab, err := service.AddCollaborator(ctx, playlist.ID, owner.ID, collaborator.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, collab)
|
|
assert.Equal(t, playlist.ID, collab.PlaylistID)
|
|
assert.Equal(t, collaborator.ID, collab.UserID)
|
|
assert.Equal(t, models.PlaylistPermissionRead, collab.Permission)
|
|
|
|
// Test AddCollaborator avec permission write (créer un autre utilisateur)
|
|
collaborator2 := createTestUserForService(t, db, "collaborator2")
|
|
collab2, err := service.AddCollaborator(ctx, playlist.ID, owner.ID, collaborator2.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, models.PlaylistPermissionWrite, collab2.Permission)
|
|
|
|
// Test AddCollaborator avec non-propriétaire (devrait échouer)
|
|
otherUser := createTestUserForService(t, db, "other_user")
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, collaborator.ID, otherUser.ID, models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "forbidden")
|
|
|
|
// Test AddCollaborator avec le propriétaire lui-même (devrait échouer)
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, owner.ID, owner.ID, models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "cannot add playlist owner")
|
|
|
|
// Test AddCollaborator avec playlist inexistante
|
|
_, err = service.AddCollaborator(ctx, uuid.New(), owner.ID, collaborator.ID, models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "playlist not found")
|
|
|
|
// Test AddCollaborator avec utilisateur inexistant
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, owner.ID, uuid.New(), models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "user not found")
|
|
}
|
|
|
|
func TestPlaylistService_RemoveCollaborator(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
collaborator := createTestUserForService(t, db, "collaborator")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Ajouter un collaborateur
|
|
_, err := service.AddCollaborator(ctx, playlist.ID, owner.ID, collaborator.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
|
|
// Retirer le collaborateur
|
|
err = service.RemoveCollaborator(ctx, playlist.ID, owner.ID, collaborator.ID)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier qu'il n'existe plus
|
|
exists, err := playlistCollaboratorRepo.Exists(ctx, playlist.ID, collaborator.ID)
|
|
assert.NoError(t, err)
|
|
assert.False(t, exists)
|
|
|
|
// Test RemoveCollaborator avec non-propriétaire (devrait échouer)
|
|
err = service.RemoveCollaborator(ctx, playlist.ID, collaborator.ID, owner.ID)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "forbidden")
|
|
|
|
// Test RemoveCollaborator avec collaborateur inexistant
|
|
err = service.RemoveCollaborator(ctx, playlist.ID, owner.ID, uuid.New())
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "collaborator not found")
|
|
}
|
|
|
|
func TestPlaylistService_UpdatePlaylist(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
otherUser := createTestUserForService(t, db, "other")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Test Update
|
|
newTitle := "Updated Title"
|
|
newDesc := "Updated Desc"
|
|
isPublic := false
|
|
updated, err := service.UpdatePlaylist(ctx, playlist.ID, owner.ID, &newTitle, &newDesc, &isPublic)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "Updated Title", updated.Title)
|
|
assert.Equal(t, "Updated Desc", updated.Description)
|
|
assert.False(t, updated.IsPublic)
|
|
|
|
// Test Forbidden
|
|
_, err = service.UpdatePlaylist(ctx, playlist.ID, otherUser.ID, &newTitle, nil, nil)
|
|
assert.ErrorIs(t, err, ErrAccessDenied)
|
|
|
|
// Test NotFound
|
|
_, err = service.UpdatePlaylist(ctx, uuid.New(), owner.ID, &newTitle, nil, nil)
|
|
assert.ErrorIs(t, err, ErrPlaylistNotFound)
|
|
}
|
|
|
|
func TestPlaylistService_DeletePlaylist(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
otherUser := createTestUserForService(t, db, "other")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Test Forbidden
|
|
err := service.DeletePlaylist(ctx, playlist.ID, otherUser.ID)
|
|
assert.ErrorIs(t, err, ErrAccessDenied)
|
|
|
|
// Test Success
|
|
err = service.DeletePlaylist(ctx, playlist.ID, owner.ID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify deletion
|
|
_, err = playlistRepo.GetByID(ctx, playlist.ID)
|
|
assert.ErrorIs(t, err, gorm.ErrRecordNotFound)
|
|
}
|
|
|
|
func TestPlaylistService_ReorderPlaylistTracks(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
track1 := createTestTrackForService(t, db, owner.ID)
|
|
track2 := createTestTrackForService(t, db, owner.ID)
|
|
|
|
// Add tracks
|
|
service.AddTrackToPlaylist(ctx, playlist.ID, track1.ID, owner.ID, 1)
|
|
service.AddTrackToPlaylist(ctx, playlist.ID, track2.ID, owner.ID, 2)
|
|
|
|
// Reorder
|
|
positions := map[uuid.UUID]int{
|
|
track1.ID: 2,
|
|
track2.ID: 1,
|
|
}
|
|
err := service.ReorderPlaylistTracks(ctx, playlist.ID, owner.ID, positions)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify order via GetPlaylist (tracks ordered by position ascending)
|
|
p, err := service.GetPlaylist(ctx, playlist.ID, &owner.ID)
|
|
assert.NoError(t, err)
|
|
require.Len(t, p.Tracks, 2)
|
|
// After reorder: track2 at pos 1, track1 at pos 2. Order depends on repo sort.
|
|
trackIDs := []uuid.UUID{p.Tracks[0].TrackID, p.Tracks[1].TrackID}
|
|
assert.Contains(t, trackIDs, track1.ID)
|
|
assert.Contains(t, trackIDs, track2.ID)
|
|
}
|
|
|
|
func TestPlaylistService_GetPlaylists(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
other := createTestUserForService(t, db, "other")
|
|
|
|
// Helper to create playlist
|
|
create := func(user *models.User, title string, public bool) *models.Playlist {
|
|
p := &models.Playlist{
|
|
UserID: user.ID,
|
|
Title: title,
|
|
IsPublic: public,
|
|
}
|
|
db.Create(p)
|
|
return p
|
|
}
|
|
|
|
create(owner, "Public 1", true)
|
|
create(owner, "Private 1", false)
|
|
create(other, "Public 2", true)
|
|
|
|
// Test List for Anonymous (Public only) - Public 1, Public 2
|
|
list, total, err := service.GetPlaylists(ctx, nil, nil, 1, 10)
|
|
assert.NoError(t, err)
|
|
assert.GreaterOrEqual(t, total, int64(2), "anonymous should see at least 2 public playlists")
|
|
assert.GreaterOrEqual(t, len(list), 2)
|
|
|
|
// Test List for Owner (Own Private + Public + Public of others)
|
|
list, total, err = service.GetPlaylists(ctx, &owner.ID, nil, 1, 10)
|
|
assert.NoError(t, err)
|
|
assert.GreaterOrEqual(t, total, int64(3), "owner sees own playlists + public of others")
|
|
assert.GreaterOrEqual(t, len(list), 3)
|
|
|
|
// Test Filter by User - anonymous viewing owner's profile: public only
|
|
list, total, err = service.GetPlaylists(ctx, nil, &owner.ID, 1, 10)
|
|
assert.NoError(t, err)
|
|
assert.GreaterOrEqual(t, total, int64(1), "filter by owner should return at least public playlists")
|
|
assert.GreaterOrEqual(t, len(list), 1)
|
|
}
|
|
|
|
func TestPlaylistService_SearchPlaylists(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "search_owner")
|
|
|
|
p1 := &models.Playlist{UserID: owner.ID, Title: "Techno Vibes", IsPublic: true}
|
|
db.Create(p1)
|
|
p2 := &models.Playlist{UserID: owner.ID, Title: "Jazz Classics", IsPublic: true}
|
|
db.Create(p2)
|
|
|
|
params := SearchPlaylistsParams{
|
|
Query: "Techno",
|
|
Page: 1,
|
|
Limit: 10,
|
|
}
|
|
results, total, err := service.SearchPlaylists(ctx, params)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, int64(1), total)
|
|
assert.Equal(t, "Techno Vibes", results[0].Title)
|
|
}
|
|
|
|
func TestPlaylistService_UpdateCollaboratorPermission(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
collaborator := createTestUserForService(t, db, "collaborator")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Ajouter un collaborateur avec permission read
|
|
_, err := service.AddCollaborator(ctx, playlist.ID, owner.ID, collaborator.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
|
|
// Mettre à jour la permission à write
|
|
err = service.UpdateCollaboratorPermission(ctx, playlist.ID, owner.ID, collaborator.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier la mise à jour
|
|
collab, err := playlistCollaboratorRepo.GetCollaborator(ctx, playlist.ID, collaborator.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, models.PlaylistPermissionWrite, collab.Permission)
|
|
|
|
// Mettre à jour la permission à admin
|
|
err = service.UpdateCollaboratorPermission(ctx, playlist.ID, owner.ID, collaborator.ID, models.PlaylistPermissionAdmin)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier la mise à jour
|
|
collab, err = playlistCollaboratorRepo.GetCollaborator(ctx, playlist.ID, collaborator.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, models.PlaylistPermissionAdmin, collab.Permission)
|
|
|
|
// Test UpdateCollaboratorPermission avec non-propriétaire (devrait échouer)
|
|
err = service.UpdateCollaboratorPermission(ctx, playlist.ID, collaborator.ID, owner.ID, models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "forbidden")
|
|
|
|
// Test UpdateCollaboratorPermission avec permission invalide
|
|
err = service.UpdateCollaboratorPermission(ctx, playlist.ID, owner.ID, collaborator.ID, models.PlaylistPermission("invalid"))
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid permission")
|
|
|
|
// Test UpdateCollaboratorPermission avec collaborateur inexistant
|
|
err = service.UpdateCollaboratorPermission(ctx, playlist.ID, owner.ID, uuid.New(), models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "collaborator not found")
|
|
}
|
|
|
|
func TestPlaylistService_CheckPermission(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
collaboratorRead := createTestUserForService(t, db, "collaborator_read")
|
|
collaboratorWrite := createTestUserForService(t, db, "collaborator_write")
|
|
collaboratorAdmin := createTestUserForService(t, db, "collaborator_admin")
|
|
otherUser := createTestUserForService(t, db, "other_user")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Le propriétaire a toujours toutes les permissions
|
|
hasPermission, err := service.CheckPermission(ctx, playlist.ID, owner.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, owner.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, owner.ID, models.PlaylistPermissionAdmin)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
// Pour une playlist publique, tout le monde peut lire
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, otherUser.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
// Mais pas écrire
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, otherUser.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
assert.False(t, hasPermission)
|
|
|
|
// Ajouter des collaborateurs avec différentes permissions
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, owner.ID, collaboratorRead.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, owner.ID, collaboratorWrite.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, owner.ID, collaboratorAdmin.ID, models.PlaylistPermissionAdmin)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier les permissions du collaborateur read
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorRead.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorRead.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
assert.False(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorRead.ID, models.PlaylistPermissionAdmin)
|
|
assert.NoError(t, err)
|
|
assert.False(t, hasPermission)
|
|
|
|
// Vérifier les permissions du collaborateur write
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorWrite.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorWrite.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorWrite.ID, models.PlaylistPermissionAdmin)
|
|
assert.NoError(t, err)
|
|
assert.False(t, hasPermission)
|
|
|
|
// Vérifier les permissions du collaborateur admin
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorAdmin.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorAdmin.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
hasPermission, err = service.CheckPermission(ctx, playlist.ID, collaboratorAdmin.ID, models.PlaylistPermissionAdmin)
|
|
assert.NoError(t, err)
|
|
assert.True(t, hasPermission)
|
|
|
|
// Test avec playlist privée
|
|
privatePlaylist := createTestPlaylistForService(t, db, owner.ID)
|
|
privatePlaylist.IsPublic = false
|
|
err = db.Save(privatePlaylist).Error
|
|
assert.NoError(t, err)
|
|
|
|
// Un utilisateur non collaborateur ne peut pas lire une playlist privée
|
|
hasPermission, err = service.CheckPermission(ctx, privatePlaylist.ID, otherUser.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
assert.False(t, hasPermission)
|
|
|
|
// Test avec playlist inexistante
|
|
_, err = service.CheckPermission(ctx, uuid.New(), owner.ID, models.PlaylistPermissionRead)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "playlist not found")
|
|
}
|
|
|
|
func TestPlaylistService_GetCollaborators(t *testing.T) {
|
|
db := setupTestPlaylistServiceDB(t)
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := &gormUserRepository{db: db}
|
|
logger := zap.NewNop()
|
|
service := NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
ctx := context.Background()
|
|
|
|
owner := createTestUserForService(t, db, "owner")
|
|
collaborator1 := createTestUserForService(t, db, "collaborator1")
|
|
collaborator2 := createTestUserForService(t, db, "collaborator2")
|
|
otherUser := createTestUserForService(t, db, "other_user")
|
|
playlist := createTestPlaylistForService(t, db, owner.ID)
|
|
|
|
// Ajouter des collaborateurs
|
|
_, err := service.AddCollaborator(ctx, playlist.ID, owner.ID, collaborator1.ID, models.PlaylistPermissionRead)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = service.AddCollaborator(ctx, playlist.ID, owner.ID, collaborator2.ID, models.PlaylistPermissionWrite)
|
|
assert.NoError(t, err)
|
|
|
|
// Le propriétaire peut récupérer les collaborateurs
|
|
collaborators, err := service.GetCollaborators(ctx, playlist.ID, owner.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, collaborators, 2)
|
|
|
|
// Un collaborateur peut récupérer les collaborateurs
|
|
collaborators, err = service.GetCollaborators(ctx, playlist.ID, collaborator1.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, collaborators, 2)
|
|
|
|
// Un utilisateur non collaborateur peut récupérer les collaborateurs d'une playlist publique
|
|
collaborators, err = service.GetCollaborators(ctx, playlist.ID, otherUser.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, collaborators, 2)
|
|
|
|
// Test avec playlist privée
|
|
privatePlaylist := createTestPlaylistForService(t, db, owner.ID)
|
|
privatePlaylist.IsPublic = false
|
|
err = db.Save(privatePlaylist).Error
|
|
assert.NoError(t, err)
|
|
|
|
// Un utilisateur non collaborateur ne peut pas récupérer les collaborateurs d'une playlist privée
|
|
_, err = service.GetCollaborators(ctx, privatePlaylist.ID, otherUser.ID)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "forbidden")
|
|
}
|