ForcePilot/backend/test/unit/channels/test_wechat_security.py

225 lines
8.6 KiB
Python
Raw Normal View History

from __future__ import annotations
import pytest
from yuxi.channels.adapters.wechat.security import (
check_dm_policy,
check_group_policy,
is_bot_mentioned,
should_require_mention,
)
from yuxi.channels.adapters.wechat.security import WeChatSecurityAdapter
class TestCheckDmPolicy:
def test_open_policy_allows(self):
assert check_dm_policy({"dm_policy": "open"}, "user123") is True
def test_disabled_policy_denies(self):
assert check_dm_policy({"dm_policy": "disabled"}, "user123") is False
def test_allowlist_user_in_list(self):
config = {"dm_policy": "allowlist", "allow_from": ["wx:user123"]}
assert check_dm_policy(config, "user123") is True
def test_allowlist_user_not_in_list(self):
config = {"dm_policy": "allowlist", "allow_from": ["wx:other"]}
assert check_dm_policy(config, "other_user") is False
def test_allowlist_empty(self):
config = {"dm_policy": "allowlist", "allow_from": []}
assert check_dm_policy(config, "anyone") is False
def test_unknown_policy_denies(self):
assert check_dm_policy({"dm_policy": "unknown_policy"}, "user") is False
def test_no_policy_defaults_to_open(self):
assert check_dm_policy({}, "user") is True
class TestCheckGroupPolicy:
def test_open_policy(self):
config = {"group_policy": "open"}
assert check_group_policy(config, "chat1", "user1") is True
def test_disabled_policy(self):
config = {"group_policy": "disabled"}
assert check_group_policy(config, "chat1", "user1") is False
def test_global_allowlist_match(self):
config = {"group_policy": "allowlist", "group_allow_from": ["wx:user1"]}
assert check_group_policy(config, "chat1", "user1") is True
def test_global_allowlist_no_match(self):
config = {"group_policy": "allowlist", "group_allow_from": ["wx:other"]}
assert check_group_policy(config, "chat1", "user1") is False
def test_per_group_allowlist_match(self):
config = {
"group_policy": "allowlist",
"groups": {"chat1": {"allow_from": ["wx:user1"]}},
}
assert check_group_policy(config, "chat1", "user1") is True
def test_per_group_allowlist_no_match(self):
config = {
"group_policy": "allowlist",
"groups": {"chat1": {"allow_from": ["wx:other"]}},
}
assert check_group_policy(config, "chat1", "user1") is False
def test_no_policy(self):
assert check_group_policy({}, "chat1", "user1") is False
class TestIsBotMentioned:
def test_wecom_with_at_and_name(self):
config = {"agent_name": "小助手"}
payload = {"Content": "@小助手 你好"}
assert is_bot_mentioned(config, payload, "wecom") is True
def test_wecom_at_only_no_name(self):
config = {"agent_name": "小助手"}
payload = {"Content": "@someone 你好"}
assert is_bot_mentioned(config, payload, "wecom") is True
def test_wecom_no_at(self):
config = {"agent_name": "小助手"}
payload = {"Content": "你好"}
assert is_bot_mentioned(config, payload, "wecom") is False
def test_wecom_empty_content(self):
config = {"agent_name": "小助手"}
payload = {"Content": ""}
assert is_bot_mentioned(config, payload, "wecom") is False
def test_mp_with_at(self):
config = {}
payload = {"Content": "@bot help"}
assert is_bot_mentioned(config, payload, "mp") is True
def test_mp_without_at(self):
config = {}
payload = {"Content": "help"}
assert is_bot_mentioned(config, payload, "mp") is False
def test_personal_with_at_list(self):
config = {}
payload = {"at_list": ["user1"]}
assert is_bot_mentioned(config, payload, "personal") is True
def test_personal_empty_at_list(self):
config = {}
payload = {"at_list": []}
assert is_bot_mentioned(config, payload, "personal") is False
def test_unknown_mode(self):
assert is_bot_mentioned({}, {}, "unknown") is False
class TestShouldRequireMention:
def test_group_requires_mention_default(self):
config = {"groups": {"chat1": {}}}
assert should_require_mention(config, "chat1") is True
def test_group_requires_mention_explicit_true(self):
config = {"groups": {"chat1": {"require_mention": True}}}
assert should_require_mention(config, "chat1") is True
def test_group_requires_mention_explicit_false(self):
config = {"groups": {"chat1": {"require_mention": False}}}
assert should_require_mention(config, "chat1") is False
def test_group_not_configured(self):
assert should_require_mention({}, "nonexistent") is True
class TestWeChatSecurityAdapter:
def test_resolve_dm_policy_default(self):
result = WeChatSecurityAdapter.resolve_dm_policy({})
assert result == "pairing"
def test_resolve_dm_policy_from_root(self):
result = WeChatSecurityAdapter.resolve_dm_policy({"dm_policy": "allowlist"})
assert result == "allowlist"
def test_resolve_dm_policy_from_account(self):
config = {"accounts": {"acc1": {"dm_policy": "open"}}}
result = WeChatSecurityAdapter.resolve_dm_policy(config, "acc1")
assert result == "open"
def test_resolve_dm_policy_account_not_found_falls_back(self):
config = {"dm_policy": "disabled", "accounts": {}}
result = WeChatSecurityAdapter.resolve_dm_policy(config, "missing")
assert result == "disabled"
def test_resolve_dm_allow_from_root(self):
result = WeChatSecurityAdapter.resolve_dm_allow_from({"allow_from": ["wx:a"]})
assert result == ["wx:a"]
def test_resolve_dm_allow_from_account(self):
config = {"accounts": {"acc1": {"allow_from": ["wx:b"]}}}
result = WeChatSecurityAdapter.resolve_dm_allow_from(config, "acc1")
assert result == ["wx:b"]
def test_resolve_dm_allow_from_empty(self):
assert WeChatSecurityAdapter.resolve_dm_allow_from({}) == []
def test_resolve_group_policy_default(self):
assert WeChatSecurityAdapter.resolve_group_policy({}) == "allowlist"
def test_resolve_group_policy_from_account(self):
config = {"accounts": {"acc1": {"group_policy": "open"}}}
result = WeChatSecurityAdapter.resolve_group_policy(config, "acc1")
assert result == "open"
def test_resolve_group_allow_from_combined(self):
config = {
"group_allow_from": ["wx:global"],
"groups": {"chat1": {"allow_from": ["wx:local"]}},
}
result = WeChatSecurityAdapter.resolve_group_allow_from(config, "chat1")
assert "wx:global" in result
assert "wx:local" in result
def test_resolve_group_allow_from_no_duplicates(self):
config = {
"group_allow_from": ["wx:a"],
"groups": {"chat1": {"allow_from": ["wx:a", "wx:b"]}},
}
result = WeChatSecurityAdapter.resolve_group_allow_from(config, "chat1")
assert result.count("wx:a") == 1
assert "wx:b" in result
def test_collect_warnings_open_dm_policy(self):
warnings = WeChatSecurityAdapter.collect_warnings({"dm_policy": "open"})
assert any("dm_policy='open'" in w for w in warnings)
def test_collect_warnings_empty_allowlist(self):
warnings = WeChatSecurityAdapter.collect_warnings({"dm_policy": "allowlist", "allow_from": []})
assert any("allowlist 为空" in w for w in warnings)
def test_collect_warnings_empty_group_allowlist(self):
warnings = WeChatSecurityAdapter.collect_warnings({"group_policy": "allowlist"})
assert any("群组 allowlist 为空" in w for w in warnings)
def test_collect_warnings_no_pairing(self):
warnings = WeChatSecurityAdapter.collect_warnings({"dm_policy": "open"})
assert any("配对机制" in w for w in warnings)
def test_collect_warnings_with_pairing_ok(self):
warnings = WeChatSecurityAdapter.collect_warnings({
"dm_policy": "pairing",
"accounts": {"acc1": {"dm_policy": "pairing"}},
})
assert not any("配对机制" in w for w in warnings)
def test_collect_audit_findings_normal(self):
findings = WeChatSecurityAdapter.collect_audit_findings({"allow_from": ["wx:a"]})
assert len(findings) == 0
def test_collect_audit_findings_large_allowlist(self):
large_list = [f"wx:{i}" for i in range(2000)]
findings = WeChatSecurityAdapter.collect_audit_findings({"allow_from": large_list})
assert len(findings) > 0
assert findings[0]["category"] == "allowlist_size"