import pytest import json from pathlib import Path from src.core.file import File from src.core.tag import Tag from src.core.tag_manager import TagManager class TestFile: """Testy pro třídu File""" @pytest.fixture def temp_dir(self, tmp_path): """Fixture pro dočasný adresář""" return tmp_path @pytest.fixture def tag_manager(self): """Fixture pro TagManager""" return TagManager() @pytest.fixture def test_file(self, temp_dir): """Fixture pro testovací soubor""" test_file = temp_dir / "test.txt" test_file.write_text("test content") return test_file def test_file_creation(self, test_file, tag_manager): """Test vytvoření File objektu""" file_obj = File(test_file, tag_manager) assert file_obj.file_path == test_file assert file_obj.filename == "test.txt" assert file_obj.new == True def test_file_metadata_filename(self, test_file, tag_manager): """Test názvu metadata souboru""" file_obj = File(test_file, tag_manager) expected = test_file.parent / ".test.txt.!tag" assert file_obj.metadata_filename == expected def test_file_initial_tags(self, test_file, tag_manager): """Test že nový soubor má tag Stav/Nové""" file_obj = File(test_file, tag_manager) assert len(file_obj.tags) == 1 assert file_obj.tags[0].full_path == "Stav/Nové" def test_file_metadata_saved(self, test_file, tag_manager): """Test že metadata jsou uložena při vytvoření""" file_obj = File(test_file, tag_manager) assert file_obj.metadata_filename.exists() def test_file_save_metadata(self, test_file, tag_manager): """Test uložení metadat""" file_obj = File(test_file, tag_manager) file_obj.new = False file_obj.ignored = True file_obj.save_metadata() # Načtení a kontrola with open(file_obj.metadata_filename, "r", encoding="utf-8") as f: data = json.load(f) assert data["new"] == False assert data["ignored"] == True def test_file_load_metadata(self, test_file, tag_manager): """Test načtení metadat""" # Vytvoření a uložení metadat file_obj = File(test_file, tag_manager) tag = tag_manager.add_tag("Video", "HD") file_obj.tags.append(tag) file_obj.date = "2025-01-15" file_obj.save_metadata() # Vytvoření nového objektu - měl by načíst metadata file_obj2 = File(test_file, tag_manager) assert len(file_obj2.tags) == 2 # Stav/Nové + Video/HD assert file_obj2.date == "2025-01-15" # Kontrola že tagy obsahují správné hodnoty tag_paths = {tag.full_path for tag in file_obj2.tags} assert "Video/HD" in tag_paths assert "Stav/Nové" in tag_paths def test_file_set_date(self, test_file, tag_manager): """Test nastavení data""" file_obj = File(test_file, tag_manager) file_obj.set_date("2025-12-25") assert file_obj.date == "2025-12-25" # Kontrola že bylo uloženo with open(file_obj.metadata_filename, "r", encoding="utf-8") as f: data = json.load(f) assert data["date"] == "2025-12-25" def test_file_set_date_to_none(self, test_file, tag_manager): """Test smazání data""" file_obj = File(test_file, tag_manager) file_obj.set_date("2025-12-25") file_obj.set_date(None) assert file_obj.date is None def test_file_set_date_empty_string(self, test_file, tag_manager): """Test nastavení prázdného řetězce jako datum""" file_obj = File(test_file, tag_manager) file_obj.set_date("2025-12-25") file_obj.set_date("") assert file_obj.date is None def test_file_add_tag_object(self, test_file, tag_manager): """Test přidání Tag objektu""" file_obj = File(test_file, tag_manager) tag = Tag("Video", "4K") file_obj.add_tag(tag) assert tag in file_obj.tags assert len(file_obj.tags) == 2 # Stav/Nové + Video/4K def test_file_add_tag_string(self, test_file, tag_manager): """Test přidání tagu jako string""" file_obj = File(test_file, tag_manager) file_obj.add_tag("Audio/MP3") tag_paths = {tag.full_path for tag in file_obj.tags} assert "Audio/MP3" in tag_paths def test_file_add_tag_string_without_category(self, test_file, tag_manager): """Test přidání tagu bez kategorie (použije 'default')""" file_obj = File(test_file, tag_manager) file_obj.add_tag("SimpleTag") tag_paths = {tag.full_path for tag in file_obj.tags} assert "default/SimpleTag" in tag_paths def test_file_add_duplicate_tag(self, test_file, tag_manager): """Test že duplicitní tag není přidán""" file_obj = File(test_file, tag_manager) tag = Tag("Video", "HD") file_obj.add_tag(tag) file_obj.add_tag(tag) # Spočítáme kolikrát se tag vyskytuje count = sum(1 for t in file_obj.tags if t == tag) assert count == 1 def test_file_remove_tag_object(self, test_file, tag_manager): """Test odstranění Tag objektu""" file_obj = File(test_file, tag_manager) tag = Tag("Video", "HD") file_obj.add_tag(tag) file_obj.remove_tag(tag) assert tag not in file_obj.tags def test_file_remove_tag_string(self, test_file, tag_manager): """Test odstranění tagu jako string""" file_obj = File(test_file, tag_manager) file_obj.add_tag("Video/HD") file_obj.remove_tag("Video/HD") tag_paths = {tag.full_path for tag in file_obj.tags} assert "Video/HD" not in tag_paths def test_file_remove_tag_string_without_category(self, test_file, tag_manager): """Test odstranění tagu bez kategorie""" file_obj = File(test_file, tag_manager) file_obj.add_tag("SimpleTag") file_obj.remove_tag("SimpleTag") tag_paths = {tag.full_path for tag in file_obj.tags} assert "default/SimpleTag" not in tag_paths def test_file_remove_nonexistent_tag(self, test_file, tag_manager): """Test odstranění neexistujícího tagu (nemělo by vyhodit výjimku)""" file_obj = File(test_file, tag_manager) initial_count = len(file_obj.tags) file_obj.remove_tag("Nonexistent/Tag") assert len(file_obj.tags) == initial_count def test_file_without_tagmanager(self, test_file): """Test File bez TagManager""" file_obj = File(test_file, tagmanager=None) assert file_obj.tagmanager is None assert len(file_obj.tags) == 0 # Bez TagManager se nepřidá Stav/Nové def test_file_metadata_persistence(self, test_file, tag_manager): """Test že metadata přežijí reload""" # Vytvoření a úprava souboru file_obj1 = File(test_file, tag_manager) file_obj1.add_tag("Video/HD") file_obj1.add_tag("Audio/Stereo") file_obj1.set_date("2025-01-01") file_obj1.new = False file_obj1.ignored = True file_obj1.save_metadata() # Načtení nového objektu file_obj2 = File(test_file, tag_manager) # Kontrola assert file_obj2.new == False assert file_obj2.ignored == True assert file_obj2.date == "2025-01-01" tag_paths = {tag.full_path for tag in file_obj2.tags} assert "Video/HD" in tag_paths assert "Audio/Stereo" in tag_paths def test_file_metadata_json_format(self, test_file, tag_manager): """Test formátu JSON metadat""" file_obj = File(test_file, tag_manager) file_obj.add_tag("Test/Tag") file_obj.set_date("2025-06-15") # Kontrola obsahu JSON with open(file_obj.metadata_filename, "r", encoding="utf-8") as f: data = json.load(f) assert "new" in data assert "ignored" in data assert "tags" in data assert "date" in data assert isinstance(data["tags"], list) def test_file_unicode_handling(self, temp_dir, tag_manager): """Test správného zacházení s unicode znaky""" test_file = temp_dir / "český_soubor.txt" test_file.write_text("obsah") file_obj = File(test_file, tag_manager) file_obj.add_tag("Kategorie/Český tag") file_obj.save_metadata() # Reload a kontrola file_obj2 = File(test_file, tag_manager) tag_paths = {tag.full_path for tag in file_obj2.tags} assert "Kategorie/Český tag" in tag_paths def test_file_complex_scenario(self, test_file, tag_manager): """Test komplexního scénáře použití""" file_obj = File(test_file, tag_manager) # Přidání více tagů file_obj.add_tag("Video/HD") file_obj.add_tag("Video/Stereo") file_obj.add_tag("Stav/Zkontrolováno") file_obj.set_date("2025-01-01") # Odstranění tagu file_obj.remove_tag("Stav/Nové") # Kontrola stavu tag_paths = {tag.full_path for tag in file_obj.tags} assert "Video/HD" in tag_paths assert "Video/Stereo" in tag_paths assert "Stav/Zkontrolováno" in tag_paths assert "Stav/Nové" not in tag_paths assert file_obj.date == "2025-01-01" # Reload a kontrola persistence file_obj2 = File(test_file, tag_manager) tag_paths2 = {tag.full_path for tag in file_obj2.tags} assert tag_paths == tag_paths2 assert file_obj2.date == "2025-01-01" class TestFileCSFDIntegration: """Testy pro CSFD integraci v File""" @pytest.fixture def temp_dir(self, tmp_path): return tmp_path @pytest.fixture def tag_manager(self): return TagManager() @pytest.fixture def test_file(self, temp_dir): test_file = temp_dir / "film.mkv" test_file.write_text("video content") return test_file def test_file_csfd_url_initial(self, test_file, tag_manager): """Test že csfd_url je None při vytvoření""" file_obj = File(test_file, tag_manager) assert file_obj.csfd_url is None def test_file_set_csfd_url(self, test_file, tag_manager): """Test nastavení CSFD URL""" file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/9423-pane-vy-jste-vdova/") assert file_obj.csfd_url == "https://www.csfd.cz/film/9423-pane-vy-jste-vdova/" def test_file_set_csfd_url_persistence(self, test_file, tag_manager): """Test že CSFD URL přežije reload""" file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") file_obj2 = File(test_file, tag_manager) assert file_obj2.csfd_url == "https://www.csfd.cz/film/123/" def test_file_set_csfd_url_none(self, test_file, tag_manager): """Test smazání CSFD URL""" file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") file_obj.set_csfd_url(None) assert file_obj.csfd_url is None def test_file_set_csfd_url_empty(self, test_file, tag_manager): """Test nastavení prázdného řetězce jako CSFD URL""" file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") file_obj.set_csfd_url("") assert file_obj.csfd_url is None def test_file_csfd_url_in_metadata(self, test_file, tag_manager): """Test že CSFD URL je uložena v metadatech""" file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/999/") import json with open(file_obj.metadata_filename, "r", encoding="utf-8") as f: data = json.load(f) assert data["csfd_url"] == "https://www.csfd.cz/film/999/" def test_apply_csfd_tags_no_url(self, test_file, tag_manager): """Test apply_csfd_tags bez nastaveného URL""" file_obj = File(test_file, tag_manager) result = file_obj.apply_csfd_tags() assert result["success"] is False assert "URL není nastavena" in result["error"] assert result["tags_added"] == [] @pytest.fixture def mock_csfd_movie(self): """Mock CSFDMovie pro testování""" from unittest.mock import MagicMock movie = MagicMock() movie.title = "Test Film" movie.year = 2020 movie.genres = ["Komedie", "Drama"] movie.country = "Česko" movie.rating = 85 return movie def test_apply_csfd_tags_success(self, test_file, tag_manager, mock_csfd_movie): """Test úspěšného načtení tagů z CSFD""" from unittest.mock import patch file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") with patch("src.core.csfd.fetch_movie", return_value=mock_csfd_movie): result = file_obj.apply_csfd_tags() assert result["success"] is True assert "Žánr/Komedie" in result["tags_added"] assert "Žánr/Drama" in result["tags_added"] assert "Rok/2020" in result["tags_added"] assert "Země/Česko" in result["tags_added"] # Kontrola že tagy jsou opravdu přidány tag_paths = {tag.full_path for tag in file_obj.tags} assert "Žánr/Komedie" in tag_paths assert "Žánr/Drama" in tag_paths assert "Rok/2020" in tag_paths assert "Země/Česko" in tag_paths def test_apply_csfd_tags_genres_only(self, test_file, tag_manager, mock_csfd_movie): """Test načtení pouze žánrů""" from unittest.mock import patch file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") with patch("src.core.csfd.fetch_movie", return_value=mock_csfd_movie): result = file_obj.apply_csfd_tags(add_genres=True, add_year=False, add_country=False) assert result["success"] is True assert "Žánr/Komedie" in result["tags_added"] assert "Rok/2020" not in result["tags_added"] assert "Země/Česko" not in result["tags_added"] def test_apply_csfd_tags_no_duplicate(self, test_file, tag_manager, mock_csfd_movie): """Test že duplicitní tagy nejsou přidány""" from unittest.mock import patch file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") # Přidáme tag ručně file_obj.add_tag("Žánr/Komedie") with patch("src.core.csfd.fetch_movie", return_value=mock_csfd_movie): result = file_obj.apply_csfd_tags() # Komedie by neměla být v tags_added, protože už existuje assert "Žánr/Komedie" not in result["tags_added"] assert "Žánr/Drama" in result["tags_added"] def test_apply_csfd_tags_network_error(self, test_file, tag_manager): """Test chyby při načítání z CSFD""" from unittest.mock import patch file_obj = File(test_file, tag_manager) file_obj.set_csfd_url("https://www.csfd.cz/film/123/") with patch("src.core.csfd.fetch_movie", side_effect=Exception("Network error")): result = file_obj.apply_csfd_tags() assert result["success"] is False assert "error" in result assert result["tags_added"] == []