"""Tests for user-added games (M6): add/remove/scan of titles no launcher reports (e.g. SPT).""" import tempfile import unittest from pathlib import Path from unittest import mock from rigdoctor.core import customgames class CustomGamesTests(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() self._file = Path(self._tmp.name) / "custom-games.json" self._patch = mock.patch.object(customgames.config, "CUSTOM_GAMES_FILE", self._file) self._patch.start() def tearDown(self): self._patch.stop() self._tmp.cleanup() def test_missing_file_scans_empty(self): self.assertEqual(customgames.scan(), []) self.assertEqual(customgames.names(), []) def test_add_then_scan_returns_game(self): self.assertTrue(customgames.add("SPT")) games = customgames.scan() self.assertEqual(len(games), 1) self.assertEqual(games[0].name, "SPT") self.assertEqual(games[0].launcher, "custom") self.assertTrue(self._file.exists()) # persisted def test_add_is_idempotent_case_insensitive(self): self.assertTrue(customgames.add("SPT")) self.assertFalse(customgames.add("spt")) # already present self.assertFalse(customgames.add(" ")) # blank self.assertEqual(customgames.names(), ["SPT"]) def test_remove(self): customgames.add("SPT") customgames.add("Minecraft") self.assertTrue(customgames.remove("spt")) # case-insensitive self.assertEqual(customgames.names(), ["Minecraft"]) self.assertFalse(customgames.remove("nope")) def test_scan_sorted_by_name(self): for n in ("Zomboid", "Apex", "SPT"): customgames.add(n) self.assertEqual([g.name for g in customgames.scan()], ["Apex", "SPT", "Zomboid"]) def test_command_and_logdir_stored_and_resolved(self): logs = Path(self._tmp.name) / "logs" logs.mkdir() sh = Path(self._tmp.name) / "tarkov.sh" sh.write_text("#!/bin/sh\n") self.assertTrue(customgames.add("SPT", command=str(sh), logdir=str(logs))) self.assertEqual(customgames.command("SPT"), [str(sh)]) self.assertEqual(customgames.log_dir("SPT"), str(logs)) def test_logdir_inferred_from_sibling_logs(self): # A command with a sibling logs/ dir (SPT's layout) → logdir auto-detected. sh = Path(self._tmp.name) / "tarkov.sh" sh.write_text("#!/bin/sh\n") (Path(self._tmp.name) / "logs").mkdir() self.assertTrue(customgames.add("SPT", command=str(sh))) self.assertEqual(customgames.log_dir("SPT"), str(Path(self._tmp.name) / "logs")) def test_no_command_resolves_to_none(self): customgames.add("SPT") self.assertIsNone(customgames.command("SPT")) self.assertIsNone(customgames.command("missing")) self.assertIsNone(customgames.log_dir("SPT")) def test_corrupt_file_degrades_to_empty(self): self._file.parent.mkdir(parents=True, exist_ok=True) self._file.write_text("{not json") self.assertEqual(customgames.scan(), []) # and a subsequent add still works (overwrites the garbage) self.assertTrue(customgames.add("SPT")) self.assertEqual(customgames.names(), ["SPT"]) if __name__ == "__main__": unittest.main()