diff --git a/app/schemas/types.py b/app/schemas/types.py index 2f38385f0..55d9e4efe 100644 --- a/app/schemas/types.py +++ b/app/schemas/types.py @@ -59,6 +59,7 @@ _MEDIA_SOURCE_VALUE_ALIASES = { "mango_tv": "mangguodiscover", "migu_video": "migu", "tencent_video": "tencentvideodiscover", + "iqiyi": "iqiyidiscover", } @@ -78,6 +79,7 @@ class MediaSource(str, Enum): MangoTV = "mangguodiscover" MiguVideo = "migu" TencentVideo = "tencentvideodiscover" + Iqiyi = "iqiyidiscover" def __str__(self) -> str: """返回可直接用于 API 和数据库的规范值。""" diff --git a/app/utils/media.py b/app/utils/media.py index 7146f2f42..1e9585942 100644 --- a/app/utils/media.py +++ b/app/utils/media.py @@ -28,6 +28,8 @@ MEDIA_SOURCE_ALIASES = { "migu_video": MediaSource.MiguVideo, "tencentvideodiscover": MediaSource.TencentVideo, "tencent_video": MediaSource.TencentVideo, + "iqiyi": MediaSource.Iqiyi, + "iqiyidiscover": MediaSource.Iqiyi, } MEDIA_SOURCE_PREFIXES = { @@ -44,6 +46,7 @@ MEDIA_SOURCE_PREFIXES = { MediaSource.MangoTV: "mangguodiscover", MediaSource.MiguVideo: "migu", MediaSource.TencentVideo: "tencentvideodiscover", + MediaSource.Iqiyi: "iqiyidiscover", } MUSIC_MEDIA_SOURCE_ORDER = ( diff --git a/tests/test_media_source_routing.py b/tests/test_media_source_routing.py index 40134dd91..8483744f2 100644 --- a/tests/test_media_source_routing.py +++ b/tests/test_media_source_routing.py @@ -4,7 +4,11 @@ from app.chain import ChainBase from app.core.context import MediaInfo from app.core.meta import MetaBase from app.schemas.types import MediaSource, MediaType -from app.utils.media import resolve_media_identity +from app.utils.media import ( + build_media_key, + parse_media_source_selection, + resolve_media_identity, +) def _chain_without_init() -> ChainBase: @@ -22,6 +26,18 @@ def test_generic_source_id_resolves_as_fixed_enum() -> None: ) == (MediaSource.AniList, "154587") +def test_iqiyi_source_routes_through_unified_identity() -> None: + """爱奇艺探索来源应支持选择解析、身份解析和媒体键构造。""" + assert parse_media_source_selection("iqiyi,iqiyidiscover") == ( + MediaSource.Iqiyi, + ) + assert resolve_media_identity( + media_source="iqiyi", + media_id="album-1", + ) == (MediaSource.Iqiyi, "album-1") + assert build_media_key("iqiyi", "album-1") == "iqiyidiscover:album-1" + + def test_plugin_source_is_preserved_as_dynamic_enum() -> None: """格式合法的插件来源应作为动态枚举成员进入通用识别链。""" assert resolve_media_identity( diff --git a/tests/test_search_media_sources.py b/tests/test_search_media_sources.py index 60f711bda..eee4bdd0a 100644 --- a/tests/test_search_media_sources.py +++ b/tests/test_search_media_sources.py @@ -20,6 +20,13 @@ def test_media_source_normalization_accepts_plugin_source() -> None: assert normalize_media_source("plugin source:invalid") is None +def test_iqiyi_media_source_aliases_are_normalized() -> None: + """爱奇艺探索来源的历史前缀和规范前缀应归一到同一媒体来源。""" + assert normalize_media_source("iqiyi") is MediaSource.Iqiyi + assert normalize_media_source("iqiyidiscover") is MediaSource.Iqiyi + assert MediaSource("iqiyi") is MediaSource.Iqiyi + + def test_resolve_anilist_search_params_preserves_identity() -> None: """精确搜索参数应保留枚举来源和原生 ID。""" params, message = asyncio.run(