From 16876e1cf0b4083fba7c2cb975938507621fd386 Mon Sep 17 00:00:00 2001 From: Zak Bearman Date: Tue, 1 Sep 2026 14:48:08 +1200 Subject: [PATCH] Advance issue status from repair actions --- backend/app/routers/requests.py | 13 +++++++++++++ backend/tests/test_backend_quality.py | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/backend/app/routers/requests.py b/backend/app/routers/requests.py index 6cb3542..764ced8 100644 --- a/backend/app/routers/requests.py +++ b/backend/app/routers/requests.py @@ -44,6 +44,7 @@ from ..db import ( get_artwork_cache_status_count, get_setting, set_setting, + update_portal_item, update_artwork_cache_stats, cleanup_history, is_seerr_media_failure_suppressed, @@ -1830,6 +1831,18 @@ def _record_replacement_activity( ) -> None: if not issue: return + current_status = str(issue.get("status") or "new").strip().lower() + next_status: Optional[str] = None + if event_type.endswith("_started"): + next_status = "in_progress" + elif event_type.endswith("_failed"): + next_status = "blocked" + if next_status and current_status not in {"done", "closed"}: + update_portal_item( + int(issue["id"]), + status=next_status, + issue_resolved_at=None, + ) add_portal_item_activity( int(issue["id"]), event_type=event_type, diff --git a/backend/tests/test_backend_quality.py b/backend/tests/test_backend_quality.py index 5408a31..493e5d5 100644 --- a/backend/tests/test_backend_quality.py +++ b/backend/tests/test_backend_quality.py @@ -1271,6 +1271,21 @@ class AuthFlowTests(TempDatabaseMixin, unittest.IsolatedAsyncioTestCase): class MediaReplacementTests(unittest.IsolatedAsyncioTestCase): + def test_failed_repair_marks_linked_issue_as_blocked(self) -> None: + issue = {"id": 12, "status": "in_progress"} + with ( + patch.object(requests_router, "update_portal_item") as update_issue, + patch.object(requests_router, "add_portal_item_activity"), + ): + requests_router._record_replacement_activity( + issue, + user={"username": "viewer", "role": "user"}, + event_type="replacement_failed", + message="Radarr could not start the replacement.", + ) + + update_issue.assert_called_once_with(12, status="blocked", issue_resolved_at=None) + async def test_movie_replacement_validates_file_then_deletes_and_searches(self) -> None: snapshot = Snapshot( request_id="3914", @@ -1315,6 +1330,7 @@ class MediaReplacementTests(unittest.IsolatedAsyncioTestCase): "created_by_username": "admin", }, ), + patch.object(requests_router, "update_portal_item") as update_issue, patch.object(requests_router, "add_portal_item_activity") as add_activity, ): result = await requests_router.action_replace_media( @@ -1328,6 +1344,7 @@ class MediaReplacementTests(unittest.IsolatedAsyncioTestCase): radarr.search.assert_awaited_once_with(44) add_activity.assert_called_once() self.assertEqual(add_activity.call_args.kwargs["event_type"], "replacement_started") + update_issue.assert_called_once_with(12, status="in_progress", issue_resolved_at=None) async def test_tv_replacement_options_return_only_safe_file_details(self) -> None: snapshot = Snapshot( @@ -1470,6 +1487,7 @@ class MediaReplacementTests(unittest.IsolatedAsyncioTestCase): "external_ref": "/requests/3909", "created_by_username": "viewer", }), + patch.object(requests_router, "update_portal_item"), patch.object(requests_router, "add_portal_item_activity"), ): result = await requests_router.action_replace_media( @@ -1510,6 +1528,7 @@ class MediaReplacementTests(unittest.IsolatedAsyncioTestCase): "external_ref": "/requests/3914", "created_by_username": "viewer", }), + patch.object(requests_router, "update_portal_item") as update_issue, patch.object(requests_router, "add_portal_item_activity") as add_activity, ): result = await requests_router.action_repair_subtitles( @@ -1521,6 +1540,7 @@ class MediaReplacementTests(unittest.IsolatedAsyncioTestCase): self.assertEqual(result["status"], "ok") bazarr.search_movie_subtitles.assert_awaited_once_with(44, language="en", forced=True) self.assertEqual(add_activity.call_args.kwargs["event_type"], "subtitle_repair_started") + update_issue.assert_called_once_with(12, status="in_progress", issue_resolved_at=None) class PortalMediaStatusTests(unittest.IsolatedAsyncioTestCase):