Add approved Sonarr release grabs
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user