mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-21 15:36:37 +08:00
252 lines
7.4 KiB
Python
252 lines
7.4 KiB
Python
import asyncio
|
|
import json
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from app.agent.tools.impl.query_download_tasks import QueryDownloadTasksTool
|
|
from app.schemas import DownloaderTorrent
|
|
|
|
|
|
def test_completed_status_returns_qbittorrent_and_transmission_completed_states():
|
|
"""
|
|
按完成状态查询时应包含 QB/TR 中非下载中、非暂停的实际状态。
|
|
"""
|
|
completed_torrents = [
|
|
DownloaderTorrent(
|
|
downloader="qb",
|
|
hash="hash-qb",
|
|
title="QB Done",
|
|
size=1024,
|
|
progress=100,
|
|
state="completed",
|
|
tags="moviepilot",
|
|
),
|
|
DownloaderTorrent(
|
|
downloader="tr",
|
|
hash="hash-tr",
|
|
title="TR Done",
|
|
size=2048,
|
|
progress=100,
|
|
state="completed",
|
|
tags="moviepilot",
|
|
),
|
|
]
|
|
download_chain = MagicMock()
|
|
download_chain.list_torrents.return_value = completed_torrents
|
|
|
|
with patch(
|
|
"app.agent.tools.impl.query_download_tasks.DownloadChain",
|
|
return_value=download_chain,
|
|
), patch.object(
|
|
QueryDownloadTasksTool,
|
|
"_load_history_map",
|
|
return_value={},
|
|
):
|
|
result = QueryDownloadTasksTool._query_downloads_sync(status="completed")
|
|
|
|
assert result["downloads"] == completed_torrents
|
|
download_chain.list_torrents.assert_called_once_with(
|
|
downloader=None,
|
|
status="completed",
|
|
include_all_tags=False,
|
|
)
|
|
|
|
|
|
def test_run_completed_status_formats_completed_download_tasks():
|
|
"""
|
|
工具输出应保留完成任务的实际下载器状态,便于用户判断来源。
|
|
"""
|
|
completed_torrents = [
|
|
DownloaderTorrent(
|
|
downloader="qb",
|
|
hash="hash-qb",
|
|
title="QB Done",
|
|
size=1024,
|
|
progress=100,
|
|
state="completed",
|
|
tags="moviepilot",
|
|
save_path="/downloads",
|
|
content_path="/downloads/QB Done",
|
|
category="电影",
|
|
download_limit=1024,
|
|
upload_limit=512,
|
|
ratio_limit=2.0,
|
|
seeding_time_limit=1440,
|
|
trackers=["https://tracker.example/announce"],
|
|
)
|
|
]
|
|
|
|
with patch.object(
|
|
QueryDownloadTasksTool,
|
|
"_query_downloads_sync",
|
|
return_value={"downloads": completed_torrents},
|
|
):
|
|
result = asyncio.run(
|
|
QueryDownloadTasksTool(session_id="session-1", user_id="10001").run(
|
|
status="completed"
|
|
)
|
|
)
|
|
|
|
payload = json.loads(result)
|
|
assert payload[0]["hash"] == "hash-qb"
|
|
assert payload[0]["state"] == "completed"
|
|
assert payload[0]["save_path"] == "/downloads"
|
|
assert payload[0]["content_path"] == "/downloads/QB Done"
|
|
assert payload[0]["category"] == "电影"
|
|
assert payload[0]["download_limit"] == 1024
|
|
assert payload[0]["upload_limit"] == 512
|
|
assert payload[0]["ratio_limit"] == 2.0
|
|
assert payload[0]["seeding_time_limit"] == 1440
|
|
assert payload[0]["trackers"] == ["https://tracker.example/announce"]
|
|
|
|
|
|
def test_hash_query_loads_trackers_for_matching_task():
|
|
"""
|
|
按 Hash 查询详情时应额外加载下载器支持的 Tracker 列表。
|
|
"""
|
|
torrent = DownloaderTorrent(
|
|
downloader="qb",
|
|
hash="a" * 40,
|
|
title="Task With Trackers",
|
|
size=1024,
|
|
progress=10,
|
|
state="downloading",
|
|
tags="moviepilot",
|
|
)
|
|
download_chain = MagicMock()
|
|
download_chain.list_torrents.return_value = [torrent]
|
|
download_chain.get_torrent_trackers.return_value = {
|
|
"qb": ["https://tracker.example/announce"]
|
|
}
|
|
|
|
with patch(
|
|
"app.agent.tools.impl.query_download_tasks.DownloadChain",
|
|
return_value=download_chain,
|
|
), patch.object(
|
|
QueryDownloadTasksTool,
|
|
"_load_history_map",
|
|
return_value={},
|
|
):
|
|
result = QueryDownloadTasksTool._query_downloads_sync(hash_value="a" * 40)
|
|
|
|
assert result["downloads"][0].trackers == ["https://tracker.example/announce"]
|
|
download_chain.get_torrent_trackers.assert_called_once_with(
|
|
hash_string="a" * 40,
|
|
downloader="qb",
|
|
)
|
|
|
|
|
|
def test_include_all_tags_passes_scope_to_downloader_query():
|
|
"""
|
|
智能体显式扩大范围时,应查询未打 MoviePilot 内置标签的下载任务。
|
|
"""
|
|
all_scope_torrents = [
|
|
DownloaderTorrent(
|
|
downloader="qb",
|
|
hash="hash-external",
|
|
title="External Task",
|
|
size=1024,
|
|
progress=10,
|
|
state="downloading",
|
|
tags="external",
|
|
)
|
|
]
|
|
download_chain = MagicMock()
|
|
download_chain.list_torrents.return_value = all_scope_torrents
|
|
|
|
with patch(
|
|
"app.agent.tools.impl.query_download_tasks.DownloadChain",
|
|
return_value=download_chain,
|
|
), patch.object(
|
|
QueryDownloadTasksTool,
|
|
"_load_history_map",
|
|
return_value={},
|
|
):
|
|
result = QueryDownloadTasksTool._query_downloads_sync(
|
|
status="all",
|
|
include_all_tags=True,
|
|
)
|
|
|
|
assert result["downloads"] == all_scope_torrents
|
|
download_chain.list_torrents.assert_called_once_with(
|
|
downloader=None,
|
|
status=None,
|
|
include_all_tags=True,
|
|
)
|
|
|
|
|
|
def test_include_all_tags_downloading_status_uses_list_torrents():
|
|
"""
|
|
查询全部标签范围的下载中任务时,不应走只面向 MoviePilot 任务的便捷方法。
|
|
"""
|
|
download_chain = MagicMock()
|
|
download_chain.list_torrents.return_value = [
|
|
DownloaderTorrent(
|
|
downloader="tr",
|
|
hash="hash-downloading",
|
|
title="Downloading External",
|
|
size=2048,
|
|
progress=50,
|
|
state="downloading",
|
|
tags="external",
|
|
)
|
|
]
|
|
|
|
with patch(
|
|
"app.agent.tools.impl.query_download_tasks.DownloadChain",
|
|
return_value=download_chain,
|
|
), patch.object(
|
|
QueryDownloadTasksTool,
|
|
"_load_history_map",
|
|
return_value={},
|
|
):
|
|
result = QueryDownloadTasksTool._query_downloads_sync(
|
|
status="downloading",
|
|
include_all_tags=True,
|
|
)
|
|
|
|
assert result["downloads"][0].hash == "hash-downloading"
|
|
download_chain.downloading.assert_not_called()
|
|
download_chain.list_torrents.assert_called_once_with(
|
|
downloader=None,
|
|
status="downloading",
|
|
include_all_tags=True,
|
|
)
|
|
|
|
|
|
def test_include_all_tags_false_string_keeps_builtin_tag_scope():
|
|
"""
|
|
CLI 字符串 false 不应被 Python 真值规则误判为扩大查询范围。
|
|
"""
|
|
download_chain = MagicMock()
|
|
download_chain.list_torrents.return_value = [
|
|
DownloaderTorrent(
|
|
downloader="qb",
|
|
hash="hash-moviepilot",
|
|
title="MoviePilot Task",
|
|
size=1024,
|
|
progress=100,
|
|
state="completed",
|
|
tags="moviepilot",
|
|
)
|
|
]
|
|
|
|
with patch(
|
|
"app.agent.tools.impl.query_download_tasks.DownloadChain",
|
|
return_value=download_chain,
|
|
), patch.object(
|
|
QueryDownloadTasksTool,
|
|
"_load_history_map",
|
|
return_value={},
|
|
):
|
|
result = QueryDownloadTasksTool._query_downloads_sync(
|
|
status="completed",
|
|
include_all_tags="false",
|
|
)
|
|
|
|
assert result["downloads"][0].hash == "hash-moviepilot"
|
|
download_chain.list_torrents.assert_called_once_with(
|
|
downloader=None,
|
|
status="completed",
|
|
include_all_tags=False,
|
|
)
|