Fix partial series completion for watchlist and Jellyfin

This commit is contained in:
Dymas
2026-05-25 23:09:14 +02:00
parent c006fb2d1d
commit 94ded2725e
6 changed files with 123 additions and 20 deletions
+71 -11
View File
@@ -1090,19 +1090,48 @@ class WatchlistCompletionTests(unittest.TestCase):
self.assertEqual(item["status"], "queued")
self.assertEqual(item["status_message"], "Queued from test.")
def test_mark_downloaded_moves_existing_category_to_finished_and_sets_download_flag(self):
self.seed_watchlist_item(show_id="show-9", title="Queue Show", category="planned", downloaded=False)
def test_mark_downloaded_keeps_existing_category_when_selected_mode_is_incomplete(self):
self.seed_watchlist_item(
show_id="show-9",
title="Queue Show",
category="planned",
downloaded=False,
expected_count=12,
airing_status="Finished",
dub_count=8,
)
with mock.patch.object(APP.WATCHLIST, "schedule_refresh", side_effect=lambda show_id, source="manual": APP.WATCHLIST.get(show_id)), mock.patch.object(
APP.WATCHLIST, "refresh", side_effect=AssertionError("mark_downloaded should not refresh synchronously")
), mock.patch.object(APP, "episode_list", return_value=["1", "2", "3", "4", "5", "6", "7", "8"]):
item = APP.WATCHLIST.mark_downloaded("show-9", title="Queue Show", mode="dub", episodes="2-3")
self.assertEqual(item["category"], "planned")
self.assertTrue(item["downloaded"])
self.assertEqual(item["finished_badge"], "")
self.assertEqual(item["status"], "queued")
self.assertEqual(item["downloaded_dub_episodes"], ["2", "3"])
def test_mark_downloaded_moves_existing_category_to_finished_when_selected_mode_is_complete(self):
self.seed_watchlist_item(
show_id="show-9c",
title="Queue Show Complete",
category="watching",
downloaded=False,
expected_count=3,
airing_status="Finished",
dub_count=3,
)
with mock.patch.object(APP.WATCHLIST, "schedule_refresh", side_effect=lambda show_id, source="manual": APP.WATCHLIST.get(show_id)), mock.patch.object(
APP.WATCHLIST, "refresh", side_effect=AssertionError("mark_downloaded should not refresh synchronously")
), mock.patch.object(APP, "episode_list", return_value=["1", "2", "3"]):
item = APP.WATCHLIST.mark_downloaded("show-9", title="Queue Show", mode="dub", episodes="2-3")
item = APP.WATCHLIST.mark_downloaded("show-9c", title="Queue Show Complete", mode="dub", episodes="1-3")
self.assertEqual(item["category"], "finished")
self.assertTrue(item["downloaded"])
self.assertEqual(item["finished_badge"], "downloaded")
self.assertEqual(item["status"], "queued")
self.assertEqual(item["downloaded_dub_episodes"], ["2", "3"])
self.assertEqual(item["downloaded_dub_episodes"], ["1", "2", "3"])
def test_mark_downloaded_creates_missing_show_in_finished_category(self):
with mock.patch.object(APP.WATCHLIST, "schedule_refresh", side_effect=lambda show_id, source="manual": APP.WATCHLIST.get(show_id)), mock.patch.object(
@@ -1116,12 +1145,20 @@ class WatchlistCompletionTests(unittest.TestCase):
self.assertEqual(item["status"], "queued")
def test_mark_downloaded_reconciles_unique_title_match_to_new_show_id(self):
self.seed_watchlist_item(show_id="legacy-show-9", title="Queue Show", category="watching", downloaded=False)
self.seed_watchlist_item(
show_id="legacy-show-9",
title="Queue Show",
category="watching",
downloaded=False,
expected_count=3,
airing_status="Finished",
sub_count=3,
)
with mock.patch.object(APP.WATCHLIST, "schedule_refresh", side_effect=lambda show_id, source="manual": APP.WATCHLIST.get(show_id)), mock.patch.object(
APP.WATCHLIST, "refresh", side_effect=AssertionError("mark_downloaded should not refresh synchronously")
):
item = APP.WATCHLIST.mark_downloaded("resolved-show-9", title="Queue Show")
), mock.patch.object(APP, "episode_list", return_value=["1", "2", "3"]):
item = APP.WATCHLIST.mark_downloaded("resolved-show-9", title="Queue Show", mode="sub", episodes="1-3")
self.assertEqual(item["show_id"], "resolved-show-9")
self.assertEqual(item["category"], "finished")
@@ -1287,10 +1324,11 @@ class JellyfinSyncTests(unittest.TestCase):
"anidb_aid": None,
"anidb_title": None,
"media_type": "tv",
"auto_download_mode": "dub",
"auto_download_name": "Jelly Show",
"auto_download_series": "1",
"downloaded_sub_episodes_json": APP.encode_episode_values([str(index) for index in range(1, 13)]),
"downloaded_dub_episodes_json": None,
"downloaded_sub_episodes_json": None,
"downloaded_dub_episodes_json": APP.encode_episode_values([str(index) for index in range(1, 13)]),
"thumbnail_path": None,
"thumbnail_checked_at": None,
}
@@ -1398,7 +1436,29 @@ class JellyfinSyncTests(unittest.TestCase):
send_webhook.assert_not_called()
def test_trigger_jellyfin_sync_for_item_skips_incomplete_series(self):
self.seed_watchlist_item(expected_count=24, downloaded_sub_episodes_json=APP.encode_episode_values([str(index) for index in range(1, 13)]))
self.seed_watchlist_item(
expected_count=12,
dub_count=8,
dub_latest_episode="8",
downloaded_dub_episodes_json=APP.encode_episode_values([str(index) for index in range(1, 9)]),
)
item = APP.WATCHLIST.get("show-jelly-1")
result = APP.trigger_jellyfin_sync_for_item(
item,
automatic=False,
config={"download_dir": "/tmp/example", "jellyfin_tv_dir": "/tmp/jellyfin-tv", "jellyfin_movie_dir": ""},
)
self.assertFalse(result["moved"])
self.assertEqual(result["reason"], "episodes_unavailable")
def test_trigger_jellyfin_sync_for_item_skips_when_dub_not_fully_downloaded(self):
self.seed_watchlist_item(
expected_count=12,
dub_count=12,
downloaded_dub_episodes_json=APP.encode_episode_values([str(index) for index in range(1, 9)]),
)
item = APP.WATCHLIST.get("show-jelly-1")
result = APP.trigger_jellyfin_sync_for_item(