mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-19 06:30:29 +08:00
119 lines
4.3 KiB
Python
119 lines
4.3 KiB
Python
import asyncio
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock, Mock, patch
|
|
|
|
from app.modules.discord import DiscordModule
|
|
from app.modules.discord.discord import Discord
|
|
from app.schemas import CommandRegisterEventData
|
|
|
|
|
|
def test_discord_module_register_commands_filters_event_subset():
|
|
"""Discord 模块注册命令时应复用渠道级 CommandRegister 事件过滤结果。"""
|
|
module = DiscordModule()
|
|
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="DiscordFilter",
|
|
service="discord-main",
|
|
)
|
|
)
|
|
|
|
with (
|
|
patch.object(
|
|
module,
|
|
"get_configs",
|
|
return_value={"discord-main": SimpleNamespace(name="discord-main", config={})},
|
|
),
|
|
patch.object(module, "get_instance", return_value=client),
|
|
patch("app.modules.discord.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_discord_module_register_commands_deletes_when_event_canceled():
|
|
"""Discord 模块注册命令被事件取消时应清理应用命令。"""
|
|
module = DiscordModule()
|
|
client = SimpleNamespace(register_commands=Mock(), delete_commands=Mock())
|
|
event = SimpleNamespace(
|
|
event_data=CommandRegisterEventData(
|
|
commands={"/sites": {"description": "管理站点"}},
|
|
origin="DiscordFilter",
|
|
service="discord-main",
|
|
cancel=True,
|
|
)
|
|
)
|
|
|
|
with (
|
|
patch.object(
|
|
module,
|
|
"get_configs",
|
|
return_value={"discord-main": SimpleNamespace(name="discord-main", config={})},
|
|
),
|
|
patch.object(module, "get_instance", return_value=client),
|
|
patch("app.modules.discord.eventmanager.send_event", return_value=event),
|
|
):
|
|
module.register_commands({"/sites": {"description": "管理站点"}})
|
|
|
|
client.delete_commands.assert_called_once_with()
|
|
client.register_commands.assert_not_called()
|
|
|
|
|
|
def test_discord_normalizes_slash_command_names():
|
|
"""Discord 命令名称应符合平台只允许小写字母数字下划线连字符的约束。"""
|
|
assert Discord._normalize_slash_command_name("/sites") == "sites"
|
|
assert Discord._normalize_slash_command_name("/clear_cache") == "clear_cache"
|
|
assert Discord._normalize_slash_command_name("/INVALID") == "invalid"
|
|
assert Discord._normalize_slash_command_name("/中文") == ""
|
|
assert Discord._normalize_slash_command_name("/" + "a" * 33) == ""
|
|
|
|
|
|
def test_discord_handle_slash_command_forwards_to_message_chain():
|
|
"""Discord 斜杠命令回调应转发为统一消息入口可识别的命令文本。"""
|
|
client = Discord.__new__(Discord)
|
|
client._update_user_chat_mapping = Mock()
|
|
client._post_to_ds = AsyncMock()
|
|
|
|
user = SimpleNamespace(id=10001, display_name="tester", global_name=None, name="tester")
|
|
channel = SimpleNamespace(id=20001)
|
|
interaction = SimpleNamespace(
|
|
id=30001,
|
|
user=user,
|
|
channel=channel,
|
|
response=SimpleNamespace(
|
|
defer=AsyncMock(),
|
|
is_done=Mock(return_value=True),
|
|
send_message=AsyncMock(),
|
|
),
|
|
followup=SimpleNamespace(send=AsyncMock()),
|
|
)
|
|
|
|
asyncio.run(client._handle_slash_command(interaction, "/sites", "refresh"))
|
|
|
|
client._update_user_chat_mapping.assert_called_once_with("10001", "20001")
|
|
client._post_to_ds.assert_awaited_once_with(
|
|
{
|
|
"type": "message",
|
|
"userid": "10001",
|
|
"username": "tester",
|
|
"user_tag": str(user),
|
|
"text": "/sites refresh",
|
|
"message_id": "30001",
|
|
"chat_id": "20001",
|
|
"channel_type": "guild",
|
|
}
|
|
)
|
|
interaction.followup.send.assert_awaited_once_with(
|
|
"命令已提交,请稍等...",
|
|
ephemeral=True,
|
|
)
|