Store library settings in the pool index and drop legacy sidecars
This commit is contained in:
+113
-468
@@ -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"]
|
||||
|
||||
Reference in New Issue
Block a user