from __future__ import annotations from datetime import datetime from types import SimpleNamespace from unittest.mock import AsyncMock import pytest @pytest.mark.parametrize( ("text", "expected"), [ ("封禁", ("/ban", ["ban"])), ("解封", ("/unban", ["unban"])), ("禁言", ("/mute", ["mute"])), ("解除禁言", ("/unmute", ["unmute"])), ("警告", ("/warn", ["warn"])), ("禁言10分钟", ("/tmute 10m", ["tmute", "10m"])), (" 禁言1分钟 ", ("/tmute 1m", ["tmute", "1m"])), ("禁言1分钟", ("/tmute 1m", ["tmute", "1m"])), ("禁言\u200b1分钟", ("/tmute 1m", ["tmute", "1m"])), ("禁言 2 小时", ("/tmute 2h", ["tmute", "2h"])), ("禁言1天", ("/tmute 1d", ["tmute", "1d"])), ("踢出", ("/kick", ["kick"])), ("踢", ("/kick", ["kick"])), ("飞", ("/kick", ["kick"])), ], ) def test_member_action_shortcut_parser(app_modules, text, expected): shortcuts = app_modules.load("wbb.services.member_shortcuts") assert shortcuts.member_action_shortcut_command(text) == expected @pytest.mark.parametrize("text", ["禁言0分钟", "禁言100分钟", "封禁 原因", "踢他"]) def test_member_action_shortcut_rejects_ambiguous_text(app_modules, text): shortcuts = app_modules.load("wbb.services.member_shortcuts") assert shortcuts.member_action_shortcut_command(text) is None @pytest.mark.asyncio async def test_member_action_shortcut_executes_temporary_mute( app_modules, monkeypatch ): admin = app_modules.load("wbb.modules.admin") chat_id = -100123 actor_id = 10 target_id = 20 privileges = SimpleNamespace( can_post_messages=False, can_edit_messages=False, can_delete_messages=True, can_restrict_members=True, can_promote_members=False, can_change_info=False, can_invite_users=False, can_pin_messages=False, can_manage_video_chats=False, ) app_modules.app.members[(chat_id, actor_id)] = SimpleNamespace( privileges=privileges ) app_modules.app.get_users = AsyncMock( return_value=SimpleNamespace(mention="@target") ) monkeypatch.setattr(admin, "list_admins", AsyncMock(return_value=[])) restrict_member = AsyncMock() target_reply = AsyncMock() replied_message = SimpleNamespace( from_user=SimpleNamespace(id=target_id), sender_chat=None, reply_text=target_reply, ) message = SimpleNamespace( text=" 禁言1分钟\u200b ", command=None, chat=SimpleNamespace(id=chat_id, restrict_member=restrict_member), from_user=SimpleNamespace(id=actor_id, mention="@admin"), sender_chat=None, reply_to_message=replied_message, reply_text=AsyncMock(), ) assert await admin._member_action_shortcut_filter(None, None, message) await admin.member_action_shortcut(None, message) restrict_member.assert_awaited_once() args, kwargs = restrict_member.await_args assert args == (target_id,) assert kwargs["until_date"] > datetime.now() assert message.text == " 禁言1分钟\u200b " assert message.command is None assert "禁言时长:** 1m" in target_reply.await_args.args[0]