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