Harden queue matching and retry behavior
This commit is contained in:
+86
-7
@@ -301,6 +301,51 @@ class QueueApiTests(unittest.TestCase):
|
||||
self.assertEqual(handler.json_status, HTTPStatus.OK)
|
||||
self.assertEqual(handler.json_payload["id"], created["id"])
|
||||
|
||||
def test_retry_rejects_done_jobs(self):
|
||||
created = self.queue.add(
|
||||
{
|
||||
"query": "Done Show",
|
||||
"title": "Done Show",
|
||||
"anime_name": "Done Show",
|
||||
"mode": "sub",
|
||||
"quality": "best",
|
||||
"episodes": "1",
|
||||
"download_dir": "/tmp/example",
|
||||
"season": "1",
|
||||
}
|
||||
)
|
||||
with self.queue.lock:
|
||||
job = self.queue._find(created["id"])
|
||||
job["status"] = "done"
|
||||
self.queue._save_job_locked(job)
|
||||
|
||||
with self.assertRaisesRegex(ValueError, "Only failed or canceled jobs can be retried"):
|
||||
self.queue.retry(created["id"])
|
||||
|
||||
def test_retry_allows_canceled_jobs(self):
|
||||
created = self.queue.add(
|
||||
{
|
||||
"query": "Canceled Show",
|
||||
"title": "Canceled Show",
|
||||
"anime_name": "Canceled Show",
|
||||
"mode": "sub",
|
||||
"quality": "best",
|
||||
"episodes": "1",
|
||||
"download_dir": "/tmp/example",
|
||||
"season": "1",
|
||||
}
|
||||
)
|
||||
with self.queue.lock:
|
||||
job = self.queue._find(created["id"])
|
||||
job["status"] = "canceled"
|
||||
job["cancel_requested"] = True
|
||||
self.queue._save_job_locked(job)
|
||||
|
||||
retried = self.queue.retry(created["id"])
|
||||
|
||||
self.assertEqual(retried["status"], "pending")
|
||||
self.assertFalse(retried["cancel_requested"])
|
||||
|
||||
def test_save_job_splits_log_and_extra_payload_columns(self):
|
||||
queue = APP.DownloadQueue(lambda: {"mode": "sub", "quality": "best", "download_dir": "/tmp/example"}, start_worker=False)
|
||||
job = {
|
||||
@@ -1326,6 +1371,19 @@ class WatchlistCompletionTests(unittest.TestCase):
|
||||
|
||||
self.assertNotIn("-S", APP.app_support.command_for_job(job))
|
||||
|
||||
def test_command_for_job_ignores_legacy_result_index(self):
|
||||
command = APP.app_support.command_for_job(
|
||||
{
|
||||
"query": "Queue Show",
|
||||
"quality": "best",
|
||||
"episodes": "1-10",
|
||||
"mode": "dub",
|
||||
"result_index": 2,
|
||||
}
|
||||
)
|
||||
|
||||
self.assertNotIn("-S", command)
|
||||
|
||||
def test_download_watchlist_item_queues_full_episode_range_for_selected_mode(self):
|
||||
item = {
|
||||
"show_id": "show-42",
|
||||
@@ -1337,9 +1395,7 @@ class WatchlistCompletionTests(unittest.TestCase):
|
||||
job = {"id": "job-1", "show_id": "show-42", "episodes": "1-12", "mode": "dub"}
|
||||
with mock.patch.object(APP, "ensure_runtime", return_value={"watchlist": APP.WATCHLIST, "download_queue": mock.Mock(), "config": {"quality": "best", "download_dir": "/tmp/downloads"}}), mock.patch.object(
|
||||
APP.WATCHLIST, "get", return_value=item
|
||||
), mock.patch.object(APP, "search_anime", return_value=[{"id": "show-42", "title": "Queue Show", "query": "Queue Show", "index": 3}]), mock.patch.object(
|
||||
APP, "episode_list", return_value=["1", "2", "12"]
|
||||
):
|
||||
), mock.patch.object(APP, "episode_list", return_value=["1", "2", "12"]):
|
||||
runtime = APP.ensure_runtime()
|
||||
runtime["download_queue"].add.return_value = job
|
||||
result = APP.download_watchlist_item("show-42", "dub")
|
||||
@@ -1362,6 +1418,30 @@ class WatchlistCompletionTests(unittest.TestCase):
|
||||
self.assertEqual(result["job"], job)
|
||||
self.assertIn("Queued Queue Show for dub download.", result["message"])
|
||||
|
||||
def test_download_watchlist_item_does_not_require_search_match(self):
|
||||
item = {
|
||||
"show_id": "show-42",
|
||||
"title": "Queue Show",
|
||||
"auto_download_name": "Queue Show",
|
||||
"auto_download_series": "1",
|
||||
"media_type": "tv",
|
||||
}
|
||||
runtime = {
|
||||
"watchlist": APP.WATCHLIST,
|
||||
"download_queue": mock.Mock(),
|
||||
"config": {"quality": "best", "download_dir": "/tmp/downloads"},
|
||||
}
|
||||
runtime["download_queue"].add.return_value = {"id": "job-1"}
|
||||
|
||||
with mock.patch.object(APP, "ensure_runtime", return_value=runtime), mock.patch.object(
|
||||
APP.WATCHLIST, "get", return_value=item
|
||||
), mock.patch.object(APP, "search_anime", side_effect=AssertionError("search should not be required")), mock.patch.object(
|
||||
APP, "episode_list", return_value=["1", "2"]
|
||||
):
|
||||
result = APP.download_watchlist_item("show-42", "dub")
|
||||
|
||||
self.assertEqual(result["job"]["id"], "job-1")
|
||||
|
||||
|
||||
class JellyfinSyncTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@@ -2048,7 +2128,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
with mock.patch.object(APP, "ensure_runtime", return_value=runtime), mock.patch.object(
|
||||
APP,
|
||||
"search_anime",
|
||||
return_value=[{"id": "show-42", "title": "Queue Show", "query": "Queue Show", "index": 2}],
|
||||
side_effect=AssertionError("search should not be required"),
|
||||
):
|
||||
result = APP.queue_watchlist_auto_download(item, refresh_source="scheduled")
|
||||
|
||||
@@ -2102,7 +2182,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
with mock.patch.object(APP, "ensure_runtime", return_value=runtime), mock.patch.object(
|
||||
APP,
|
||||
"search_anime",
|
||||
return_value=[{"id": "show-99", "title": "Backlog Show", "query": "Backlog Show", "index": 1}],
|
||||
side_effect=AssertionError("search should not be required"),
|
||||
):
|
||||
result = APP.queue_watchlist_auto_download(item, refresh_source="manual")
|
||||
|
||||
@@ -2156,7 +2236,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
with mock.patch.object(APP, "ensure_runtime", return_value=runtime), mock.patch.object(
|
||||
APP,
|
||||
"search_anime",
|
||||
return_value=[{"id": "show-77", "title": "Split Season Show", "query": "Split Season Show", "index": 1}],
|
||||
side_effect=AssertionError("search should not be required"),
|
||||
):
|
||||
result = APP.queue_watchlist_auto_download(item, refresh_source="manual")
|
||||
|
||||
@@ -2177,7 +2257,6 @@ class AutoDownloadQueueTests(unittest.TestCase):
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class StartupBehaviorTests(unittest.TestCase):
|
||||
def test_main_does_not_eagerly_initialize_runtime(self):
|
||||
server = mock.Mock()
|
||||
|
||||
Reference in New Issue
Block a user