Files
AstrBot/tests_v4/test_events.py
whatevertogo 9c5ecf0a13 feat: Enhance plugin capability support and legacy compatibility
- Introduced LoadedCapability class to manage plugin capabilities.
- Updated load_plugin function to discover and load capabilities alongside handlers.
- Enhanced Peer class to handle remote provided capabilities during initialization.
- Added tests for capability registration and invocation in legacy plugins.
- Improved MessageChain and message component handling in legacy plugins.
- Added comprehensive tests for legacy plugin integration and compatibility.
- Updated protocol messages to include provided capabilities in initialization.
- Enhanced top-level module imports to include capability-related functions.
2026-03-13 06:16:57 +08:00

141 lines
4.5 KiB
Python

"""
Unit tests for Events module.
"""
from __future__ import annotations
import pytest
from astrbot_sdk.events import MessageEvent, PlainTextResult
class TestMessageEvent:
"""Tests for MessageEvent."""
def test_from_payload_creates_event(self):
"""from_payload() should create a MessageEvent from dict."""
payload = {
"text": "hello world",
"session_id": "session-1",
"user_id": "user-1",
"platform": "test",
}
event = MessageEvent.from_payload(payload)
assert event.text == "hello world"
assert event.session_id == "session-1"
assert event.user_id == "user-1"
assert event.platform == "test"
def test_from_payload_handles_missing_fields(self):
"""from_payload() should handle missing optional fields."""
payload = {"text": "test"}
event = MessageEvent.from_payload(payload)
assert event.text == "test"
assert event.session_id == "" # Falls back to empty string
assert event.user_id is None # Optional field
def test_from_payload_preserves_raw_payload(self):
"""from_payload() should preserve raw payload."""
payload = {
"text": "test",
"extra_field": "extra_value",
}
event = MessageEvent.from_payload(payload)
assert event.raw == payload
assert event.raw["extra_field"] == "extra_value"
def test_from_payload_reads_target_shape(self):
"""from_payload() should derive session/platform from structured target payload."""
event = MessageEvent.from_payload(
{
"text": "hello",
"target": {
"conversation_id": "session-1",
"platform": "test-platform",
},
}
)
assert event.session_id == "session-1"
assert event.platform == "test-platform"
@pytest.mark.asyncio
async def test_bind_reply_handler(self):
"""bind_reply_handler() should enable reply functionality."""
event = MessageEvent(text="hello", session_id="s1")
replies = []
async def capture_reply(text: str) -> None:
replies.append(text)
event.bind_reply_handler(capture_reply)
await event.reply("response")
assert replies == ["response"]
@pytest.mark.asyncio
async def test_reply_without_handler_raises(self):
"""reply() without bound handler should raise."""
event = MessageEvent(text="hello", session_id="s1")
with pytest.raises(RuntimeError, match="未绑定 reply handler"):
await event.reply("response")
def test_to_payload(self):
"""to_payload() should serialize event to dict."""
event = MessageEvent(
text="hello",
session_id="session-1",
user_id="user-1",
platform="test",
)
payload = event.to_payload()
assert payload["text"] == "hello"
assert payload["session_id"] == "session-1"
assert payload["user_id"] == "user-1"
assert payload["platform"] == "test"
assert payload["target"]["conversation_id"] == "session-1"
def test_to_payload_preserves_extra_raw_fields(self):
"""to_payload() should preserve unmodeled raw fields during round-trip."""
event = MessageEvent.from_payload(
{
"text": "hello",
"session_id": "session-1",
"trace_id": "trace-123",
}
)
event.text = "updated"
payload = event.to_payload()
assert payload["trace_id"] == "trace-123"
assert payload["text"] == "updated"
def test_plain_result_createsPlainTextResult(self):
"""plain_result() should create PlainTextResult."""
event = MessageEvent(text="hello", session_id="s1")
result = event.plain_result("test output")
assert isinstance(result, PlainTextResult)
assert result.text == "test output"
class TestPlainTextResult:
"""Tests for PlainTextResult."""
def test_create_plain_text_result(self):
"""Should create PlainTextResult."""
result = PlainTextResult(text="hello")
assert result.text == "hello"
def test_plain_text_result_is_dataclass(self):
"""PlainTextResult should be a dataclass with slots."""
result = PlainTextResult(text="test")
# It's a dataclass, check attribute access works
assert result.text == "test"