"""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"