mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-22 08:43:37 +08:00
fix(subscribe): 修复 RSS 媒体 ID 误识别跳过 (#6266)
This commit is contained in:
184
tests/test_subscribe_media_id_conflict.py
Normal file
184
tests/test_subscribe_media_id_conflict.py
Normal file
@@ -0,0 +1,184 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
from app.chain.subscribe import SubscribeChain
|
||||
from app.core.context import Context, MediaInfo, TorrentInfo
|
||||
from app.schemas.types import MediaType
|
||||
|
||||
|
||||
def _target_media(tmdb_id=106449, douban_id=None) -> MediaInfo:
|
||||
"""构造订阅目标媒体。"""
|
||||
return MediaInfo(
|
||||
title="凡人修仙传",
|
||||
original_title="凡人修仙传",
|
||||
names=["A Record Of A Mortals Journey To Immortality"],
|
||||
type=MediaType.TV,
|
||||
year="2020",
|
||||
season_years={1: "2020"},
|
||||
tmdb_id=tmdb_id,
|
||||
douban_id=douban_id,
|
||||
)
|
||||
|
||||
|
||||
def _candidate_media(tmdb_id=285479, douban_id=None) -> MediaInfo:
|
||||
"""构造由 RSS 标题推断出的候选媒体。"""
|
||||
return MediaInfo(
|
||||
title="凡人修仙传",
|
||||
type=MediaType.TV,
|
||||
year="2020",
|
||||
tmdb_id=tmdb_id,
|
||||
douban_id=douban_id,
|
||||
)
|
||||
|
||||
|
||||
def _torrent_meta(*, en_name="A Record Of A Mortals Journey To Immortality", tmdbid=None):
|
||||
"""构造不触发外部识别的标题解析结果。"""
|
||||
return SimpleNamespace(
|
||||
tmdbid=tmdbid,
|
||||
doubanid=None,
|
||||
bangumiid=None,
|
||||
anilistid=None,
|
||||
media_source="themoviedb" if tmdbid else None,
|
||||
media_id=str(tmdbid) if tmdbid else None,
|
||||
cn_name="",
|
||||
en_name=en_name,
|
||||
type=MediaType.TV,
|
||||
year=None,
|
||||
org_string=f"{en_name} S01E186 2160p WEB-DL",
|
||||
)
|
||||
|
||||
|
||||
def _context(meta, candidate, torrent) -> Context:
|
||||
"""构造 RSS 候选上下文。"""
|
||||
return Context(
|
||||
meta_info=meta,
|
||||
media_info=candidate,
|
||||
torrent_info=torrent,
|
||||
resource_source="rss",
|
||||
match_source="tmdbid",
|
||||
candidate_recognized=True,
|
||||
media_info_is_target=False,
|
||||
)
|
||||
|
||||
|
||||
def _reconcile(target, candidate, meta, torrent, context):
|
||||
"""调用订阅链的候选媒体冲突复核。"""
|
||||
return SubscribeChain._SubscribeChain__reconcile_candidate_media(
|
||||
target_mediainfo=target,
|
||||
candidate_mediainfo=candidate,
|
||||
torrent_meta=meta,
|
||||
torrent_info=torrent,
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
||||
def test_inferred_tmdb_conflict_falls_back_to_strict_alias_match():
|
||||
"""标题推断到重复 TMDB 条目时应允许订阅目标别名复核。"""
|
||||
target = _target_media()
|
||||
candidate = _candidate_media()
|
||||
meta = _torrent_meta()
|
||||
torrent = TorrentInfo(
|
||||
title="A Record Of A Mortals Journey To Immortality S01E186 2160p WEB-DL",
|
||||
site_name="测试站点",
|
||||
category=MediaType.TV.value,
|
||||
)
|
||||
context = _context(meta, candidate, torrent)
|
||||
|
||||
result = _reconcile(target, candidate, meta, torrent, context)
|
||||
|
||||
assert result is target
|
||||
assert context.media_info is target
|
||||
assert context.match_source == "title"
|
||||
assert context.candidate_recognized is False
|
||||
assert context.media_info_is_target is True
|
||||
|
||||
|
||||
def test_inferred_tmdb_conflict_rejects_nonmatching_title():
|
||||
"""ID 冲突且标题和别名不匹配时应继续拒绝候选。"""
|
||||
target = _target_media()
|
||||
candidate = _candidate_media()
|
||||
meta = _torrent_meta(en_name="Different Series")
|
||||
torrent = TorrentInfo(
|
||||
title="Different Series S01E186 2160p WEB-DL",
|
||||
site_name="测试站点",
|
||||
category=MediaType.TV.value,
|
||||
)
|
||||
context = _context(meta, candidate, torrent)
|
||||
|
||||
assert _reconcile(target, candidate, meta, torrent, context) is None
|
||||
assert context.media_info is candidate
|
||||
assert context.match_source == "tmdbid"
|
||||
assert context.candidate_recognized is True
|
||||
assert context.media_info_is_target is False
|
||||
|
||||
|
||||
def test_inferred_douban_conflict_falls_back_to_strict_alias_match():
|
||||
"""豆瓣 ID 推断冲突时应使用同一套严格标题复核。"""
|
||||
target = _target_media(tmdb_id=None, douban_id="30170816")
|
||||
candidate = _candidate_media(tmdb_id=None, douban_id="36612345")
|
||||
meta = _torrent_meta()
|
||||
torrent = TorrentInfo(
|
||||
title="A Record Of A Mortals Journey To Immortality S01E186 2160p WEB-DL",
|
||||
site_name="测试站点",
|
||||
category=MediaType.TV.value,
|
||||
)
|
||||
context = _context(meta, candidate, torrent)
|
||||
|
||||
result = _reconcile(target, candidate, meta, torrent, context)
|
||||
|
||||
assert result is target
|
||||
assert context.media_info is target
|
||||
assert context.match_source == "title"
|
||||
|
||||
|
||||
def test_explicit_tmdb_identity_keeps_strict_conflict_rejection():
|
||||
"""标题显式携带媒体 ID 时不得被标题别名覆盖。"""
|
||||
target = _target_media()
|
||||
candidate = _candidate_media()
|
||||
meta = _torrent_meta(tmdbid=285479)
|
||||
torrent = TorrentInfo(
|
||||
title="A Record Of A Mortals Journey To Immortality S01E186 {tmdbid=285479}",
|
||||
site_name="测试站点",
|
||||
category=MediaType.TV.value,
|
||||
)
|
||||
context = _context(meta, candidate, torrent)
|
||||
|
||||
assert _reconcile(target, candidate, meta, torrent, context) is None
|
||||
assert context.media_info is candidate
|
||||
assert context.match_source == "tmdbid"
|
||||
|
||||
|
||||
def test_conflict_rejects_target_without_same_source_identity():
|
||||
"""订阅目标缺少候选同来源 ID 时不得用标题跨来源放行。"""
|
||||
target = _target_media(tmdb_id=None)
|
||||
candidate = _candidate_media()
|
||||
meta = _torrent_meta()
|
||||
torrent = TorrentInfo(
|
||||
title="A Record Of A Mortals Journey To Immortality S01E186",
|
||||
site_name="测试站点",
|
||||
category=MediaType.TV.value,
|
||||
)
|
||||
context = _context(meta, candidate, torrent)
|
||||
|
||||
assert _reconcile(target, candidate, meta, torrent, context) is None
|
||||
assert context.media_info is candidate
|
||||
|
||||
|
||||
def test_matching_media_id_preserves_candidate_identity():
|
||||
"""媒体 ID 原本一致时应保持候选识别上下文。"""
|
||||
target = _target_media()
|
||||
candidate = _candidate_media(tmdb_id=106449)
|
||||
meta = _torrent_meta()
|
||||
torrent = TorrentInfo(
|
||||
title="A Record Of A Mortals Journey To Immortality S01E186",
|
||||
site_name="测试站点",
|
||||
category=MediaType.TV.value,
|
||||
)
|
||||
context = _context(meta, candidate, torrent)
|
||||
|
||||
result = _reconcile(target, candidate, meta, torrent, context)
|
||||
|
||||
assert result is candidate
|
||||
assert context.media_info is candidate
|
||||
assert context.match_source == "tmdbid"
|
||||
assert context.candidate_recognized is True
|
||||
assert context.media_info_is_target is False
|
||||
Reference in New Issue
Block a user