Add approved Sonarr release grabs

This commit is contained in:
Mikei386
2026-08-23 14:38:42 +02:00
parent 76bfc65978
commit 09634a27f9
3 changed files with 289 additions and 7 deletions
+79
View File
@@ -0,0 +1,79 @@
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()