mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-07-17 10:42:17 +08:00
Merge remote-tracking branch 'origin/v2' into v2
This commit is contained in:
@@ -330,6 +330,7 @@ def _build_tv_context(episode_list=None):
|
||||
),
|
||||
torrent_info=SimpleNamespace(title="Test Show S01 2160p", site_name="TestSite"),
|
||||
allowed_episodes=None,
|
||||
confirmed_full_coverage=False,
|
||||
)
|
||||
|
||||
|
||||
@@ -362,6 +363,40 @@ def test_batch_download_rejects_complete_coverage_when_files_do_not_cover_target
|
||||
|
||||
assert downloads == []
|
||||
assert lefts == no_exists
|
||||
assert context.confirmed_full_coverage is False
|
||||
chain.download_single.assert_not_called()
|
||||
|
||||
|
||||
def test_batch_download_rejects_complete_coverage_when_only_missing_episodes_match(monkeypatch):
|
||||
"""
|
||||
完整覆盖要求目标范围全集,不能只覆盖当前缺口集。
|
||||
"""
|
||||
_FakeBatchTorrentHelper.episodes = [4, 5]
|
||||
monkeypatch.setattr(download_module, "TorrentHelper", _FakeBatchTorrentHelper)
|
||||
monkeypatch.setattr(download_module.eventmanager, "send_event", lambda *args, **kwargs: None)
|
||||
|
||||
chain = DownloadChain.__new__(DownloadChain)
|
||||
chain.download_torrent = MagicMock(return_value=(b"torrent-content", "", ["demo.mkv"]))
|
||||
chain.download_single = MagicMock(return_value="hash")
|
||||
|
||||
context = _build_tv_context()
|
||||
no_exists = {
|
||||
1: {
|
||||
1: NotExistMediaInfo(
|
||||
season=1,
|
||||
episodes=[4, 5],
|
||||
total_episode=5,
|
||||
start_episode=1,
|
||||
require_complete_coverage=True,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
downloads, lefts = chain.batch_download(contexts=[context], no_exists=no_exists)
|
||||
|
||||
assert downloads == []
|
||||
assert lefts == no_exists
|
||||
assert context.confirmed_full_coverage is False
|
||||
chain.download_single.assert_not_called()
|
||||
|
||||
|
||||
@@ -462,9 +497,43 @@ def test_batch_download_accepts_complete_coverage_when_files_cover_target_range(
|
||||
|
||||
assert downloads == [context]
|
||||
assert lefts == {}
|
||||
assert context.confirmed_full_coverage is True
|
||||
chain.download_single.assert_called_once()
|
||||
|
||||
|
||||
def test_batch_download_rejects_complete_coverage_when_files_have_same_count_but_wrong_range(monkeypatch):
|
||||
"""
|
||||
完整覆盖按目标集号集合判断,不能让同数量的偏移局部包通过。
|
||||
"""
|
||||
_FakeBatchTorrentHelper.episodes = list(range(1, 45))
|
||||
monkeypatch.setattr(download_module, "TorrentHelper", _FakeBatchTorrentHelper)
|
||||
monkeypatch.setattr(download_module.eventmanager, "send_event", lambda *args, **kwargs: None)
|
||||
|
||||
chain = DownloadChain.__new__(DownloadChain)
|
||||
chain.download_torrent = MagicMock(return_value=(b"torrent-content", "", ["demo.mkv"]))
|
||||
chain.download_single = MagicMock(return_value="hash")
|
||||
|
||||
context = _build_tv_context()
|
||||
no_exists = {
|
||||
1: {
|
||||
1: NotExistMediaInfo(
|
||||
season=1,
|
||||
episodes=[],
|
||||
total_episode=143,
|
||||
start_episode=100,
|
||||
require_complete_coverage=True,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
downloads, lefts = chain.batch_download(contexts=[context], no_exists=no_exists)
|
||||
|
||||
assert downloads == []
|
||||
assert lefts == no_exists
|
||||
assert context.confirmed_full_coverage is False
|
||||
chain.download_single.assert_not_called()
|
||||
|
||||
|
||||
def test_batch_download_accepts_complete_coverage_when_title_episodes_cover_target(monkeypatch):
|
||||
"""
|
||||
显式标出完整范围的候选也可满足完整覆盖任务。
|
||||
@@ -494,6 +563,7 @@ def test_batch_download_accepts_complete_coverage_when_title_episodes_cover_targ
|
||||
|
||||
assert downloads == [context]
|
||||
assert lefts == {}
|
||||
assert context.confirmed_full_coverage is True
|
||||
chain.download_torrent.assert_not_called()
|
||||
chain.download_single.assert_called_once()
|
||||
|
||||
@@ -527,6 +597,7 @@ def test_batch_download_rejects_complete_coverage_when_title_episodes_are_partia
|
||||
|
||||
assert downloads == []
|
||||
assert lefts == no_exists
|
||||
assert context.confirmed_full_coverage is False
|
||||
chain.download_torrent.assert_not_called()
|
||||
chain.download_single.assert_not_called()
|
||||
|
||||
@@ -561,6 +632,7 @@ def test_batch_download_complete_coverage_ignores_allowed_episode_narrowing(monk
|
||||
|
||||
assert downloads == []
|
||||
assert lefts == no_exists
|
||||
assert context.confirmed_full_coverage is False
|
||||
chain.download_torrent.assert_not_called()
|
||||
chain.download_single.assert_not_called()
|
||||
|
||||
@@ -593,4 +665,5 @@ def test_batch_download_keeps_count_check_without_complete_coverage(monkeypatch)
|
||||
|
||||
assert downloads == [context]
|
||||
assert lefts == {}
|
||||
assert context.confirmed_full_coverage is False
|
||||
chain.download_single.assert_called_once()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -265,6 +265,81 @@ class TransferJobManagerTest(unittest.TestCase):
|
||||
self.assertEqual(target_item, transferinfo.target_item)
|
||||
self.assertEqual(target_folder, transferinfo.target_diritem)
|
||||
|
||||
def test_single_file_transfer_intercept_event_carries_file_meta(self):
|
||||
"""
|
||||
单文件整理拦截事件应携带元数据,便于事件处理器按季集匹配。
|
||||
"""
|
||||
handler = TransHandler()
|
||||
source_item = FileItem(
|
||||
storage="alist",
|
||||
path="/downloads/Test.Show.S02E03.mkv",
|
||||
type="file",
|
||||
name="Test.Show.S02E03.mkv",
|
||||
basename="Test.Show.S02E03",
|
||||
extension="mkv",
|
||||
size=1024,
|
||||
modify_time=1715939275.0,
|
||||
)
|
||||
target_path = Path("/library")
|
||||
target_file = Path("/library/Test.Show.S02E03.mkv")
|
||||
target_folder = FileItem(
|
||||
storage="alist",
|
||||
type="dir",
|
||||
path="/library/",
|
||||
name="library",
|
||||
basename="library",
|
||||
)
|
||||
target_item = FileItem(
|
||||
storage="alist",
|
||||
path=target_file.as_posix(),
|
||||
type="file",
|
||||
name=target_file.name,
|
||||
basename=target_file.stem,
|
||||
extension="mkv",
|
||||
size=1024,
|
||||
)
|
||||
source_oper = SimpleNamespace(
|
||||
is_support_transtype=lambda transfer_type: True,
|
||||
move=lambda fileitem, path, name: True,
|
||||
)
|
||||
target_oper = SimpleNamespace(
|
||||
get_folder=lambda path: target_folder,
|
||||
get_item=lambda path: None,
|
||||
)
|
||||
in_meta = MetaVideo("Test.Show.S02E03")
|
||||
|
||||
with patch.object(
|
||||
TransHandler, "get_rename_path", return_value=target_file
|
||||
), patch(
|
||||
"app.modules.filemanager.transhandler.DirectoryHelper.get_media_root_path",
|
||||
return_value=Path("/library"),
|
||||
), patch.object(
|
||||
TransHandler,
|
||||
"_TransHandler__transfer_command",
|
||||
return_value=(target_item, ""),
|
||||
), patch(
|
||||
"app.modules.filemanager.transhandler.eventmanager.send_event",
|
||||
return_value=None,
|
||||
) as send_event:
|
||||
transferinfo = handler.transfer_media(
|
||||
fileitem=source_item,
|
||||
in_meta=in_meta,
|
||||
mediainfo=make_media_info(),
|
||||
target_storage="alist",
|
||||
target_path=target_path,
|
||||
transfer_type="move",
|
||||
source_oper=source_oper,
|
||||
target_oper=target_oper,
|
||||
need_scrape=True,
|
||||
need_notify=True,
|
||||
)
|
||||
|
||||
self.assertTrue(transferinfo.success)
|
||||
event_data = send_event.call_args.args[1]
|
||||
self.assertIs(in_meta, event_data.meta)
|
||||
self.assertEqual(2, event_data.meta.begin_season)
|
||||
self.assertEqual(3, event_data.meta.begin_episode)
|
||||
|
||||
def test_success_callback_uses_transfer_result_target_diritem(self):
|
||||
"""
|
||||
回调发送刮削事件时应直接使用整理结果里的目标目录项。
|
||||
|
||||
Reference in New Issue
Block a user