"""Tests for folder persistence and metadata repair (GOG rename handling).""" from pathlib import Path from src.config import MetadataStore from src.models import DownloadedBonus, DownloadedInstaller, GameRecord, InstallerType def _installer(version: str, filename: str) -> DownloadedInstaller: return DownloadedInstaller( filename=filename, size=1, version=version, language="en", installer_type=InstallerType.GAME, downloaded_at="", ) def _make_version(base: Path, folder: str, version: str, *filenames: str) -> None: d = base / folder / version d.mkdir(parents=True, exist_ok=True) for f in filenames: (d / f).write_text("x") def _make_bonus(base: Path, folder: str, *filenames: str) -> None: d = base / folder / "Bonus" d.mkdir(parents=True, exist_ok=True) for f in filenames: (d / f).write_text("x") class TestFolderField: def test_roundtrip_persists_folder(self) -> None: rec = GameRecord(game_id="1", name="Old Name", folder="Pinned Folder") restored = GameRecord.from_dict("1", rec.to_dict()) assert restored.folder == "Pinned Folder" def test_empty_folder_not_written(self) -> None: rec = GameRecord(game_id="1", name="Game") assert "folder" not in rec.to_dict() class TestCandidateLookup: def test_finds_files_across_folders(self, tmp_path: Path) -> None: # Game renamed: v1 under old folder, v2 under new (pinned) folder. _make_version(tmp_path, "New Title", "2.0", "setup.exe") _make_version(tmp_path, "Old Title", "1.0", "setup.exe") store = MetadataStore(str(tmp_path)) rec = GameRecord( game_id="1", name="Old Title", folder="New Title", latest_version="2.0", installers=[_installer("2.0", "setup.exe"), _installer("1.0", "setup.exe")], ) store.games["1"] = rec store.save = lambda: None # type: ignore[method-assign] removed = store.verify_metadata() assert removed == 0 # both installers found despite living in different folders assert rec.latest_version == "2.0" assert len(rec.installers) == 2 class TestRepairFolders: def test_repoints_to_newest_version_folder_and_merges(self, tmp_path: Path) -> None: # Split data: old folder has 1.0 + a bonus, new-title folder has 2.0. _make_version(tmp_path, "Witcher Complete", "1.0", "setup_1.exe") _make_version(tmp_path, "Witcher Remastered", "2.0", "setup_2.exe") _make_bonus(tmp_path, "Witcher Complete", "ost.zip") store = MetadataStore(str(tmp_path)) # Metadata still points at the old folder and (wrongly) a single version. rec = GameRecord( game_id="1", name="Witcher Complete", folder="", latest_version="2.0", installers=[_installer("1.0", "setup_1.exe"), _installer("2.0", "setup_2.exe")], bonuses=[DownloadedBonus(filename="ost.zip", name="OST", bonus_type="audio", size=1, downloaded_at="")], ) store.games["1"] = rec saved: dict[str, bool] = {} store.save = lambda: saved.update(saved=True) # type: ignore[method-assign] changed = store.repair_folders({"1": ["Witcher Remastered"]}) assert changed == 1 assert rec.folder == "Witcher Remastered" # pinned to newest-version folder assert rec.latest_version == "2.0" assert {i.version for i in rec.installers} == {"1.0", "2.0"} # merged from both folders assert len(rec.bonuses) == 1 # bonus in old folder still found assert saved.get("saved") def test_drops_bonus_with_missing_file(self, tmp_path: Path) -> None: _make_version(tmp_path, "Game", "1.0", "setup.exe") store = MetadataStore(str(tmp_path)) rec = GameRecord( game_id="1", name="Game", installers=[_installer("1.0", "setup.exe")], bonuses=[DownloadedBonus(filename="gone.zip", name="X", bonus_type="", size=1, downloaded_at="")], ) store.games["1"] = rec store.save = lambda: None # type: ignore[method-assign] store.repair_folders({"1": ["Game"]}) assert rec.bonuses == [] # file not on disk -> dropped