Add exact media replacement from issues
Magent CI/CD / verify (push) Canceled after 6m9s
Magent CI/CD / deploy-prod (push) Canceled after 0s
Magent CI/CD / deploy-beta (push) Canceled after 0s

This commit is contained in:
2026-08-31 22:05:11 +12:00
parent f8770cb44a
commit ec8145a58a
7 changed files with 979 additions and 34 deletions
+91
View File
@@ -1166,6 +1166,97 @@ class AuthFlowTests(TempDatabaseMixin, unittest.IsolatedAsyncioTestCase):
)
class MediaReplacementTests(unittest.IsolatedAsyncioTestCase):
async def test_movie_replacement_validates_file_then_deletes_and_searches(self) -> None:
snapshot = Snapshot(
request_id="3914",
title="Replacement Movie",
request_type=RequestType.movie,
state=NormalizedState.available,
raw={
"arr": {
"item": {
"id": 44,
"movieFile": {
"id": 77,
"relativePath": "Replacement.Movie.1080p.mkv",
},
}
}
},
)
radarr = SimpleNamespace(
configured=lambda: True,
delete_movie_file=AsyncMock(return_value=None),
search=AsyncMock(return_value={"id": 1}),
)
runtime = SimpleNamespace(
jellyseerr_base_url="http://seerr",
jellyseerr_api_key="secret",
radarr_base_url="http://radarr",
radarr_api_key="secret",
)
with (
patch.object(requests_router, "get_runtime_settings", return_value=runtime),
patch.object(requests_router, "build_snapshot", new=AsyncMock(return_value=snapshot)),
patch.object(requests_router, "RadarrClient", return_value=radarr),
patch.object(requests_router, "save_action"),
):
result = await requests_router.action_replace_media(
"3914",
{"file_id": 77, "confirmed": True},
{"username": "admin", "role": "admin", "auto_search_enabled": True},
)
self.assertEqual(result["status"], "ok")
radarr.delete_movie_file.assert_awaited_once_with(77)
radarr.search.assert_awaited_once_with(44)
async def test_tv_replacement_options_return_only_safe_file_details(self) -> None:
snapshot = Snapshot(
request_id="3909",
title="Replacement Series",
request_type=RequestType.tv,
state=NormalizedState.available,
raw={"arr": {"item": {"id": 22}}},
)
sonarr = SimpleNamespace(
configured=lambda: True,
get_episode_files=AsyncMock(return_value=[{
"id": 88,
"seasonNumber": 2,
"path": "/private/library/Replacement.Series.S02E03.mkv",
"size": 1024,
"quality": {"quality": {"name": "WEBDL-1080p"}},
}]),
get_episodes=AsyncMock(return_value=[{
"id": 101,
"episodeFileId": 88,
"seasonNumber": 2,
"episodeNumber": 3,
}]),
)
runtime = SimpleNamespace(
jellyseerr_base_url="http://seerr",
jellyseerr_api_key="secret",
sonarr_base_url="http://sonarr",
sonarr_api_key="secret",
)
with (
patch.object(requests_router, "get_runtime_settings", return_value=runtime),
patch.object(requests_router, "build_snapshot", new=AsyncMock(return_value=snapshot)),
patch.object(requests_router, "SonarrClient", return_value=sonarr),
):
result = await requests_router.replacement_options(
"3909",
{"username": "viewer", "role": "user", "auto_search_enabled": True},
)
self.assertEqual(result["files"][0]["name"], "Replacement.Series.S02E03.mkv")
self.assertEqual(result["files"][0]["episodes"], ["S02E03"])
self.assertNotIn("/private/library", str(result))
class PortalMediaStatusTests(unittest.IsolatedAsyncioTestCase):
def setUp(self) -> None:
portal_router._MEDIA_STATUS_CACHE.update(expires_at=0.0, payload=None)