Files
Tagger/tests/test_file.py

418 lines
15 KiB
Python
Raw Normal View History

2025-12-23 10:41:53 +01:00
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"
2025-12-30 07:54:30 +01:00
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"] == []