Files
SyncVito/tests/test_config_store.py
2026-09-29 04:53:04 +02:00

95 lines
3.1 KiB
Python

from pathlib import Path
from unittest.mock import patch
import pytest
from syncvito.config_store import ConfigError, ConfigStore
from syncvito.models import AppConfig, AppSettings, SyncDirection, SyncTask
def test_config_roundtrip(tmp_path: Path) -> None:
path = tmp_path / "config.json"
config = AppConfig(
tasks=[
SyncTask(
name="Archiv",
source=str(tmp_path / "quelle"),
target=str(tmp_path / "ziel"),
direction=SyncDirection.BIDIRECTIONAL,
selected_paths=["Dokumente"],
)
],
settings=AppSettings(font_size=12, ui_scale=110, check_updates_on_start=False),
)
ConfigStore(path).save(config)
loaded = ConfigStore(path).load()
assert loaded.settings.font_size == 12
assert loaded.settings.ui_scale == 110
assert loaded.settings.check_updates_on_start is False
assert loaded.tasks[0].name == "Archiv"
assert loaded.tasks[0].direction is SyncDirection.BIDIRECTIONAL
assert loaded.tasks[0].selected_paths == ["Dokumente"]
def test_config_corrupt_json_creates_backup(tmp_path: Path) -> None:
path = tmp_path / "config.json"
path.write_text("{ unvollstaendiges json...", encoding="utf-8")
store = ConfigStore(path)
with pytest.raises(ConfigError, match="syntaktisch beschädigt"):
store.load()
defekt_files = list(tmp_path.glob("config.defekt-*.json"))
assert len(defekt_files) == 1
assert not path.exists()
def test_config_read_locked_does_not_rename_file(tmp_path: Path) -> None:
path = tmp_path / "config.json"
path.write_text('{"schema_version": 1, "tasks": [], "settings": {}}', encoding="utf-8")
store = ConfigStore(path)
with (
patch.object(Path, "read_text", side_effect=PermissionError(13, "Permission denied")),
pytest.raises(ConfigError, match="konnte nicht gelesen werden"),
):
store.load()
# Originaldatei darf bei Lese-/Sperrfehler NICHT umbenannt/gelöscht werden!
assert path.exists()
assert list(tmp_path.glob("config.defekt-*.json")) == []
def test_config_load_with_invalid_task_keeps_task_disabled() -> None:
data = {
"schema_version": 1,
"tasks": [
{
"name": "Ungültig",
"source": "C:\\Ordner",
"target": "C:\\Ordner", # Gleiche Quelle und Ziel -> ValueError bei validate()
"interval_minutes": 30,
}
],
"settings": {},
}
config = AppConfig.from_dict(data)
assert len(config.tasks) == 1
assert config.tasks[0].name == "Ungültig"
assert config.tasks[0].enabled is False
def test_sync_task_safe_resolve_network_oserror(tmp_path: Path) -> None:
task = SyncTask(
name="Netzwerk-Task",
source=str(tmp_path / "lokal"),
target=r"\\UnerreichbarerServer\Freigabe\Ordner",
)
with patch.object(Path, "resolve", side_effect=OSError("Network unreachable")):
task.validate()
assert task.source == str((tmp_path / "lokal").resolve())
assert r"\\UnerreichbarerServer\Freigabe\Ordner" in task.target