Files
MoviePilot/tests/test_plugin_catalog_runtime.py
T

60 lines
2.2 KiB
Python

"""插件安装事实与运行状态投影测试。"""
from types import SimpleNamespace
from app.runtime.extensions.plugin.catalog import PluginCatalogFacade
from app.schemas.plugin import PluginRuntimeStatus
from app.schemas.types import SystemConfigKey
def test_installed_catalog_keeps_plugins_that_are_not_loaded():
"""已安装清单中的插件即使缺依赖或源码也必须保留可观察卡片。"""
class ActivePlugin:
plugin_name = "已运行插件"
plugin_version = "1.0.0"
plugin_order = 0
active_instance = SimpleNamespace(get_state=lambda: True)
statuses = {
"ActivePlugin": PluginRuntimeStatus.ACTIVE,
"DependencyPending": PluginRuntimeStatus.DEPENDENCY_PENDING,
"SourceMissing": PluginRuntimeStatus.SOURCE_MISSING,
}
facade = PluginCatalogFacade(
classes=lambda: {"ActivePlugin": ActivePlugin},
running=lambda: {"ActivePlugin": active_instance},
storage=lambda: SimpleNamespace(
read=lambda key: [
"ActivePlugin",
"DependencyPending",
"SourceMissing",
] if key is SystemConfigKey.UserInstalledPlugins else None,
),
system=lambda: SimpleNamespace(),
market_catalog=lambda: None,
market_loader=lambda *_args, **_kwargs: [],
async_market_loader=lambda *_args, **_kwargs: [],
map_plugin=lambda **_kwargs: None,
auth_checker=lambda **_kwargs: True,
plugin_attr=lambda _plugin_id, _attr: None,
plugin_instance=lambda _plugin_id: None,
plugin_instances=lambda: {},
runtime_status=statuses.get,
log=SimpleNamespace(error=lambda *_args: None, info=lambda *_args: None),
)
plugins = facade.installed()
assert [plugin.id for plugin in plugins] == [
"ActivePlugin",
"DependencyPending",
"SourceMissing",
]
assert [plugin.runtime_status for plugin in plugins] == [
PluginRuntimeStatus.ACTIVE,
PluginRuntimeStatus.DEPENDENCY_PENDING,
PluginRuntimeStatus.SOURCE_MISSING,
]
assert plugins[1].plugin_name == "DependencyPending"
assert plugins[2].installed is True