mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-25 03:27:15 +00:00
feat(qqofficial): add markdown reply rendering (#2459)
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
"""Tests for QQ Official keyboard payload helpers."""
|
||||
"""Tests for QQ Official message and keyboard payload helpers."""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import time
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
import langbot_plugin.api.entities.builtin.platform.message as platform_message
|
||||
@@ -99,6 +101,12 @@ def _stream_test_adapter():
|
||||
adapter.bot = MagicMock()
|
||||
adapter.bot.send_stream_msg = AsyncMock(return_value={'id': 'stream-1'})
|
||||
adapter.bot.send_markdown_keyboard = AsyncMock(return_value={'id': 'message-1'})
|
||||
adapter.bot.send_private_text_msg = AsyncMock()
|
||||
adapter.bot.send_group_text_msg = AsyncMock()
|
||||
adapter.bot.send_private_markdown_msg = AsyncMock()
|
||||
adapter.bot.send_group_markdown_msg = AsyncMock()
|
||||
adapter.bot.send_channle_group_text_msg = AsyncMock()
|
||||
adapter.bot.send_channle_private_text_msg = AsyncMock()
|
||||
adapter.ap = None
|
||||
adapter._stream_ctx = {}
|
||||
adapter._stream_ctx_ts = {}
|
||||
@@ -142,6 +150,105 @@ async def test_qq_stream_replace_mode_sends_complete_snapshots():
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_qq_markdown_messages_use_markdown_payloads():
|
||||
requests = []
|
||||
|
||||
def capture_request(request: httpx.Request) -> httpx.Response:
|
||||
requests.append((str(request.url), json.loads(request.content)))
|
||||
return httpx.Response(200, json={})
|
||||
|
||||
client = QQOfficialClient('secret', 'token', 'app-id', AsyncMock())
|
||||
client.access_token = 'access-token'
|
||||
client.access_token_expiry_time = time.time() + 3600
|
||||
client._http_clients[None] = httpx.AsyncClient(transport=httpx.MockTransport(capture_request))
|
||||
|
||||
try:
|
||||
await client.send_private_markdown_msg('user-1', '# Hello', msg_id='message-1', msg_seq=2)
|
||||
await client.send_group_markdown_msg('group-1', '* Hello', event_id='event-1', msg_seq=3)
|
||||
finally:
|
||||
await client.close()
|
||||
|
||||
assert requests == [
|
||||
(
|
||||
'https://api.sgroup.qq.com/v2/users/user-1/messages',
|
||||
{'msg_type': 2, 'markdown': {'content': '# Hello'}, 'msg_seq': 2, 'msg_id': 'message-1'},
|
||||
),
|
||||
(
|
||||
'https://api.sgroup.qq.com/v2/groups/group-1/messages',
|
||||
{'msg_type': 2, 'markdown': {'content': '* Hello'}, 'msg_seq': 3, 'event_id': 'event-1'},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_qq_markdown_rendering_switches_c2c_and_group_text_replies():
|
||||
adapter = _stream_test_adapter()
|
||||
adapter.config = {'enable-markdown-rendering': True}
|
||||
|
||||
await adapter._send_c2c_or_group_text_reply('c2c', 'user-1', '# Hello', msg_id='message-1')
|
||||
await adapter._send_c2c_or_group_text_reply('group', 'group-1', '* Hello', event_id='event-1')
|
||||
|
||||
adapter.bot.send_private_markdown_msg.assert_awaited_once_with(
|
||||
user_openid='user-1',
|
||||
content='# Hello',
|
||||
msg_id='message-1',
|
||||
event_id=None,
|
||||
msg_seq=1,
|
||||
)
|
||||
adapter.bot.send_group_markdown_msg.assert_awaited_once_with(
|
||||
group_openid='group-1',
|
||||
content='* Hello',
|
||||
msg_id=None,
|
||||
event_id='event-1',
|
||||
msg_seq=1,
|
||||
)
|
||||
adapter.bot.send_private_text_msg.assert_not_awaited()
|
||||
adapter.bot.send_group_text_msg.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_qq_markdown_rendering_defaults_to_plain_text_replies():
|
||||
adapter = _stream_test_adapter()
|
||||
adapter.config = {}
|
||||
|
||||
await adapter._send_c2c_or_group_text_reply('c2c', 'user-1', 'Hello')
|
||||
await adapter._send_c2c_or_group_text_reply('group', 'group-1', 'Hello')
|
||||
|
||||
adapter.bot.send_private_text_msg.assert_awaited_once()
|
||||
adapter.bot.send_group_text_msg.assert_awaited_once()
|
||||
adapter.bot.send_private_markdown_msg.assert_not_awaited()
|
||||
adapter.bot.send_group_markdown_msg.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_qq_markdown_rendering_does_not_affect_channel_messages():
|
||||
adapter = _stream_test_adapter()
|
||||
adapter.config = {'enable-markdown-rendering': True}
|
||||
message = platform_message.MessageChain([platform_message.Plain(text='# Hello')])
|
||||
|
||||
channel_source = MagicMock()
|
||||
channel_source.t = 'AT_MESSAGE_CREATE'
|
||||
channel_source.channel_id = 'channel-1'
|
||||
channel_source.d_id = 'message-1'
|
||||
channel_event = MagicMock()
|
||||
channel_event.source_platform_object = channel_source
|
||||
await adapter.reply_message(channel_event, message)
|
||||
|
||||
dm_source = MagicMock()
|
||||
dm_source.t = 'DIRECT_MESSAGE_CREATE'
|
||||
dm_source.guild_id = 'guild-1'
|
||||
dm_source.d_id = 'message-2'
|
||||
dm_event = MagicMock()
|
||||
dm_event.source_platform_object = dm_source
|
||||
await adapter.reply_message(dm_event, message)
|
||||
|
||||
adapter.bot.send_channle_group_text_msg.assert_awaited_once_with('channel-1', '# Hello', 'message-1')
|
||||
adapter.bot.send_channle_private_text_msg.assert_awaited_once_with('guild-1', '# Hello', 'message-2')
|
||||
adapter.bot.send_private_markdown_msg.assert_not_awaited()
|
||||
adapter.bot.send_group_markdown_msg.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_qq_non_streaming_fallback_keeps_latest_snapshot_only():
|
||||
from langbot.pkg.platform.sources.qqofficial import QQOfficialAdapter
|
||||
|
||||
Reference in New Issue
Block a user