Files
MoviePilot/tests/test_transfer_mounted_disk_cleanup.py
T
jxxghp 7e851dbfa7 refactor(chain): 处理链功能域 mixin 化,清理未使用导入并根治兼容层循环导入
- ChainBase 拆分为 RecognitionMixin/MessageProcessingMixin/NotificationMixin
- TransferChain 拆分为 7 个功能 mixin(_mixins.py),SubscribeChain 音乐订阅域拆出 _music.py
- 斜杠命令交互四件套收敛为 InteractionChainMixin 委托,会话管理器移至 application 层,chain 层不再 re-export
- 模块基础类收敛到 app/modules/_base(notification/mediaserver 语义重命名)
- 清理 app/chain/__init__.py 24 个未使用导入,修正 49 处测试 patch 目标到实际命名空间
- 兼容层 legacy 符号不再并入 __all__,根治 schemas 初始化反向拉起 application.transfer 的循环导入
- 修复 bangumi 集数为字符串时 set_bangumi_info 抛 TypeError
- 新增重复代码等架构门禁测试;capability 清单校验排除下划线内部目录
2026-08-16 16:30:16 +08:00

148 lines
4.5 KiB
Python

from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
from app.chain.transfer import TransferChain
from app.schemas import FileItem, TransferDirectoryConf
from app.application.transfer import TransferTask
from app.adapters.system.host import SystemUtils
def _make_task(
storage: str = "local",
download_path: str = "/mnt/clouddrive/downloads",
) -> TransferTask:
return TransferTask(
fileitem=FileItem(
storage=storage,
path=f"{download_path}/Test.Show.S01E01.mkv",
type="file",
name="Test.Show.S01E01.mkv",
),
target_directory=TransferDirectoryConf(
storage=storage,
download_path=download_path,
),
)
def test_enabled_cleanup_skips_filesystem_detection():
"""
开关开启时应保持旧行为,且不产生额外文件系统检测。
"""
with patch(
"app.chain._mixins.SystemUtils.is_network_filesystem"
) as is_network_filesystem:
should_delete = (
TransferChain._should_delete_empty_source_directories(
_make_task(),
True,
{},
)
)
assert should_delete is True
is_network_filesystem.assert_not_called()
def test_disabled_cleanup_keeps_mounted_local_source_directories():
"""
开关关闭时应保留网络或 FUSE 挂载的本地源目录。
"""
with patch(
"app.chain._mixins.SystemUtils.is_network_filesystem",
return_value=True,
) as is_network_filesystem:
should_delete = (
TransferChain._should_delete_empty_source_directories(
_make_task(),
False,
{},
)
)
assert should_delete is False
is_network_filesystem.assert_called_once_with(
Path("/mnt/clouddrive/downloads"), include_local_fuse=True
)
def test_disabled_cleanup_still_deletes_ordinary_local_source_directories():
"""
开关关闭时普通本地文件系统仍应删除空目录。
"""
with patch(
"app.chain._mixins.SystemUtils.is_network_filesystem",
return_value=False,
):
should_delete = (
TransferChain._should_delete_empty_source_directories(
_make_task(download_path="/downloads"),
False,
{},
)
)
assert should_delete is True
def test_disabled_cleanup_does_not_change_remote_storage_cleanup():
"""
开关关闭时非本地存储仍应执行原有空目录清理。
"""
with patch(
"app.chain._mixins.SystemUtils.is_network_filesystem"
) as is_network_filesystem:
should_delete = (
TransferChain._should_delete_empty_source_directories(
_make_task(storage="alist", download_path="/downloads"),
False,
{},
)
)
assert should_delete is True
is_network_filesystem.assert_not_called()
def test_mounted_filesystem_detection_is_cached_by_source_directory():
"""
同一源根目录的批量任务应只检测一次文件系统。
"""
mounted_filesystem_cache = {}
with patch(
"app.chain._mixins.SystemUtils.is_network_filesystem",
return_value=True,
) as is_network_filesystem:
for _ in range(2):
should_delete = (
TransferChain._should_delete_empty_source_directories(
_make_task(),
False,
mounted_filesystem_cache,
)
)
assert should_delete is False
is_network_filesystem.assert_called_once_with(
Path("/mnt/clouddrive/downloads"), include_local_fuse=True
)
def test_cleanup_detection_includes_local_fuse_mounts():
"""
空目录清理场景应将原本排除的本地 FUSE 文件系统视为挂载盘。
"""
df_result = SimpleNamespace(
returncode=0,
stdout="Filesystem Type 1K-blocks Used Available Use% Mounted on\n"
"shfs fuse.shfs 1 1 1 1% /mnt/user\n",
)
with patch("app.adapters.system.host.platform.system", return_value="Linux"), patch(
"app.adapters.system.host.subprocess.run", return_value=df_result
):
assert SystemUtils.is_network_filesystem(Path("/mnt/user")) is False
assert SystemUtils.is_network_filesystem(
Path("/mnt/user"), include_local_fuse=True
) is True