import pytest import json from pathlib import Path 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 ) class TestGlobalConfig: """Testy pro globální config""" @pytest.fixture def temp_global_config(self, tmp_path, monkeypatch): """Fixture pro dočasný globální config soubor""" config_path = tmp_path / "config.json" import src.core.config as config_module monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path) return config_path def test_default_global_config_structure(self): """Test struktury defaultní globální konfigurace""" 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 DEFAULT_GLOBAL_CONFIG["window_geometry"] == "1200x800" assert DEFAULT_GLOBAL_CONFIG["window_maximized"] is False assert DEFAULT_GLOBAL_CONFIG["last_folder"] is None def test_load_global_config_nonexistent_file(self, temp_global_config): """Test načtení globální konfigurace když soubor neexistuje""" config = load_global_config() assert config == DEFAULT_GLOBAL_CONFIG def test_save_global_config(self, temp_global_config): """Test uložení globální konfigurace""" test_config = { "window_geometry": "800x600", "window_maximized": True, "last_folder": "/home/user/documents", "sidebar_width": 300, "recent_folders": ["/path1", "/path2"], } save_global_config(test_config) assert temp_global_config.exists() with open(temp_global_config, "r", encoding="utf-8") as f: saved_data = json.load(f) assert saved_data == test_config def test_load_global_config_existing_file(self, temp_global_config): """Test načtení existující globální konfigurace""" test_config = { "window_geometry": "1920x1080", "window_maximized": False, "last_folder": "/test/path", "sidebar_width": 250, "recent_folders": [], } save_global_config(test_config) loaded_config = load_global_config() assert loaded_config == test_config def test_load_global_config_merges_defaults(self, temp_global_config): """Test že chybějící klíče jsou doplněny z defaultů""" partial_config = {"window_geometry": "800x600"} with open(temp_global_config, "w", encoding="utf-8") as f: json.dump(partial_config, f) loaded = load_global_config() assert loaded["window_geometry"] == "800x600" assert loaded["window_maximized"] == DEFAULT_GLOBAL_CONFIG["window_maximized"] assert loaded["sidebar_width"] == DEFAULT_GLOBAL_CONFIG["sidebar_width"] def test_global_config_corrupted_file(self, temp_global_config): """Test načtení poškozeného global config souboru""" with open(temp_global_config, "w") as f: f.write("{ invalid json }") config = load_global_config() assert config == DEFAULT_GLOBAL_CONFIG def test_global_config_utf8_encoding(self, temp_global_config): """Test UTF-8 encoding s českými znaky""" test_config = { **DEFAULT_GLOBAL_CONFIG, "last_folder": "/cesta/s/českými/znaky", "recent_folders": ["/složka/čeština"], } save_global_config(test_config) loaded_config = load_global_config() assert loaded_config["last_folder"] == "/cesta/s/českými/znaky" assert loaded_config["recent_folders"] == ["/složka/čeština"] def test_global_config_returns_new_dict(self, temp_global_config): """Test že load_global_config vrací nový dictionary""" config1 = load_global_config() config2 = load_global_config() assert config1 is not config2 assert config1 == config2 def test_global_config_recent_folders(self, temp_global_config): """Test ukládání recent_folders""" folders = ["/path/one", "/path/two", "/path/three"] test_config = {**DEFAULT_GLOBAL_CONFIG, "recent_folders": folders} save_global_config(test_config) loaded = load_global_config() assert loaded["recent_folders"] == folders 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 == ".tagger.json" 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""" @pytest.fixture def temp_global_config(self, tmp_path, monkeypatch): """Fixture pro dočasný globální config soubor""" config_path = tmp_path / "config.json" import src.core.config as config_module monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path) return config_path def test_load_config_legacy(self, temp_global_config): """Test že load_config funguje jako alias pro load_global_config""" test_config = {**DEFAULT_GLOBAL_CONFIG, "last_folder": "/test"} save_global_config(test_config) loaded = load_config() assert loaded["last_folder"] == "/test" def test_save_config_legacy(self, temp_global_config): """Test že save_config funguje jako alias pro save_global_config""" test_config = {**DEFAULT_GLOBAL_CONFIG, "last_folder": "/legacy"} save_config(test_config) loaded = load_global_config() assert loaded["last_folder"] == "/legacy" class TestConfigEdgeCases: """Testy pro edge cases""" @pytest.fixture def temp_global_config(self, tmp_path, monkeypatch): """Fixture pro dočasný globální config soubor""" config_path = tmp_path / "config.json" import src.core.config as config_module monkeypatch.setattr(config_module, 'GLOBAL_CONFIG_FILE', config_path) return config_path def test_config_path_with_spaces(self, temp_global_config): """Test s cestou obsahující mezery""" test_config = { **DEFAULT_GLOBAL_CONFIG, "last_folder": "/path/with spaces/in name" } save_global_config(test_config) loaded = load_global_config() assert loaded["last_folder"] == "/path/with spaces/in name" def test_config_long_path(self, temp_global_config): """Test s dlouhou cestou""" long_path = "/very/long/path/" + "subdir/" * 50 + "final" test_config = {**DEFAULT_GLOBAL_CONFIG, "last_folder": long_path} save_global_config(test_config) loaded = load_global_config() assert loaded["last_folder"] == long_path def test_config_many_recent_folders(self, temp_global_config): """Test s velkým počtem recent folders""" folders = [f"/path/folder{i}" for i in range(100)] test_config = {**DEFAULT_GLOBAL_CONFIG, "recent_folders": folders} save_global_config(test_config) loaded = load_global_config() 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} save_global_config(test_config) with open(temp_global_config, "r", encoding="utf-8") as f: content = f.read() # Mělo by být naformátováno s indentací assert " " in content def test_config_ensure_ascii_false(self, temp_global_config): """Test že ensure_ascii=False funguje správně""" test_config = { **DEFAULT_GLOBAL_CONFIG, "last_folder": "/cesta/čeština" } save_global_config(test_config) with open(temp_global_config, "r", encoding="utf-8") as f: content = f.read() assert "čeština" in content assert "\\u" not in content # Nemělo by být escapováno def test_config_overwrite(self, temp_global_config): """Test přepsání existující konfigurace""" config1 = {**DEFAULT_GLOBAL_CONFIG, "last_folder": "/path1"} config2 = {**DEFAULT_GLOBAL_CONFIG, "last_folder": "/path2"} save_global_config(config1) save_global_config(config2) 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