mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-29 19:37:54 +08:00
156 lines
5.3 KiB
Python
156 lines
5.3 KiB
Python
"""
|
|
验证Slack 命令注册及渠道能力声明。
|
|
"""
|
|
|
|
from types import SimpleNamespace
|
|
from unittest.mock import Mock, patch
|
|
|
|
from app.modules.slack import SlackModule
|
|
from app.modules.slack.slack import Slack
|
|
from app.schemas.event import CommandRegisterEventData
|
|
|
|
|
|
def test_slack_module_register_commands_filters_event_subset():
|
|
"""
|
|
Slack 模块注册命令时应复用渠道级 CommandRegister 事件过滤结果。
|
|
"""
|
|
module = SlackModule()
|
|
client = SimpleNamespace(register_commands=Mock(), delete_commands=Mock())
|
|
original_commands = {
|
|
"/sites": {"description": "管理站点"},
|
|
"/version": {"description": "当前版本"},
|
|
}
|
|
event = SimpleNamespace(
|
|
event_data=CommandRegisterEventData(
|
|
commands={"/sites": {"description": "管理站点"}, "/unknown": {"description": "无效"}},
|
|
origin="SlackFilter",
|
|
service="slack-main",
|
|
)
|
|
)
|
|
|
|
with (
|
|
patch.object(
|
|
module,
|
|
"get_configs",
|
|
return_value={"slack-main": SimpleNamespace(name="slack-main", config={})},
|
|
),
|
|
patch.object(module, "get_instance", return_value=client),
|
|
patch("app.modules._base.notification.eventmanager.send_event", return_value=event),
|
|
):
|
|
module.register_commands(original_commands)
|
|
|
|
client.register_commands.assert_called_once_with({"/sites": {"description": "管理站点"}})
|
|
client.delete_commands.assert_not_called()
|
|
|
|
|
|
def test_slack_manifest_update_preserves_foreign_commands():
|
|
"""
|
|
Slack Manifest 更新应只替换 MoviePilot 本次管理的 Slash Commands。
|
|
"""
|
|
client = Slack.__new__(Slack)
|
|
manifest_client = SimpleNamespace(
|
|
apps_manifest_export=Mock(
|
|
return_value={
|
|
"ok": True,
|
|
"manifest": {
|
|
"features": {
|
|
"slash_commands": [
|
|
{"command": "/keep", "description": "保留"},
|
|
{"command": "/sites", "description": "旧站点"},
|
|
{
|
|
"command": "/old_moviepilot",
|
|
"description": "旧命令",
|
|
"usage_hint": "MoviePilot 可选参数",
|
|
},
|
|
]
|
|
}
|
|
},
|
|
}
|
|
),
|
|
apps_manifest_update=Mock(return_value={"ok": True}),
|
|
)
|
|
client._manifest_client = manifest_client
|
|
client._app_id = "A123"
|
|
client._command_request_url = "https://example.com/slack/commands"
|
|
client._registered_command_names = {"/sites"}
|
|
|
|
assert client.register_commands(
|
|
{
|
|
"/sites": {"description": "管理站点"},
|
|
"/version": {"description": "当前版本"},
|
|
}
|
|
)
|
|
|
|
manifest_client.apps_manifest_update.assert_called_once()
|
|
_, kwargs = manifest_client.apps_manifest_update.call_args
|
|
assert kwargs["app_id"] == "A123"
|
|
slash_commands = kwargs["manifest"]["features"]["slash_commands"]
|
|
assert [item["command"] for item in slash_commands] == [
|
|
"/keep",
|
|
"/sites",
|
|
"/version",
|
|
]
|
|
assert slash_commands[1]["url"] == "https://example.com/slack/commands"
|
|
assert client._registered_command_names == {"/sites", "/version"}
|
|
|
|
|
|
def test_slack_command_registration_skips_without_manifest_credentials():
|
|
"""
|
|
未配置 Slack Manifest 凭据时不应尝试自动注册。
|
|
"""
|
|
client = Slack.__new__(Slack)
|
|
client._manifest_client = None
|
|
client._app_id = ""
|
|
|
|
assert client.register_commands({"/sites": {"description": "管理站点"}}) is False
|
|
|
|
|
|
def test_slack_normalizes_slash_command_names():
|
|
"""
|
|
Slack 命令名称应符合平台 Slash Command 约束。
|
|
"""
|
|
assert Slack._normalize_slack_command("/sites") == "/sites"
|
|
assert Slack._normalize_slack_command("CLEAR_CACHE") == "/clear_cache"
|
|
assert Slack._normalize_slack_command("/中文") == ""
|
|
assert Slack._normalize_slack_command("/" + "a" * 32) == ""
|
|
|
|
|
|
def test_slack_plain_text_interaction_buttons_render_and_clear_on_edit():
|
|
"""
|
|
纯文本交互必须显示按钮,后续无按钮编辑应清除旧操作区。
|
|
"""
|
|
client = Slack.__new__(Slack)
|
|
client._client = Mock()
|
|
client._client.chat_postMessage.return_value = {"ok": True, "ts": "1", "channel": "C1"}
|
|
client._client.chat_update.return_value = {"ok": True, "ts": "1", "channel": "C1"}
|
|
buttons = [[{"text": "确认升级", "callback_data": "update:req:download"}]]
|
|
|
|
assert (
|
|
client.send_msg(
|
|
title="发现更新",
|
|
text="v3.0.0 -> v3.1.0",
|
|
userid="C1",
|
|
buttons=buttons,
|
|
)[0]
|
|
is True
|
|
)
|
|
|
|
posted = client._client.chat_postMessage.call_args.kwargs
|
|
assert posted["text"] == "发现更新\nv3.0.0 -> v3.1.0"
|
|
assert [block["type"] for block in posted["blocks"]] == ["section", "actions"]
|
|
assert posted["blocks"][1]["elements"][0]["value"] == "update:req:download"
|
|
|
|
assert (
|
|
client.send_msg(
|
|
title="正在下载",
|
|
text="50%",
|
|
original_message_id="1",
|
|
original_chat_id="C1",
|
|
)[0]
|
|
is True
|
|
)
|
|
|
|
updated = client._client.chat_update.call_args.kwargs
|
|
assert updated["text"] == "正在下载\n50%"
|
|
assert updated["blocks"] == []
|