Add AniList alternative titles to watchlist

This commit is contained in:
Dymas
2026-05-25 09:10:42 +02:00
parent 643408b19d
commit 64979d5d32
7 changed files with 448 additions and 6 deletions
+64
View File
@@ -621,6 +621,64 @@ class WatchlistRefreshJobTests(unittest.TestCase):
self.assertIn("restart", status["message"].lower())
class WatchlistAniListTests(unittest.TestCase):
def setUp(self):
APP.reset_runtime(wait=True)
APP.initialize_runtime(start_workers=False)
self.watchlist = APP.WATCHLIST
with self.watchlist._connect() as conn:
conn.execute("DELETE FROM watchlist")
def test_watchlist_schema_includes_anilist_columns(self):
with self.watchlist._connect() as conn:
columns = {row["name"] for row in conn.execute("PRAGMA table_info(watchlist)").fetchall()}
self.assertIn("anilist_id", columns)
self.assertIn("anilist_title", columns)
self.assertIn("anilist_site_url", columns)
self.assertIn("alternative_titles_json", columns)
def test_refresh_caches_anilist_alternative_titles(self):
self.watchlist.add({"show_id": "show-1", "title": "Attack on Titan", "category": "watching"})
with mock.patch.object(
APP,
"fetch_show_episode_snapshot",
return_value={"show_id": "show-1", "title": "Attack on Titan", "episodes": {"sub": ["1", "2"], "dub": ["1"]}},
), mock.patch.object(
APP,
"resolve_animeschedule_anime",
return_value={"route": "attack-on-titan", "title": "Attack on Titan", "episodes": 2, "status": "Finished"},
), mock.patch.object(
APP,
"resolve_anilist_media",
return_value={
"id": 16498,
"siteUrl": "https://anilist.co/anime/16498",
"title": {
"romaji": "Shingeki no Kyojin",
"english": "Attack on Titan",
"native": "進撃の巨人",
"userPreferred": "Attack on Titan",
},
"synonyms": ["AoT"],
},
):
item = self.watchlist.refresh("show-1", include_thumbnail=False)
self.assertEqual(item["anilist_id"], 16498)
self.assertEqual(item["anilist_site_url"], "https://anilist.co/anime/16498")
self.assertEqual(
item["alternative_titles"],
[
{"label": "Romaji", "value": "Shingeki no Kyojin"},
{"label": "Native", "value": "進撃の巨人"},
{"label": "Synonym", "value": "AoT"},
],
)
self.assertTrue(item["has_alternative_titles"])
class ThumbnailEventRecoveryTests(unittest.TestCase):
def test_ensure_thumbnails_skips_show_removed_during_batch(self):
store = object.__new__(APP.WatchlistStore)
@@ -1779,6 +1837,12 @@ class TemplateHelperTests(unittest.TestCase):
self.assertIn('downloadWatchlistItem(item, "sub"', APP.WATCHLIST_HTML)
self.assertIn('downloadWatchlistItem(item, "dub"', APP.WATCHLIST_HTML)
def test_watchlist_page_renders_alternative_titles_toggle(self):
self.assertIn("Alternative titles", APP.WATCHLIST_HTML)
self.assertIn('class="ghost alt-titles-toggle"', APP.WATCHLIST_HTML)
self.assertIn('altTitlesPanel.classList.toggle("open")', APP.WATCHLIST_HTML)
self.assertIn("AniList alternative titles were not available for this show.", APP.WATCHLIST_HTML)
def test_watchlist_thumbnail_warmup_skips_repeated_attempts(self):
self.assertIn("thumbnailWarmupPending: new Set()", APP.WATCHLIST_HTML)
self.assertIn("function thumbnailWarmupToken(item)", APP.WATCHLIST_HTML)