mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 23:47:41 +08:00
fix: 跳过推荐空缓存
This commit is contained in:
+24
-24
@@ -105,7 +105,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
ImageHelper().fetch_image(url=url)
|
ImageHelper().fetch_image(url=url)
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def tmdb_movies(self, sort_by: Optional[str] = "popularity.desc",
|
def tmdb_movies(self, sort_by: Optional[str] = "popularity.desc",
|
||||||
with_genres: Optional[str] = "",
|
with_genres: Optional[str] = "",
|
||||||
with_original_language: Optional[str] = "",
|
with_original_language: Optional[str] = "",
|
||||||
@@ -131,7 +131,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [movie.to_dict() for movie in movies] if movies else []
|
return [movie.to_dict() for movie in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def tmdb_tvs(self, sort_by: Optional[str] = "popularity.desc",
|
def tmdb_tvs(self, sort_by: Optional[str] = "popularity.desc",
|
||||||
with_genres: Optional[str] = "",
|
with_genres: Optional[str] = "",
|
||||||
with_original_language: Optional[str] = "zh|en|ja|ko",
|
with_original_language: Optional[str] = "zh|en|ja|ko",
|
||||||
@@ -166,7 +166,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [info.to_dict() for info in infos] if infos else []
|
return [info.to_dict() for info in infos] if infos else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def bangumi_calendar(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def bangumi_calendar(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
Bangumi每日放送
|
Bangumi每日放送
|
||||||
@@ -175,7 +175,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in medias[(page - 1) * count: page * count]] if medias else []
|
return [media.to_dict() for media in medias[(page - 1) * count: page * count]] if medias else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_movie_showing(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_movie_showing(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣正在热映
|
豆瓣正在热映
|
||||||
@@ -184,7 +184,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_movies(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
def douban_movies(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
||||||
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
@@ -195,7 +195,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_tvs(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
def douban_tvs(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
||||||
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
@@ -206,7 +206,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_movie_top250(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_movie_top250(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣电影TOP250
|
豆瓣电影TOP250
|
||||||
@@ -215,7 +215,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_tv_weekly_chinese(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_tv_weekly_chinese(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣国产剧集榜
|
豆瓣国产剧集榜
|
||||||
@@ -224,7 +224,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_tv_weekly_global(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_tv_weekly_global(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣全球剧集榜
|
豆瓣全球剧集榜
|
||||||
@@ -233,7 +233,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_tv_animation(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_tv_animation(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣热门动漫
|
豆瓣热门动漫
|
||||||
@@ -242,7 +242,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_movie_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_movie_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣热门电影
|
豆瓣热门电影
|
||||||
@@ -251,7 +251,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
def douban_tv_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
def douban_tv_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
豆瓣热门电视剧
|
豆瓣热门电视剧
|
||||||
@@ -260,7 +260,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_tmdb_movies(self, sort_by: Optional[str] = "popularity.desc",
|
async def async_tmdb_movies(self, sort_by: Optional[str] = "popularity.desc",
|
||||||
with_genres: Optional[str] = "",
|
with_genres: Optional[str] = "",
|
||||||
with_original_language: Optional[str] = "",
|
with_original_language: Optional[str] = "",
|
||||||
@@ -286,7 +286,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [movie.to_dict() for movie in movies] if movies else []
|
return [movie.to_dict() for movie in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_tmdb_tvs(self, sort_by: Optional[str] = "popularity.desc",
|
async def async_tmdb_tvs(self, sort_by: Optional[str] = "popularity.desc",
|
||||||
with_genres: Optional[str] = "",
|
with_genres: Optional[str] = "",
|
||||||
with_original_language: Optional[str] = "zh|en|ja|ko",
|
with_original_language: Optional[str] = "zh|en|ja|ko",
|
||||||
@@ -321,7 +321,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [info.to_dict() for info in infos] if infos else []
|
return [info.to_dict() for info in infos] if infos else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_bangumi_calendar(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_bangumi_calendar(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步Bangumi每日放送
|
异步Bangumi每日放送
|
||||||
@@ -330,7 +330,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in medias[(page - 1) * count: page * count]] if medias else []
|
return [media.to_dict() for media in medias[(page - 1) * count: page * count]] if medias else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_movie_showing(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_movie_showing(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣正在热映
|
异步豆瓣正在热映
|
||||||
@@ -339,7 +339,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_movies(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
async def async_douban_movies(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
||||||
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
@@ -350,7 +350,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_tvs(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
async def async_douban_tvs(self, sort: Optional[str] = "R", tags: Optional[str] = "",
|
||||||
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
@@ -361,7 +361,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_movie_top250(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_movie_top250(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣电影TOP250
|
异步豆瓣电影TOP250
|
||||||
@@ -370,7 +370,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_tv_weekly_chinese(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_tv_weekly_chinese(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣国产剧集榜
|
异步豆瓣国产剧集榜
|
||||||
@@ -379,7 +379,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_tv_weekly_global(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_tv_weekly_global(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣全球剧集榜
|
异步豆瓣全球剧集榜
|
||||||
@@ -388,7 +388,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_tv_animation(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_tv_animation(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣热门动漫
|
异步豆瓣热门动漫
|
||||||
@@ -397,7 +397,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in tvs] if tvs else []
|
return [media.to_dict() for media in tvs] if tvs else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_movie_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_movie_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣热门电影
|
异步豆瓣热门电影
|
||||||
@@ -406,7 +406,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
|
|||||||
return [media.to_dict() for media in movies] if movies else []
|
return [media.to_dict() for media in movies] if movies else []
|
||||||
|
|
||||||
@log_execution_time(logger=logger)
|
@log_execution_time(logger=logger)
|
||||||
@cached(ttl=recommend_ttl, region=recommend_cache_region)
|
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
|
||||||
async def async_douban_tv_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
async def async_douban_tv_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]:
|
||||||
"""
|
"""
|
||||||
异步豆瓣热门电视剧
|
异步豆瓣热门电视剧
|
||||||
|
|||||||
@@ -1,42 +1,95 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from unittest import TestCase
|
from typing import Generator
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from app.chain.recommend import RecommendChain
|
from app.chain.recommend import RecommendChain
|
||||||
from app.core.cache import TTLCache
|
from app.core.cache import TTLCache
|
||||||
|
|
||||||
|
|
||||||
class RecommendChainTest(TestCase):
|
SYNC_EMPTY_CACHE_CASES = [
|
||||||
def tearDown(self):
|
("tmdb_movies", "app.chain.recommend.TmdbChain", "tmdb_discover"),
|
||||||
"""
|
("tmdb_tvs", "app.chain.recommend.TmdbChain", "tmdb_discover"),
|
||||||
清理推荐缓存,避免缓存装饰器状态影响其他用例。
|
("tmdb_trending", "app.chain.recommend.TmdbChain", "tmdb_trending"),
|
||||||
"""
|
("bangumi_calendar", "app.chain.recommend.BangumiChain", "calendar"),
|
||||||
RecommendChain.tmdb_trending.cache_clear()
|
("douban_movie_showing", "app.chain.recommend.DoubanChain", "movie_showing"),
|
||||||
asyncio.run(RecommendChain.async_tmdb_trending.cache_clear())
|
("douban_movies", "app.chain.recommend.DoubanChain", "douban_discover"),
|
||||||
|
("douban_tvs", "app.chain.recommend.DoubanChain", "douban_discover"),
|
||||||
|
("douban_movie_top250", "app.chain.recommend.DoubanChain", "movie_top250"),
|
||||||
|
("douban_tv_weekly_chinese", "app.chain.recommend.DoubanChain", "tv_weekly_chinese"),
|
||||||
|
("douban_tv_weekly_global", "app.chain.recommend.DoubanChain", "tv_weekly_global"),
|
||||||
|
("douban_tv_animation", "app.chain.recommend.DoubanChain", "tv_animation"),
|
||||||
|
("douban_movie_hot", "app.chain.recommend.DoubanChain", "movie_hot"),
|
||||||
|
("douban_tv_hot", "app.chain.recommend.DoubanChain", "tv_hot"),
|
||||||
|
]
|
||||||
|
|
||||||
|
ASYNC_EMPTY_CACHE_CASES = [
|
||||||
|
("async_tmdb_movies", "app.chain.recommend.TmdbChain"),
|
||||||
|
("async_tmdb_tvs", "app.chain.recommend.TmdbChain"),
|
||||||
|
("async_tmdb_trending", "app.chain.recommend.TmdbChain"),
|
||||||
|
("async_bangumi_calendar", "app.chain.recommend.BangumiChain"),
|
||||||
|
("async_douban_movie_showing", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_movies", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_tvs", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_movie_top250", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_tv_weekly_chinese", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_tv_weekly_global", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_tv_animation", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_movie_hot", "app.chain.recommend.DoubanChain"),
|
||||||
|
("async_douban_tv_hot", "app.chain.recommend.DoubanChain"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def clear_recommend_cache() -> None:
|
||||||
|
"""清理推荐缓存,避免缓存装饰器状态影响用例。"""
|
||||||
TTLCache(region=RecommendChain.recommend_cache_region).clear()
|
TTLCache(region=RecommendChain.recommend_cache_region).clear()
|
||||||
|
|
||||||
def test_tmdb_trending_does_not_cache_empty_result(self):
|
|
||||||
"""
|
@pytest.fixture(autouse=True)
|
||||||
TMDB流行趋势返回空列表时不应缓存,避免一次接口异常后长时间固定为空。
|
def isolated_recommend_cache() -> Generator[None, None, None]:
|
||||||
"""
|
"""每个用例前后都清空推荐缓存。"""
|
||||||
|
clear_recommend_cache()
|
||||||
|
yield
|
||||||
|
clear_recommend_cache()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("method_name", "chain_target", "backend_method"),
|
||||||
|
SYNC_EMPTY_CACHE_CASES,
|
||||||
|
)
|
||||||
|
def test_sync_recommend_methods_do_not_cache_empty_result(
|
||||||
|
method_name: str,
|
||||||
|
chain_target: str,
|
||||||
|
backend_method: str,
|
||||||
|
) -> None:
|
||||||
|
"""同步推荐来源返回空列表时不应缓存。"""
|
||||||
chain = RecommendChain()
|
chain = RecommendChain()
|
||||||
with patch("app.chain.recommend.TmdbChain") as tmdb_chain:
|
recommend_method = getattr(chain, method_name)
|
||||||
tmdb_chain.return_value.tmdb_trending.side_effect = [[], []]
|
|
||||||
|
|
||||||
self.assertEqual(chain.tmdb_trending(page=1), [])
|
with patch(chain_target) as backend_chain:
|
||||||
self.assertEqual(chain.tmdb_trending(page=1), [])
|
backend_call = getattr(backend_chain.return_value, backend_method)
|
||||||
|
backend_call.side_effect = [[], []]
|
||||||
|
|
||||||
self.assertEqual(tmdb_chain.return_value.tmdb_trending.call_count, 2)
|
assert recommend_method(page=1) == []
|
||||||
|
assert recommend_method(page=1) == []
|
||||||
|
|
||||||
def test_async_tmdb_trending_does_not_cache_empty_result(self):
|
assert backend_call.call_count == 2
|
||||||
"""
|
|
||||||
异步TMDB流行趋势返回空列表时也不应缓存。
|
|
||||||
"""
|
@pytest.mark.parametrize(("method_name", "chain_target"), ASYNC_EMPTY_CACHE_CASES)
|
||||||
|
def test_async_recommend_methods_do_not_cache_empty_result(
|
||||||
|
method_name: str,
|
||||||
|
chain_target: str,
|
||||||
|
) -> None:
|
||||||
|
"""异步推荐来源返回空列表时不应缓存。"""
|
||||||
chain = RecommendChain()
|
chain = RecommendChain()
|
||||||
with patch("app.chain.recommend.TmdbChain") as tmdb_chain:
|
recommend_method = getattr(chain, method_name)
|
||||||
tmdb_chain.return_value.async_run_module = AsyncMock(side_effect=[[], []])
|
|
||||||
|
|
||||||
self.assertEqual(asyncio.run(chain.async_tmdb_trending(page=1)), [])
|
with patch(chain_target) as backend_chain:
|
||||||
self.assertEqual(asyncio.run(chain.async_tmdb_trending(page=1)), [])
|
backend_chain.return_value.async_run_module = AsyncMock(side_effect=[[], []])
|
||||||
|
|
||||||
self.assertEqual(tmdb_chain.return_value.async_run_module.call_count, 2)
|
assert asyncio.run(recommend_method(page=1)) == []
|
||||||
|
assert asyncio.run(recommend_method(page=1)) == []
|
||||||
|
|
||||||
|
assert backend_chain.return_value.async_run_module.call_count == 2
|
||||||
|
|||||||
Reference in New Issue
Block a user