import unittest from arr_mcp.mcp import mcp_sonarr class FakeSonarrClient: def __init__(self, *, rejected: bool = False) -> None: self.posted = [] self.release = { "guid": "exact-guid", "title": "Murder.She.Wrote.S07.German.AC3D.DL.1080p.WebHD.x265-FuN", "indexer": "Test Indexer", "indexerId": 7, "size": 27_600_000_000, "protocol": "usenet", "downloadAllowed": not rejected, "releaseGroup": "FuN", "seasonNumber": 7, "fullSeason": True, "rejections": ["Existing file has equal or better quality"] if rejected else [], } def get_release(self, **_kwargs): return [dict(self.release)] def get_episode(self, **_kwargs): return [ {"id": 1, "seasonNumber": 7, "episodeNumber": 1, "hasFile": True}, {"id": 2, "seasonNumber": 7, "episodeNumber": 2, "hasFile": False}, ] def post_release(self, data): self.posted.append(data) return data class ReleaseGrabTests(unittest.IsolatedAsyncioTestCase): def setUp(self) -> None: mcp_sonarr._APPROVALS.clear() async def test_exact_release_requires_preview_and_ticket(self) -> None: client = FakeSonarrClient() scope = {"series_id": 42, "season_number": 7, "guid": "exact-guid"} preview = await mcp_sonarr._preview_release_grab(client, scope) self.assertFalse(preview["download_started"]) self.assertEqual(preview["existing_episode_files_in_season"], 1) self.assertTrue(preview["approval_ticket"]) result = await mcp_sonarr._grab_release( client, {**scope, "confirm": True, "approval_ticket": preview["approval_ticket"]}, ) self.assertTrue(result["download_started"]) self.assertFalse(result["replacement_guaranteed"]) self.assertEqual(len(client.posted), 1) self.assertEqual(client.posted[0]["guid"], "exact-guid") async def test_rejected_release_needs_force_in_preview(self) -> None: client = FakeSonarrClient(rejected=True) scope = {"series_id": 42, "season_number": 7, "guid": "exact-guid"} blocked = await mcp_sonarr._preview_release_grab(client, scope) self.assertTrue(blocked["force_required"]) self.assertIsNone(blocked["approval_ticket"]) approved = await mcp_sonarr._preview_release_grab(client, {**scope, "force": True}) self.assertFalse(approved["force_required"]) self.assertTrue(approved["approval_ticket"]) async def test_guid_must_still_match_current_sonarr_results(self) -> None: client = FakeSonarrClient() with self.assertRaisesRegex(ValueError, "no longer present"): await mcp_sonarr._preview_release_grab( client, {"series_id": 42, "season_number": 7, "guid": "different-guid"}, ) if __name__ == "__main__": unittest.main()