Store library settings in the pool index and drop legacy sidecars

This commit is contained in:
2026-07-03 16:06:45 +02:00
parent f0f38d4257
commit 7ae0709f38
13 changed files with 379 additions and 2292 deletions
+8 -182
View File
@@ -2,8 +2,6 @@ import pytest
import json
from src.core.config import (
load_global_config, save_global_config, DEFAULT_GLOBAL_CONFIG,
load_folder_config, save_folder_config, DEFAULT_FOLDER_CONFIG,
get_folder_config_path, folder_has_config, FOLDER_CONFIG_NAME,
load_config, save_config # Legacy functions
)
@@ -20,16 +18,23 @@ class TestGlobalConfig:
return config_path
def test_default_global_config_structure(self):
"""Test struktury defaultní globální konfigurace"""
"""Test struktury defaultní globální konfigurace (jen data aplikace)"""
assert "window_geometry" in DEFAULT_GLOBAL_CONFIG
assert "window_maximized" in DEFAULT_GLOBAL_CONFIG
assert "last_folder" in DEFAULT_GLOBAL_CONFIG
assert "sidebar_width" in DEFAULT_GLOBAL_CONFIG
assert "recent_folders" in DEFAULT_GLOBAL_CONFIG
assert "pool_dir" in DEFAULT_GLOBAL_CONFIG
assert "filmoteka_dir" in DEFAULT_GLOBAL_CONFIG
assert DEFAULT_GLOBAL_CONFIG["window_geometry"] == "1200x800"
assert DEFAULT_GLOBAL_CONFIG["window_maximized"] is False
assert DEFAULT_GLOBAL_CONFIG["last_folder"] is None
def test_global_config_holds_no_library_settings(self):
"""Library settings (tag_schema / copyasis_folders) žijí v indexu, ne tady."""
assert "tag_schema" not in DEFAULT_GLOBAL_CONFIG
assert "copyasis_folders" not in DEFAULT_GLOBAL_CONFIG
def test_load_global_config_nonexistent_file(self, temp_global_config):
"""Test načtení globální konfigurace když soubor neexistuje"""
config = load_global_config()
@@ -62,8 +67,6 @@ class TestGlobalConfig:
"recent_folders": [],
"pool_dir": None,
"filmoteka_dir": None,
"copyasis_folders": ["Seriály"],
"tag_schema": DEFAULT_GLOBAL_CONFIG["tag_schema"],
}
save_global_config(test_config)
@@ -125,150 +128,6 @@ class TestGlobalConfig:
assert len(loaded["recent_folders"]) == 3
class TestFolderConfig:
"""Testy pro složkový config"""
def test_default_folder_config_structure(self):
"""Test struktury defaultní složkové konfigurace"""
assert "ignore_patterns" in DEFAULT_FOLDER_CONFIG
assert "custom_tags" in DEFAULT_FOLDER_CONFIG
assert "recursive" in DEFAULT_FOLDER_CONFIG
assert isinstance(DEFAULT_FOLDER_CONFIG["ignore_patterns"], list)
assert isinstance(DEFAULT_FOLDER_CONFIG["custom_tags"], dict)
assert DEFAULT_FOLDER_CONFIG["recursive"] is True
def test_get_folder_config_path(self, tmp_path):
"""Test získání cesty ke složkovému configu"""
path = get_folder_config_path(tmp_path)
assert path == tmp_path / FOLDER_CONFIG_NAME
assert path.name == ".Curator.!ftag"
def test_load_folder_config_nonexistent(self, tmp_path):
"""Test načtení neexistujícího složkového configu"""
config = load_folder_config(tmp_path)
assert config == DEFAULT_FOLDER_CONFIG
def test_save_folder_config(self, tmp_path):
"""Test uložení složkového configu"""
test_config = {
"ignore_patterns": ["*.tmp", "*.log"],
"custom_tags": {"Projekt": ["Web", "API"]},
"recursive": False,
}
save_folder_config(tmp_path, test_config)
config_path = get_folder_config_path(tmp_path)
assert config_path.exists()
with open(config_path, "r", encoding="utf-8") as f:
saved_data = json.load(f)
assert saved_data == test_config
def test_load_folder_config_existing(self, tmp_path):
"""Test načtení existujícího složkového configu"""
test_config = {
"ignore_patterns": ["*.pyc"],
"custom_tags": {},
"recursive": True,
"hardlink_output_dir": None,
"hardlink_categories": None,
}
save_folder_config(tmp_path, test_config)
loaded = load_folder_config(tmp_path)
assert loaded == test_config
def test_load_folder_config_merges_defaults(self, tmp_path):
"""Test že chybějící klíče jsou doplněny z defaultů"""
partial_config = {"ignore_patterns": ["*.tmp"]}
config_path = get_folder_config_path(tmp_path)
with open(config_path, "w", encoding="utf-8") as f:
json.dump(partial_config, f)
loaded = load_folder_config(tmp_path)
assert loaded["ignore_patterns"] == ["*.tmp"]
assert loaded["custom_tags"] == DEFAULT_FOLDER_CONFIG["custom_tags"]
assert loaded["recursive"] == DEFAULT_FOLDER_CONFIG["recursive"]
def test_folder_has_config_true(self, tmp_path):
"""Test folder_has_config když config existuje"""
save_folder_config(tmp_path, DEFAULT_FOLDER_CONFIG)
assert folder_has_config(tmp_path) is True
def test_folder_has_config_false(self, tmp_path):
"""Test folder_has_config když config neexistuje"""
assert folder_has_config(tmp_path) is False
def test_folder_config_ignore_patterns(self, tmp_path):
"""Test ukládání ignore patterns"""
patterns = ["*.tmp", "*.log", "*.cache", "*/node_modules/*", "*.pyc"]
test_config = {**DEFAULT_FOLDER_CONFIG, "ignore_patterns": patterns}
save_folder_config(tmp_path, test_config)
loaded = load_folder_config(tmp_path)
assert loaded["ignore_patterns"] == patterns
assert len(loaded["ignore_patterns"]) == 5
def test_folder_config_custom_tags(self, tmp_path):
"""Test ukládání custom tagů"""
custom_tags = {
"Projekt": ["Frontend", "Backend", "API"],
"Stav": ["Hotovo", "Rozpracováno"],
}
test_config = {**DEFAULT_FOLDER_CONFIG, "custom_tags": custom_tags}
save_folder_config(tmp_path, test_config)
loaded = load_folder_config(tmp_path)
assert loaded["custom_tags"] == custom_tags
def test_folder_config_corrupted_file(self, tmp_path):
"""Test načtení poškozeného folder config souboru"""
config_path = get_folder_config_path(tmp_path)
with open(config_path, "w") as f:
f.write("{ invalid json }")
config = load_folder_config(tmp_path)
assert config == DEFAULT_FOLDER_CONFIG
def test_folder_config_utf8_encoding(self, tmp_path):
"""Test UTF-8 v folder configu"""
test_config = {
"ignore_patterns": ["*.čeština"],
"custom_tags": {"Štítky": ["Červená", "Žlutá"]},
"recursive": True,
}
save_folder_config(tmp_path, test_config)
loaded = load_folder_config(tmp_path)
assert loaded["ignore_patterns"] == ["*.čeština"]
assert loaded["custom_tags"]["Štítky"] == ["Červená", "Žlutá"]
def test_multiple_folders_independent_configs(self, tmp_path):
"""Test že různé složky mají nezávislé configy"""
folder1 = tmp_path / "folder1"
folder2 = tmp_path / "folder2"
folder1.mkdir()
folder2.mkdir()
config1 = {**DEFAULT_FOLDER_CONFIG, "ignore_patterns": ["*.txt"]}
config2 = {**DEFAULT_FOLDER_CONFIG, "ignore_patterns": ["*.jpg"]}
save_folder_config(folder1, config1)
save_folder_config(folder2, config2)
loaded1 = load_folder_config(folder1)
loaded2 = load_folder_config(folder2)
assert loaded1["ignore_patterns"] == ["*.txt"]
assert loaded2["ignore_patterns"] == ["*.jpg"]
class TestLegacyFunctions:
"""Testy pro zpětnou kompatibilitu"""
@@ -342,18 +201,6 @@ class TestConfigEdgeCases:
assert len(loaded["recent_folders"]) == 100
def test_folder_config_special_characters_in_patterns(self, tmp_path):
"""Test se speciálními znaky v patterns"""
test_config = {
**DEFAULT_FOLDER_CONFIG,
"ignore_patterns": ["*.tmp", "file[0-9].txt", "test?.log"]
}
save_folder_config(tmp_path, test_config)
loaded = load_folder_config(tmp_path)
assert loaded["ignore_patterns"] == test_config["ignore_patterns"]
def test_config_json_formatting(self, temp_global_config):
"""Test že config je uložen ve správném JSON formátu s indentací"""
test_config = {**DEFAULT_GLOBAL_CONFIG}
@@ -391,24 +238,3 @@ class TestConfigEdgeCases:
loaded = load_global_config()
assert loaded["last_folder"] == "/path2"
def test_folder_config_recursive_false(self, tmp_path):
"""Test nastavení recursive na False"""
test_config = {**DEFAULT_FOLDER_CONFIG, "recursive": False}
save_folder_config(tmp_path, test_config)
loaded = load_folder_config(tmp_path)
assert loaded["recursive"] is False
def test_empty_folder_config(self, tmp_path):
"""Test prázdného folder configu"""
config_path = get_folder_config_path(tmp_path)
with open(config_path, "w", encoding="utf-8") as f:
json.dump({}, f)
loaded = load_folder_config(tmp_path)
# Mělo by doplnit všechny defaulty
assert loaded["ignore_patterns"] == []
assert loaded["custom_tags"] == {}
assert loaded["recursive"] is True
+97 -151
View File
@@ -1,191 +1,154 @@
import pytest
import json
from pathlib import Path
from src.core.file import File
from src.core.pool_index import PoolIndex
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
"""Testy pro třídu File (metadata žijí v pool indexu)"""
@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 index(self, tmp_path):
"""Pool index that backs the File's metadata."""
return PoolIndex(tmp_path)
def test_file_creation(self, test_file, tag_manager):
"""Test vytvoření File objektu"""
file_obj = File(test_file, tag_manager)
@pytest.fixture
def test_file(self, tmp_path):
f = tmp_path / "test.txt"
f.write_text("test content")
return f
def test_file_creation(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
assert file_obj.file_path == test_file
assert file_obj.filename == "test.txt"
assert file_obj.new == True
assert file_obj.new is 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 nemá žádné automatické tagy (Stav/Nové odstraněn)"""
file_obj = File(test_file, tag_manager)
def test_file_initial_tags(self, test_file, tag_manager, index):
"""Nový soubor nemá žádné automatické tagy (Stav/Nové odstraněn)."""
file_obj = File(test_file, tag_manager, index=index)
assert file_obj.tags == []
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_metadata_saved_to_index(self, test_file, tag_manager, index):
"""Metadata jsou zapsána do indexu už při vytvoření."""
file_obj = File(test_file, tag_manager, index=index)
assert index.get(file_obj.file_path) is not None
def test_file_save_metadata(self, test_file, tag_manager):
"""Test uložení metadat"""
def test_file_no_sidecar_written(self, test_file, tag_manager, index):
"""Žádný .!tag sidecar už nevzniká."""
File(test_file, tag_manager, index=index)
assert not (test_file.parent / ".test.txt.!tag").exists()
def test_index_less_file_is_in_memory_only(self, test_file, tag_manager):
"""Bez indexu je File jen v paměti — nic se nezapíše na disk."""
file_obj = File(test_file, tag_manager)
file_obj.add_tag("Video/HD")
file_obj.save_metadata() # no-op
assert not (test_file.parent / ".test.txt.!tag").exists()
def test_file_save_metadata(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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)
data = index.get(file_obj.file_path)
assert data["new"] is False
assert data["ignored"] is True
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)
def test_file_load_metadata(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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)
# A fresh File over the same index reloads the metadata
file_obj2 = File(test_file, tag_manager, index=index)
assert len(file_obj2.tags) == 1 # Video/HD
assert file_obj2.date == "2025-01-15"
assert "Video/HD" in {t.full_path for t in file_obj2.tags}
# Kontrola že tagy obsahují správné hodnoty
tag_paths = {tag.full_path for tag in file_obj2.tags}
assert "Video/HD" in tag_paths
def test_file_set_date(self, test_file, tag_manager):
"""Test nastavení data"""
file_obj = File(test_file, tag_manager)
def test_file_set_date(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
file_obj.set_date("2025-12-25")
assert file_obj.date == "2025-12-25"
assert index.get(file_obj.file_path)["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)
def test_file_set_date_to_none(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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)
def test_file_set_date_empty_string(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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)
def test_file_add_tag_object(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
tag = Tag("Video", "4K")
file_obj.add_tag(tag)
assert tag in file_obj.tags
assert len(file_obj.tags) == 1 # Video/4K
assert len(file_obj.tags) == 1
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)
def test_file_add_tag_string(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
file_obj.add_tag("Audio/MP3")
assert "Audio/MP3" in {t.full_path for t in file_obj.tags}
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)
def test_file_add_tag_string_without_category(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
file_obj.add_tag("SimpleTag")
assert "default/SimpleTag" in {t.full_path for t in file_obj.tags}
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)
def test_file_add_duplicate_tag(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
tag = Tag("Video", "HD")
file_obj.add_tag(tag)
file_obj.add_tag(tag)
assert sum(1 for t in file_obj.tags if t == tag) == 1
# 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)
def test_file_remove_tag_object(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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)
def test_file_remove_tag_string(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
file_obj.add_tag("Video/HD")
file_obj.remove_tag("Video/HD")
assert "Video/HD" not in {t.full_path for t in file_obj.tags}
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)
def test_file_remove_tag_string_without_category(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
file_obj.add_tag("SimpleTag")
file_obj.remove_tag("SimpleTag")
assert "default/SimpleTag" not in {t.full_path for t in file_obj.tags}
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)
def test_file_remove_nonexistent_tag(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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 # nový soubor nemá žádné automatické tagy
assert len(file_obj.tags) == 0
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)
def test_file_metadata_persistence(self, test_file, tag_manager, index):
file_obj1 = File(test_file, tag_manager, index=index)
file_obj1.add_tag("Video/HD")
file_obj1.add_tag("Audio/Stereo")
file_obj1.set_date("2025-01-01")
@@ -193,73 +156,54 @@ class TestFile:
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
file_obj2 = File(test_file, tag_manager, index=index)
assert file_obj2.new is False
assert file_obj2.ignored is True
assert file_obj2.date == "2025-01-01"
tag_paths = {tag.full_path for tag in file_obj2.tags}
tag_paths = {t.full_path for t 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)
def test_file_metadata_record_shape(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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)
data = index.get(file_obj.file_path)
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"
def test_file_unicode_handling(self, tmp_path, tag_manager, index):
test_file = tmp_path / "český_soubor.txt"
test_file.write_text("obsah")
file_obj = File(test_file, tag_manager)
file_obj = File(test_file, tag_manager, index=index)
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
file_obj2 = File(test_file, tag_manager, index=index)
assert "Kategorie/Český tag" in {t.full_path for t in file_obj2.tags}
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ů
def test_file_complex_scenario(self, test_file, tag_manager, index):
file_obj = File(test_file, tag_manager, index=index)
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}
tag_paths = {t.full_path for t 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
file_obj2 = File(test_file, tag_manager, index=index)
assert {t.full_path for t in file_obj2.tags} == tag_paths
assert file_obj2.date == "2025-01-01"
@@ -271,10 +215,14 @@ class TestApplyCsfdTags:
return TagManager()
@pytest.fixture
def movie_file(self, tmp_path, tag_manager):
def index(self, tmp_path):
return PoolIndex(tmp_path)
@pytest.fixture
def movie_file(self, tmp_path, tag_manager, index):
path = tmp_path / "Matrix.mkv"
path.write_text("x")
f = File(path, tag_manager)
f = File(path, tag_manager, index=index)
f.set_csfd_link("https://www.csfd.cz/film/9499-matrix/")
return f
@@ -314,7 +262,6 @@ class TestApplyCsfdTags:
paths = {t.full_path for t in movie_file.tags}
assert not any(p.startswith("Režie/") for p in paths)
assert not any(p.startswith("Herec/") for p in paths)
# …but the data is kept in the cache
cached = movie_file.get_cached_movie()
assert cached.directors == ["Lana Wachowski"]
assert cached.actors == ["Keanu Reeves", "Laurence Fishburne"]
@@ -392,7 +339,6 @@ class TestApplyCsfdTags:
first = CSFDMovie(title="A", url="u", year=1999, genres=["Akční"])
with patch("src.core.csfd.fetch_movie", return_value=first):
movie_file.apply_csfd_tags()
# different movie on re-fetch
second = CSFDMovie(title="B", url="u", year=2009, genres=["Drama"])
with patch("src.core.csfd.fetch_movie", return_value=second):
movie_file.apply_csfd_tags()
+113 -468
View File
@@ -1,294 +1,55 @@
import pytest
from src.core.file import File
from src.core.file_manager import FileManager
from src.core.tag_manager import TagManager
from src.core.tag import Tag
@pytest.fixture
def temp_global_config(tmp_path, monkeypatch):
"""Point the global config file at a throwaway path for each test."""
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, "GLOBAL_CONFIG_FILE", config_path)
return config_path
@pytest.fixture
def tag_manager():
return TagManager()
@pytest.fixture
def file_manager(tag_manager, temp_global_config):
return FileManager(tag_manager)
def _in_memory_files(tmp_path, tag_manager, *names):
"""Create real files and wrap them as index-less (in-memory) File objects."""
files = []
for name in names:
path = tmp_path / name
path.write_text("content")
files.append(File(path, tag_manager))
return files
class TestFileManager:
"""Testy pro třídu FileManager"""
@pytest.fixture
def tag_manager(self):
"""Fixture pro TagManager"""
return TagManager()
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
"""Fixture pro FileManager"""
return FileManager(tag_manager)
@pytest.fixture
def temp_dir(self, tmp_path):
"""Fixture pro dočasný adresář s testovacími soubory"""
# Vytvoření struktury souborů
(tmp_path / "file1.txt").write_text("content1")
(tmp_path / "file2.txt").write_text("content2")
(tmp_path / "file3.jpg").write_text("image")
# Podsložka
subdir = tmp_path / "subdir"
subdir.mkdir()
(subdir / "file4.txt").write_text("content4")
return tmp_path
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
"""Fixture pro dočasný global config soubor"""
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
"""Basic FileManager state."""
def test_file_manager_creation(self, file_manager, tag_manager):
"""Test vytvoření FileManager"""
assert file_manager.filelist == []
assert file_manager.folders == []
assert file_manager.tagmanager == tag_manager
assert file_manager.global_config is not None
assert file_manager.folder_configs == {}
assert file_manager.current_folder is None
def test_file_manager_append_folder(self, file_manager, temp_dir):
"""Test přidání složky"""
file_manager.append(temp_dir)
assert temp_dir in file_manager.folders
assert len(file_manager.filelist) > 0
assert file_manager.current_folder == temp_dir
def test_file_manager_append_folder_finds_all_files(self, file_manager, temp_dir):
"""Test že append najde všechny soubory včetně podsložek"""
file_manager.append(temp_dir)
# Měli bychom najít file1.txt, file2.txt, file3.jpg, subdir/file4.txt
# (ne .!tag soubory)
filenames = {f.filename for f in file_manager.filelist}
assert "file1.txt" in filenames
assert "file2.txt" in filenames
assert "file3.jpg" in filenames
assert "file4.txt" in filenames
def test_file_manager_ignores_tag_files(self, file_manager, temp_dir):
"""Test že .!tag soubory jsou ignorovány"""
# Vytvoření .!tag souboru
(temp_dir / ".file1.txt.!tag").write_text('{"tags": []}')
file_manager.append(temp_dir)
filenames = {f.filename for f in file_manager.filelist}
assert ".file1.txt.!tag" not in filenames
def test_file_manager_ignores_curator_config_files(self, file_manager, temp_dir):
"""Test že Curator config soubory jsou ignorovány"""
(temp_dir / ".Curator.!ftag").write_text('{}') # Folder config
(temp_dir / ".Curator.!gtag").write_text('{}') # Global config
file_manager.append(temp_dir)
filenames = {f.filename for f in file_manager.filelist}
assert ".Curator.!ftag" not in filenames
assert ".Curator.!gtag" not in filenames
def test_file_manager_updates_last_folder(self, file_manager, temp_dir):
"""Test aktualizace last_folder v global configu"""
file_manager.append(temp_dir)
assert file_manager.global_config["last_folder"] == str(temp_dir)
def test_file_manager_updates_recent_folders(self, file_manager, temp_dir):
"""Test aktualizace recent_folders"""
file_manager.append(temp_dir)
assert str(temp_dir) in file_manager.global_config["recent_folders"]
assert file_manager.global_config["recent_folders"][0] == str(temp_dir)
def test_file_manager_recent_folders_max_10(self, file_manager, tmp_path):
"""Test že recent_folders má max 10 položek"""
for i in range(15):
folder = tmp_path / f"folder{i}"
folder.mkdir()
(folder / "file.txt").write_text("content")
file_manager.append(folder)
assert len(file_manager.global_config["recent_folders"]) <= 10
def test_file_manager_loads_folder_config(self, file_manager, temp_dir):
"""Test že se načte folder config při append"""
file_manager.append(temp_dir)
assert temp_dir in file_manager.folder_configs
assert "ignore_patterns" in file_manager.folder_configs[temp_dir]
class TestFileManagerIgnorePatterns:
"""Testy pro ignore patterns"""
@pytest.fixture
def tag_manager(self):
return TagManager()
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
return FileManager(tag_manager)
@pytest.fixture
def temp_dir(self, tmp_path):
(tmp_path / "file1.txt").write_text("content1")
(tmp_path / "file2.txt").write_text("content2")
(tmp_path / "file3.jpg").write_text("image")
subdir = tmp_path / "subdir"
subdir.mkdir()
(subdir / "file4.txt").write_text("content4")
return tmp_path
def test_ignore_patterns_by_extension(self, file_manager, temp_dir):
"""Test ignorování souborů podle přípony"""
from src.core.config import save_folder_config
save_folder_config(temp_dir, {"ignore_patterns": ["*.jpg"], "custom_tags": {}, "recursive": True})
file_manager.append(temp_dir)
filenames = {f.filename for f in file_manager.filelist}
assert "file3.jpg" not in filenames
assert "file1.txt" in filenames
def test_ignore_patterns_path(self, file_manager, temp_dir):
"""Test ignorování podle celé cesty"""
from src.core.config import save_folder_config
save_folder_config(temp_dir, {"ignore_patterns": ["*/subdir/*"], "custom_tags": {}, "recursive": True})
file_manager.append(temp_dir)
filenames = {f.filename for f in file_manager.filelist}
assert "file4.txt" not in filenames
assert "file1.txt" in filenames
def test_multiple_ignore_patterns(self, file_manager, temp_dir):
"""Test více ignore patternů najednou"""
from src.core.config import save_folder_config
save_folder_config(temp_dir, {"ignore_patterns": ["*.jpg", "*/subdir/*"], "custom_tags": {}, "recursive": True})
file_manager.append(temp_dir)
filenames = {f.filename for f in file_manager.filelist}
assert "file3.jpg" not in filenames
assert "file4.txt" not in filenames
assert "file1.txt" in filenames
assert "file2.txt" in filenames
def test_set_ignore_patterns(self, file_manager, temp_dir):
"""Test nastavení ignore patterns přes metodu"""
file_manager.append(temp_dir)
file_manager.set_ignore_patterns(["*.tmp", "*.log"])
patterns = file_manager.get_ignore_patterns()
assert patterns == ["*.tmp", "*.log"]
def test_get_ignore_patterns_empty(self, file_manager, temp_dir):
"""Test získání prázdných ignore patterns"""
file_manager.append(temp_dir)
patterns = file_manager.get_ignore_patterns()
assert patterns == []
class TestFileManagerFolderConfig:
"""Testy pro folder config management"""
@pytest.fixture
def tag_manager(self):
return TagManager()
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
return FileManager(tag_manager)
@pytest.fixture
def temp_dir(self, tmp_path):
(tmp_path / "file1.txt").write_text("content")
return tmp_path
def test_get_folder_config_current(self, file_manager, temp_dir):
"""Test získání configu pro aktuální složku"""
file_manager.append(temp_dir)
config = file_manager.get_folder_config()
assert "ignore_patterns" in config
def test_get_folder_config_specific(self, file_manager, temp_dir, tmp_path):
"""Test získání configu pro specifickou složku"""
folder2 = tmp_path / "folder2"
folder2.mkdir()
(folder2 / "file.txt").write_text("content")
file_manager.append(temp_dir)
file_manager.append(folder2)
config = file_manager.get_folder_config(temp_dir)
assert config is not None
def test_get_folder_config_no_current(self, file_manager):
"""Test získání configu když není current folder"""
config = file_manager.get_folder_config()
assert config == {}
def test_save_folder_config(self, file_manager, temp_dir):
"""Test uložení folder configu"""
file_manager.append(temp_dir)
new_config = {"ignore_patterns": ["*.test"], "custom_tags": {}, "recursive": False}
file_manager.save_folder_config(config=new_config)
loaded = file_manager.get_folder_config()
assert loaded["ignore_patterns"] == ["*.test"]
assert loaded["recursive"] is False
assert file_manager.index is None
class TestFileManagerTagOperations:
"""Testy pro operace s tagy"""
"""assign/remove tag operations over the loaded file list."""
@pytest.fixture
def tag_manager(self):
return TagManager()
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
return FileManager(tag_manager)
@pytest.fixture
def temp_dir(self, tmp_path):
(tmp_path / "file1.txt").write_text("content1")
(tmp_path / "file2.txt").write_text("content2")
(tmp_path / "file3.txt").write_text("content3")
return tmp_path
def test_assign_tag_to_file_objects_tag_object(self, file_manager, temp_dir):
"""Test přiřazení Tag objektu k souborům"""
file_manager.append(temp_dir)
files = file_manager.filelist[:2]
def test_assign_tag_to_file_objects_tag_object(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt", "f2.txt")
file_manager.filelist = files
tag = Tag("Video", "HD")
file_manager.assign_tag_to_file_objects(files, tag)
@@ -296,30 +57,27 @@ class TestFileManagerTagOperations:
for f in files:
assert tag in f.tags
def test_assign_tag_string_with_category(self, file_manager, temp_dir):
"""Test přiřazení tagu jako string s kategorií"""
file_manager.append(temp_dir)
files = file_manager.filelist[:1]
def test_assign_tag_string_with_category(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt")
file_manager.filelist = files
file_manager.assign_tag_to_file_objects(files, "Video/4K")
tag_paths = {tag.full_path for tag in files[0].tags}
assert "Video/4K" in tag_paths
def test_assign_tag_string_without_category(self, file_manager, temp_dir):
"""Test přiřazení tagu bez kategorie (default)"""
file_manager.append(temp_dir)
files = file_manager.filelist[:1]
def test_assign_tag_string_without_category(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt")
file_manager.filelist = files
file_manager.assign_tag_to_file_objects(files, "SimpleTag")
tag_paths = {tag.full_path for tag in files[0].tags}
assert "default/SimpleTag" in tag_paths
def test_assign_tag_no_duplicate(self, file_manager, temp_dir):
"""Test že tag není přidán dvakrát"""
file_manager.append(temp_dir)
files = file_manager.filelist[:1]
def test_assign_tag_no_duplicate(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt")
file_manager.filelist = files
tag = Tag("Video", "HD")
file_manager.assign_tag_to_file_objects(files, tag)
@@ -328,10 +86,9 @@ class TestFileManagerTagOperations:
count = sum(1 for t in files[0].tags if t == tag)
assert count == 1
def test_remove_tag_from_file_objects(self, file_manager, temp_dir):
"""Test odstranění tagu ze souborů"""
file_manager.append(temp_dir)
files = file_manager.filelist[:2]
def test_remove_tag_from_file_objects(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt", "f2.txt")
file_manager.filelist = files
tag = Tag("Video", "HD")
file_manager.assign_tag_to_file_objects(files, tag)
@@ -340,10 +97,9 @@ class TestFileManagerTagOperations:
for f in files:
assert tag not in f.tags
def test_remove_tag_string(self, file_manager, temp_dir):
"""Test odstranění tagu jako string"""
file_manager.append(temp_dir)
files = file_manager.filelist[:1]
def test_remove_tag_string(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt")
file_manager.filelist = files
file_manager.assign_tag_to_file_objects(files, "Video/HD")
file_manager.remove_tag_from_file_objects(files, "Video/HD")
@@ -351,210 +107,73 @@ class TestFileManagerTagOperations:
tag_paths = {tag.full_path for tag in files[0].tags}
assert "Video/HD" not in tag_paths
def test_callback_on_tag_change(self, file_manager, temp_dir):
"""Test callback při změně tagů"""
file_manager.append(temp_dir)
def test_callback_on_tag_change(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt")
file_manager.filelist = files
callback_calls = []
file_manager.on_files_changed = lambda filelist: callback_calls.append(len(filelist))
def callback(filelist):
callback_calls.append(len(filelist))
file_manager.on_files_changed = callback
file_manager.assign_tag_to_file_objects([file_manager.filelist[0]], Tag("Test", "Tag"))
file_manager.assign_tag_to_file_objects([files[0]], Tag("Test", "Tag"))
assert len(callback_calls) == 1
class TestFileManagerFiltering:
"""Testy pro filtrování souborů"""
"""filter_files_by_tags over the loaded file list."""
@pytest.fixture
def tag_manager(self):
return TagManager()
def loaded(self, file_manager, tmp_path, tag_manager):
files = _in_memory_files(tmp_path, tag_manager, "f1.txt", "f2.txt", "f3.txt")
file_manager.filelist = files
return file_manager
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
def test_filter_empty_tags_returns_all(self, loaded):
assert len(loaded.filter_files_by_tags([])) == len(loaded.filelist)
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
return FileManager(tag_manager)
def test_filter_none_returns_all(self, loaded):
assert len(loaded.filter_files_by_tags(None)) == len(loaded.filelist)
@pytest.fixture
def temp_dir(self, tmp_path):
(tmp_path / "file1.txt").write_text("content1")
(tmp_path / "file2.txt").write_text("content2")
(tmp_path / "file3.txt").write_text("content3")
return tmp_path
def test_filter_empty_tags_returns_all(self, file_manager, temp_dir):
"""Test filtrace bez tagů vrací všechny soubory"""
file_manager.append(temp_dir)
filtered = file_manager.filter_files_by_tags([])
assert len(filtered) == len(file_manager.filelist)
def test_filter_none_returns_all(self, file_manager, temp_dir):
"""Test filtrace s None vrací všechny soubory"""
file_manager.append(temp_dir)
filtered = file_manager.filter_files_by_tags(None)
assert len(filtered) == len(file_manager.filelist)
def test_filter_by_single_tag(self, file_manager, temp_dir):
"""Test filtrace podle jednoho tagu"""
file_manager.append(temp_dir)
def test_filter_by_single_tag(self, loaded):
tag = Tag("Video", "HD")
files_to_tag = file_manager.filelist[:2]
file_manager.assign_tag_to_file_objects(files_to_tag, tag)
loaded.assign_tag_to_file_objects(loaded.filelist[:2], tag)
filtered = file_manager.filter_files_by_tags([tag])
filtered = loaded.filter_files_by_tags([tag])
assert len(filtered) == 2
for f in filtered:
assert tag in f.tags
def test_filter_by_multiple_tags_and_logic(self, file_manager, temp_dir):
"""Test filtrace podle více tagů (AND logika)"""
file_manager.append(temp_dir)
def test_filter_by_multiple_tags_and_logic(self, loaded):
tag1 = Tag("Video", "HD")
tag2 = Tag("Audio", "Stereo")
loaded.assign_tag_to_file_objects([loaded.filelist[0]], tag1)
loaded.assign_tag_to_file_objects([loaded.filelist[0]], tag2)
loaded.assign_tag_to_file_objects([loaded.filelist[1]], tag1)
# První soubor má oba tagy
file_manager.assign_tag_to_file_objects([file_manager.filelist[0]], tag1)
file_manager.assign_tag_to_file_objects([file_manager.filelist[0]], tag2)
# Druhý soubor má jen první tag
file_manager.assign_tag_to_file_objects([file_manager.filelist[1]], tag1)
filtered = file_manager.filter_files_by_tags([tag1, tag2])
filtered = loaded.filter_files_by_tags([tag1, tag2])
assert len(filtered) == 1
assert filtered[0] == file_manager.filelist[0]
assert filtered[0] == loaded.filelist[0]
def test_filter_by_tag_strings(self, file_manager, temp_dir):
"""Test filtrace podle tagů jako stringy"""
file_manager.append(temp_dir)
file_manager.assign_tag_to_file_objects([file_manager.filelist[0]], "Video/HD")
def test_filter_by_tag_strings(self, loaded):
loaded.assign_tag_to_file_objects([loaded.filelist[0]], "Video/HD")
assert len(loaded.filter_files_by_tags(["Video/HD"])) == 1
filtered = file_manager.filter_files_by_tags(["Video/HD"])
assert len(filtered) == 1
def test_filter_no_match(self, file_manager, temp_dir):
"""Test filtrace když nic neodpovídá"""
file_manager.append(temp_dir)
filtered = file_manager.filter_files_by_tags([Tag("NonExistent", "Tag")])
assert len(filtered) == 0
class TestFileManagerLegacy:
"""Testy pro zpětnou kompatibilitu"""
@pytest.fixture
def tag_manager(self):
return TagManager()
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
return FileManager(tag_manager)
def test_config_property_returns_global(self, file_manager):
"""Test že property config vrací global_config"""
assert file_manager.config is file_manager.global_config
def test_config_property_modifiable(self, file_manager):
"""Test že změny přes config property se projeví"""
file_manager.config["test_key"] = "test_value"
assert file_manager.global_config["test_key"] == "test_value"
def test_filter_no_match(self, loaded):
assert len(loaded.filter_files_by_tags([Tag("NonExistent", "Tag")])) == 0
class TestFileManagerEdgeCases:
"""Testy pro edge cases"""
@pytest.fixture
def tag_manager(self):
return TagManager()
@pytest.fixture
def temp_global_config(self, tmp_path, monkeypatch):
config_path = tmp_path / "test_config.json"
import src.core.config as config_module
monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path)
return config_path
@pytest.fixture
def file_manager(self, tag_manager, temp_global_config):
return FileManager(tag_manager)
def test_empty_filelist_operations(self, file_manager):
"""Test operací s prázdným filelistem"""
filtered = file_manager.filter_files_by_tags([Tag("Video", "HD")])
assert filtered == []
# Přiřazení tagů na prázdný seznam
assert file_manager.filter_files_by_tags([Tag("Video", "HD")]) == []
file_manager.assign_tag_to_file_objects([], Tag("Video", "HD"))
assert len(file_manager.filelist) == 0
def test_assign_tag_to_empty_list(self, file_manager):
"""Test přiřazení tagu prázdnému seznamu souborů"""
file_manager.assign_tag_to_file_objects([], Tag("Test", "Tag"))
# Nemělo by vyhodit výjimku
file_manager.assign_tag_to_file_objects([], Tag("Test", "Tag")) # no exception
def test_remove_nonexistent_tag(self, file_manager, tmp_path):
"""Test odstranění neexistujícího tagu"""
(tmp_path / "file.txt").write_text("content")
file_manager.append(tmp_path)
# Nemělo by vyhodit výjimku
file_manager.remove_tag_from_file_objects(file_manager.filelist, Tag("NonExistent", "Tag"))
def test_multiple_folders(self, file_manager, tmp_path):
"""Test práce s více složkami"""
folder1 = tmp_path / "folder1"
folder2 = tmp_path / "folder2"
folder1.mkdir()
folder2.mkdir()
(folder1 / "file1.txt").write_text("content1")
(folder2 / "file2.txt").write_text("content2")
file_manager.append(folder1)
file_manager.append(folder2)
assert len(file_manager.folders) == 2
filenames = {f.filename for f in file_manager.filelist}
assert "file1.txt" in filenames
assert "file2.txt" in filenames
def test_folder_with_special_characters(self, file_manager, tmp_path):
"""Test složky se speciálními znaky v názvu"""
special_folder = tmp_path / "složka s českou diakritikou"
special_folder.mkdir()
(special_folder / "soubor.txt").write_text("obsah")
file_manager.append(special_folder)
filenames = {f.filename for f in file_manager.filelist}
assert "soubor.txt" in filenames
def test_file_with_special_characters(self, file_manager, tmp_path):
"""Test souboru se speciálními znaky v názvu"""
(tmp_path / "soubor s mezerami.txt").write_text("content")
(tmp_path / "čeština.txt").write_text("obsah")
file_manager.append(tmp_path)
filenames = {f.filename for f in file_manager.filelist}
assert "soubor s mezerami.txt" in filenames
assert "čeština.txt" in filenames
def test_remove_nonexistent_tag(self, file_manager, tmp_path, tag_manager):
file_manager.filelist = _in_memory_files(tmp_path, tag_manager, "file.txt")
file_manager.remove_tag_from_file_objects(
file_manager.filelist, Tag("NonExistent", "Tag")) # no exception
class TestPoolManagement:
@@ -669,7 +288,8 @@ class TestPoolManagement:
assert movie.file_path.exists()
assert not source.exists() # moved, not copied
def test_filmoteka_category_roots_from_schema(self, file_manager):
def test_filmoteka_category_roots_from_schema(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_tag_schema([
{"category": "Žánr", "csfd_field": "genres", "transform": None, "filmoteka_root": ""},
{"category": "Rok", "csfd_field": "year", "transform": None, "filmoteka_root": "Dle roku"},
@@ -802,8 +422,33 @@ class TestPoolManagement:
assert len(reloaded.filelist) == 1
assert reloaded.filelist[0].title == "Matrix"
def test_copyasis_folders_default_and_set(self, file_manager):
def test_copyasis_folders_default_and_set(self, file_manager, tmp_path):
assert file_manager.copyasis_folders == ["Seriály"]
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_copyasis_folders(["Seriály", " Dokumenty ", ""])
assert file_manager.copyasis_folders == ["Seriály", "Dokumenty"]
def test_library_settings_stored_in_index_not_global(self, file_manager, tmp_path):
"""tag_schema / copyasis_folders persist in the pool index, not .!gtag."""
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_copyasis_folders(["Seriály", "Dokumenty"])
assert "copyasis_folders" not in file_manager.global_config
assert file_manager.index.get_setting("copyasis_folders") == ["Seriály", "Dokumenty"]
# a fresh manager over the same pool reads the stored settings back
reloaded = FileManager(TagManager())
reloaded.set_pool_dir(tmp_path / "pool")
assert reloaded.copyasis_folders == ["Seriály", "Dokumenty"]
def test_migrates_legacy_global_settings_into_index(self, file_manager, tmp_path):
"""Old settings left in the global config move into the index on open."""
file_manager.set_pool_dir(tmp_path / "pool")
# simulate a pre-migration global config carrying library settings
file_manager.global_config["copyasis_folders"] = ["Seriály", "Filmy jinak"]
file_manager.index = None # force a fresh open + migration
assert file_manager.copyasis_folders == ["Seriály", "Filmy jinak"]
assert "copyasis_folders" not in file_manager.global_config
assert file_manager.index.get_setting("copyasis_folders") == ["Seriály", "Filmy jinak"]
+1 -1
View File
@@ -61,7 +61,7 @@ class TestFileWithIndex:
f = File(movie, TagManager(), index=index)
assert not f.metadata_filename.exists() # no sidecar
assert not (movie.parent / ".Matrix.mkv.!tag").exists() # no sidecar
assert index.get(movie) is not None # record created in index
assert f.tags == [] # no automatic tags