91 lines
2.7 KiB
Python
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"
|