mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-09 09:26:55 +08:00
fix(workflow): resolve plugin actions by public id
This commit is contained in:
@@ -47,7 +47,16 @@ class InvokePluginAction(BaseAction):
|
||||
logger.error(f"插件不存在: {params.plugin_id}")
|
||||
return context
|
||||
actions = plugin_actions[0].get("actions", [])
|
||||
action = next((action for action in actions if action.get("action_id") == params.action_id), None)
|
||||
# 插件公开动作契约使用 ``id``;读取旧插件声明时保留 action_id 回退,避免已保存工作流失效。
|
||||
action = next(
|
||||
(
|
||||
action
|
||||
for action in actions
|
||||
if (action.get("id") or action.get("action_id"))
|
||||
== params.action_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if not action or not action.get("func"):
|
||||
logger.error(f"插件动作不存在: {params.plugin_id} - {params.action_id}")
|
||||
return context
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
"""插件工作流动作标识的公开契约与执行回归。"""
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from app.schemas.workflow import ActionContext
|
||||
from app.workflow.actions.invoke_plugin import InvokePluginAction
|
||||
|
||||
|
||||
def _execute_with_action(action: dict) -> tuple[InvokePluginAction, ActionContext]:
|
||||
"""在最小运行时替身中执行一个插件动作。"""
|
||||
context = ActionContext(content="before")
|
||||
action_fn = Mock(return_value=(True, context))
|
||||
action["func"] = action_fn
|
||||
plugin_manager = Mock()
|
||||
plugin_manager.get_plugin_actions.return_value = [
|
||||
{"plugin_id": "plugin-a", "actions": [action]}
|
||||
]
|
||||
|
||||
with patch(
|
||||
"app.workflow.actions.get_configured_system_config",
|
||||
return_value=Mock(),
|
||||
), patch(
|
||||
"app.workflow.actions.invoke_plugin.get_plugin_manager",
|
||||
return_value=plugin_manager,
|
||||
):
|
||||
action_runner = InvokePluginAction("invoke")
|
||||
result = action_runner.execute(
|
||||
workflow_id=1,
|
||||
params={
|
||||
"plugin_id": "plugin-a",
|
||||
"action_id": "cleanup",
|
||||
"action_params": {"force": True},
|
||||
},
|
||||
context=context,
|
||||
)
|
||||
|
||||
action_fn.assert_called_once_with(context, force=True)
|
||||
assert action_runner.success is True
|
||||
assert action_runner.done is True
|
||||
return action_runner, result
|
||||
|
||||
|
||||
def test_invoke_plugin_uses_public_action_id() -> None:
|
||||
"""插件公开的 id 字段必须可被工作流执行器解析。"""
|
||||
_, result = _execute_with_action({"id": "cleanup"})
|
||||
|
||||
assert result.content == "before"
|
||||
|
||||
|
||||
def test_invoke_plugin_keeps_legacy_action_id_fallback() -> None:
|
||||
"""历史插件声明仍可通过 action_id 回退执行。"""
|
||||
_, result = _execute_with_action({"action_id": "cleanup"})
|
||||
|
||||
assert result.content == "before"
|
||||
Reference in New Issue
Block a user