ForcePilot/backend/test/unit/channels/test_channels_feishu_p0.py
Kris 3264900bc9 test: 新增多渠道单元测试用例并配置测试环境变量
新增了Twitch、Telegram、Discord、Slack、Mattermost、WeChat、Zalo等多渠道的单元测试用例,覆盖了令牌处理、速率限制、消息去重、会话解析、格式转换、安全策略等模块
同时在测试配置中添加了测试用的OpenAI API密钥环境变量
2026-05-12 00:56:47 +08:00

122 lines
4.4 KiB
Python

"""P0优化验证测试: dedup, merge_text, media validation, button styles"""
import hashlib
from yuxi.channels.adapters.feishu.cards import resolve_button_type
from yuxi.channels.adapters.feishu.dedup import FeishuDedupStore
from yuxi.channels.adapters.feishu.media import MediaSizeError, validate_media_size
from yuxi.channels.adapters.feishu.stream import merge_streaming_text
from yuxi.channels.adapters.feishu.verify import check_webhook_rate_limit, verify_and_decrypt_webhook
class TestFeishuP0Enhancements:
def test_dedup_has_processed(self):
store = FeishuDedupStore()
event = {
"event": {"message": {"message_id": "msg1"}, "event_id": "evt1"},
"event_type": "im.message.receive_v1",
}
assert not store.has_processed(event)
store.record_processed(event)
assert store.has_processed(event)
store.finalize_processing(event)
assert store.has_processed(event)
def test_dedup_different_events(self):
store = FeishuDedupStore()
event1 = {
"event": {"message": {"message_id": "msg1"}, "event_id": "evt1"},
"event_type": "im.message.receive_v1",
}
event2 = {
"event": {"message": {"message_id": "msg2"}, "event_id": "evt2"},
"event_type": "im.message.receive_v1",
}
store.finalize_processing(event1)
assert store.has_processed(event1)
assert not store.has_processed(event2)
def test_rate_limit_enforced(self):
for _ in range(1000):
assert check_webhook_rate_limit("test_ip_limit")
assert not check_webhook_rate_limit("test_ip_limit")
def test_merge_startswith(self):
assert merge_streaming_text("", "Hello") == "Hello"
assert merge_streaming_text("Hello", "Hello World") == "Hello World"
def test_merge_existing_contains_prefix(self):
assert merge_streaming_text("Hello World", "Hello") == "Hello World"
def test_merge_concatenation(self):
assert merge_streaming_text("Hello, ", "World") == "Hello, World"
def test_merge_with_prefix_overlap(self):
assert merge_streaming_text("today is", "is lovely") == "today is lovely"
def test_media_size_valid(self):
validate_media_size(b"x" * 512, max_mb=1)
def test_media_size_invalid(self):
try:
validate_media_size(b"x" * (2 * 1024 * 1024), max_mb=1)
assert False, "Should have raised MediaSizeError"
except MediaSizeError:
pass
def test_button_type_default(self):
assert resolve_button_type(None) == "default"
assert resolve_button_type("") == "default"
def test_button_type_primary(self):
assert resolve_button_type("primary") == "primary"
def test_button_type_danger(self):
assert resolve_button_type("danger") == "danger"
def test_button_type_unknown(self):
assert resolve_button_type("unknown") == "default"
def test_verify_signature_ok(self):
body = b"{test: true}"
ts = "1234567890"
nonce = "abc"
key = "secret"
raw = f"{ts}{nonce}{key}".encode() + body
sig = hashlib.sha256(raw).hexdigest()
headers = {
"X-Lark-Request-Timestamp": ts,
"X-Lark-Request-Nonce": nonce,
"X-Lark-Signature": sig,
}
ok, result_body, status = verify_and_decrypt_webhook(headers, body, key, "test_p0_verify")
assert ok
assert status == "ok"
assert result_body == body
def test_verify_signature_bad(self):
body = b"{test: true}"
headers = {
"X-Lark-Request-Timestamp": "bad",
"X-Lark-Request-Nonce": "bad",
"X-Lark-Signature": "bad",
}
ok, result_body, status = verify_and_decrypt_webhook(headers, body, "", "test_p0_verify2")
assert not ok
assert status == "signature_mismatch"
def test_oversized_body_rejected(self):
huge_body = b"x" * (11 * 1024 * 1024)
ts = "1234567890"
nonce = "abc"
key = "secret"
raw = f"{ts}{nonce}{key}".encode() + huge_body
sig = hashlib.sha256(raw).hexdigest()
headers = {
"X-Lark-Request-Timestamp": ts,
"X-Lark-Request-Nonce": nonce,
"X-Lark-Signature": sig,
}
ok, _, status = verify_and_decrypt_webhook(headers, huge_body, key, "test_p0_size")
assert not ok
assert status == "signature_mismatch"