""" Unit tests for playlist_manager CRUD operations. Tests the core playlist management functions: - Loading playlists from file - Creating playlists - Getting playlists - Modifying playlists - Deleting playlists - Listing playlists - Renaming playlists """ import json import pytest from unittest.mock import patch, MagicMock class TestPlaylistManagerCRUD: """Tests for playlist CRUD operations.""" @pytest.fixture def playlists_file(self, tmp_path): """Create a temporary playlists.json file.""" file_path = tmp_path / "playlists.json" file_path.write_text("{}") return str(file_path) @pytest.fixture def playlist_manager_patched(self, playlists_file): """Patch PLAYLISTS_FILE to use temporary file.""" with patch("modules.core.playlist_manager.PLAYLISTS_FILE", playlists_file): # Need to re-import to get patched version from modules.core import playlist_manager yield playlist_manager def test_load_playlists_empty_file(self, playlists_file, playlist_manager_patched): """Test loading playlists from an empty file returns empty dict.""" result = playlist_manager_patched.load_playlists() assert result == {} def test_load_playlists_with_data(self, playlists_file, playlist_manager_patched): """Test loading playlists with existing data.""" # Write some data to the file with open(playlists_file, "w") as f: json.dump({"my_playlist": ["pattern1.thr", "pattern2.thr"]}, f) result = playlist_manager_patched.load_playlists() assert "my_playlist" in result assert result["my_playlist"] == ["pattern1.thr", "pattern2.thr"] def test_create_playlist(self, playlists_file, playlist_manager_patched): """Test creating a new playlist.""" files = ["circle.thr", "spiral.thr"] result = playlist_manager_patched.create_playlist("test_playlist", files) assert result is True # Verify it was saved playlists = playlist_manager_patched.load_playlists() assert "test_playlist" in playlists assert playlists["test_playlist"] == files def test_create_playlist_overwrites_existing(self, playlists_file, playlist_manager_patched): """Test creating a playlist with existing name overwrites it.""" # Create initial playlist playlist_manager_patched.create_playlist("test_playlist", ["old.thr"]) # Create again with same name playlist_manager_patched.create_playlist("test_playlist", ["new.thr"]) playlists = playlist_manager_patched.load_playlists() assert playlists["test_playlist"] == ["new.thr"] def test_get_playlist_exists(self, playlists_file, playlist_manager_patched): """Test getting an existing playlist.""" playlist_manager_patched.create_playlist("my_playlist", ["a.thr", "b.thr"]) result = playlist_manager_patched.get_playlist("my_playlist") assert result is not None assert result["name"] == "my_playlist" assert result["files"] == ["a.thr", "b.thr"] def test_get_playlist_not_found(self, playlists_file, playlist_manager_patched): """Test getting a non-existent playlist returns None.""" result = playlist_manager_patched.get_playlist("nonexistent") assert result is None def test_modify_playlist(self, playlists_file, playlist_manager_patched): """Test modifying an existing playlist.""" # Create initial playlist playlist_manager_patched.create_playlist("my_playlist", ["old.thr"]) # Modify it new_files = ["new1.thr", "new2.thr", "new3.thr"] result = playlist_manager_patched.modify_playlist("my_playlist", new_files) assert result is True # Verify changes playlist = playlist_manager_patched.get_playlist("my_playlist") assert playlist["files"] == new_files def test_delete_playlist(self, playlists_file, playlist_manager_patched): """Test deleting a playlist.""" # Create a playlist playlist_manager_patched.create_playlist("to_delete", ["pattern.thr"]) # Delete it result = playlist_manager_patched.delete_playlist("to_delete") assert result is True # Verify it's gone playlist = playlist_manager_patched.get_playlist("to_delete") assert playlist is None def test_delete_playlist_not_found(self, playlists_file, playlist_manager_patched): """Test deleting a non-existent playlist returns False.""" result = playlist_manager_patched.delete_playlist("nonexistent") assert result is False def test_list_all_playlists(self, playlists_file, playlist_manager_patched): """Test listing all playlist names.""" # Create multiple playlists playlist_manager_patched.create_playlist("playlist1", ["a.thr"]) playlist_manager_patched.create_playlist("playlist2", ["b.thr"]) playlist_manager_patched.create_playlist("playlist3", ["c.thr"]) result = playlist_manager_patched.list_all_playlists() assert len(result) == 3 assert "playlist1" in result assert "playlist2" in result assert "playlist3" in result def test_list_all_playlists_empty(self, playlists_file, playlist_manager_patched): """Test listing playlists when none exist.""" result = playlist_manager_patched.list_all_playlists() assert result == [] def test_add_to_playlist(self, playlists_file, playlist_manager_patched): """Test adding a pattern to an existing playlist.""" # Create playlist playlist_manager_patched.create_playlist("my_playlist", ["existing.thr"]) # Add pattern result = playlist_manager_patched.add_to_playlist("my_playlist", "new_pattern.thr") assert result is True # Verify playlist = playlist_manager_patched.get_playlist("my_playlist") assert "new_pattern.thr" in playlist["files"] assert len(playlist["files"]) == 2 def test_add_to_playlist_not_found(self, playlists_file, playlist_manager_patched): """Test adding to a non-existent playlist returns False.""" result = playlist_manager_patched.add_to_playlist("nonexistent", "pattern.thr") assert result is False class TestPlaylistRename: """Tests for playlist rename functionality.""" @pytest.fixture def playlists_file(self, tmp_path): """Create a temporary playlists.json file.""" file_path = tmp_path / "playlists.json" file_path.write_text("{}") return str(file_path) @pytest.fixture def playlist_manager_patched(self, playlists_file): """Patch PLAYLISTS_FILE to use temporary file.""" with patch("modules.core.playlist_manager.PLAYLISTS_FILE", playlists_file): from modules.core import playlist_manager yield playlist_manager def test_rename_playlist_success(self, playlists_file, playlist_manager_patched): """Test successfully renaming a playlist.""" # Create initial playlist playlist_manager_patched.create_playlist("old_name", ["a.thr", "b.thr"]) # Rename it success, message = playlist_manager_patched.rename_playlist("old_name", "new_name") assert success is True assert "new_name" in message # Verify old name is gone assert playlist_manager_patched.get_playlist("old_name") is None # Verify new name exists with same files new_playlist = playlist_manager_patched.get_playlist("new_name") assert new_playlist is not None assert new_playlist["files"] == ["a.thr", "b.thr"] def test_rename_playlist_not_found(self, playlists_file, playlist_manager_patched): """Test renaming a non-existent playlist.""" success, message = playlist_manager_patched.rename_playlist("nonexistent", "new_name") assert success is False assert "not found" in message.lower() def test_rename_playlist_empty_name(self, playlists_file, playlist_manager_patched): """Test renaming with empty name fails.""" playlist_manager_patched.create_playlist("my_playlist", ["a.thr"]) success, message = playlist_manager_patched.rename_playlist("my_playlist", "") assert success is False assert "empty" in message.lower() def test_rename_playlist_whitespace_name(self, playlists_file, playlist_manager_patched): """Test renaming with whitespace-only name fails.""" playlist_manager_patched.create_playlist("my_playlist", ["a.thr"]) success, message = playlist_manager_patched.rename_playlist("my_playlist", " ") assert success is False assert "empty" in message.lower() def test_rename_playlist_same_name(self, playlists_file, playlist_manager_patched): """Test renaming to the same name succeeds with unchanged message.""" playlist_manager_patched.create_playlist("my_playlist", ["a.thr"]) success, message = playlist_manager_patched.rename_playlist("my_playlist", "my_playlist") assert success is True assert "unchanged" in message.lower() def test_rename_playlist_name_exists(self, playlists_file, playlist_manager_patched): """Test renaming to an existing playlist name fails.""" playlist_manager_patched.create_playlist("playlist1", ["a.thr"]) playlist_manager_patched.create_playlist("playlist2", ["b.thr"]) success, message = playlist_manager_patched.rename_playlist("playlist1", "playlist2") assert success is False assert "already exists" in message.lower() def test_rename_playlist_trims_whitespace(self, playlists_file, playlist_manager_patched): """Test renaming trims whitespace from new name.""" playlist_manager_patched.create_playlist("old_name", ["a.thr"]) success, message = playlist_manager_patched.rename_playlist("old_name", " new_name ") assert success is True # Verify trimmed name is used assert playlist_manager_patched.get_playlist("new_name") is not None assert playlist_manager_patched.get_playlist(" new_name ") is None