Files
2026-07-13 13:12:33 +08:00

91 lines
2.7 KiB
Python

from __future__ import annotations
import asyncio
from types import SimpleNamespace
from typing import Any
from unittest.mock import AsyncMock
from opensquilla.channels.qq import QQChannel, QQChannelConfig
def _make_channel() -> QQChannel:
return QQChannel(QQChannelConfig(name="qq", app_id="app-id", app_secret="app-secret"))
def _raw_c2c(msg_id: str, openid: str, content: str) -> Any:
return SimpleNamespace(
id=msg_id,
author=SimpleNamespace(user_openid=openid),
content=content,
)
def _raw_group(msg_id: str, member_openid: str, group_openid: str, content: str) -> Any:
return SimpleNamespace(
id=msg_id,
author=SimpleNamespace(member_openid=member_openid),
group_openid=group_openid,
content=content,
)
async def test_qq_streaming_reply_kwargs_pin_c2c_target() -> None:
channel = _make_channel()
channel._enqueue_message(_raw_c2c("m-1", "openid-1", "hi"), is_group=False)
msg = await channel.receive()
assert channel.streaming_reply_kwargs(msg) == {
"chat_type": "c2c",
"target": "openid-1",
"msg_id": "m-1",
}
async def test_qq_streaming_reply_kwargs_pin_group_target() -> None:
channel = _make_channel()
channel._enqueue_message(_raw_group("m-2", "member-1", "group-1", "hi"), is_group=True)
msg = await channel.receive()
assert channel.streaming_reply_kwargs(msg) == {
"chat_type": "group",
"target": "group-1",
"msg_id": "m-2",
}
async def test_qq_streamed_reply_targets_sender_even_after_newer_inbound() -> None:
channel = _make_channel()
channel.api = SimpleNamespace(post_c2c_message=AsyncMock(), post_group_message=AsyncMock())
channel._enqueue_message(_raw_c2c("m-a", "openid-a", "question from a"), is_group=False)
msg_a = await channel.receive()
mid_stream = asyncio.Event()
release = asyncio.Event()
async def chunks() -> Any:
yield "answer for a, part 1. "
mid_stream.set()
await release.wait()
yield "part 2."
stream_task = asyncio.create_task(
channel.send_streaming(chunks(), **channel.streaming_reply_kwargs(msg_a))
)
await mid_stream.wait()
# Another user's message is received while A's answer is still streaming.
channel._enqueue_message(_raw_c2c("m-b", "openid-b", "unrelated"), is_group=False)
await channel.receive()
release.set()
await asyncio.wait_for(stream_task, timeout=5)
assert channel.api.post_c2c_message.await_count == 1
kwargs = channel.api.post_c2c_message.await_args.kwargs
assert "answer for a" in kwargs["content"]
assert kwargs["openid"] == "openid-a"
assert kwargs["msg_id"] == "m-a"