Files
AI-Profile-Router/dev/test_sonarr_release_grab.py
T

151 lines
5.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""Focused offline tests for the model-oriented Sonarr overlay."""
from __future__ import annotations
import importlib.util
import sys
import types
import unittest
from pathlib import Path
SOURCE = Path(__file__).parents[1] / "platform/mcp/patches/mcp_sonarr.py"
def load_module():
async def run_blocking(function, *args, **kwargs):
kwargs.pop("service", None)
return function(*args, **kwargs)
def dispatch(client, action, kwargs, **_options):
return getattr(client, action)(**kwargs)
utilities = types.ModuleType("agent_utilities.mcp_utilities")
utilities.dispatch = dispatch
utilities.run_blocking = run_blocking
sys.modules["agent_utilities"] = types.ModuleType("agent_utilities")
sys.modules["agent_utilities.mcp_utilities"] = utilities
fastmcp = types.ModuleType("fastmcp")
fastmcp.FastMCP = object
sys.modules["fastmcp"] = fastmcp
pydantic = types.ModuleType("pydantic")
pydantic.Field = lambda *args, **kwargs: kwargs.get("default")
sys.modules["pydantic"] = pydantic
auth = types.ModuleType("arr_mcp.auth")
auth.get_sonarr_client = lambda: None
sys.modules["arr_mcp"] = types.ModuleType("arr_mcp")
sys.modules["arr_mcp.auth"] = auth
spec = importlib.util.spec_from_file_location("sonarr_patch", SOURCE)
module = importlib.util.module_from_spec(spec)
assert spec.loader
spec.loader.exec_module(module)
return module
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=None, **kwargs):
payload = data if data is not None else kwargs
self.posted.append(payload)
return payload
class ReleaseGrabTests(unittest.IsolatedAsyncioTestCase):
def setUp(self) -> None:
self.module = load_module()
self.module._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 self.module._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 self.module._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 self.module._preview_release_grab(client, scope)
self.assertTrue(blocked["force_required"])
self.assertIsNone(blocked["approval_ticket"])
approved = await self.module._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 self.module._preview_release_grab(
client,
{"series_id": 42, "season_number": 7, "guid": "different-guid"},
)
async def test_search_can_limit_results_to_group_and_season_pack(self) -> None:
client = FakeSonarrClient()
client.get_release = lambda **_kwargs: [
dict(client.release),
{
**client.release,
"guid": "episode-guid",
"title": "Mord.ist.ihr.Hobby.S07E02.German.1080p-FuN",
"fullSeason": False,
},
{
**client.release,
"guid": "other-group",
"title": "Mord.ist.ihr.Hobby.S07.German.1080p-HQC",
"releaseGroup": "HQC",
},
]
result = await self.module._search_releases(
client,
{
"series_id": 42,
"season_number": 7,
"release_group": "FuN",
"season_pack_only": True,
},
)
self.assertEqual(result["results"]["total"], 1)
self.assertEqual(result["results"]["items"][0]["guid"], "exact-guid")
if __name__ == "__main__":
unittest.main()