866e546b59
* feat: 将kook适配器插件并入astrbot官方适配器目录中 * refactor: 重命名函数名为 _warp_message * refactor: 使用Protocol替换Union类型 * bugfix: 修复base64前缀处理问题 * refactor: 抛出的错误不再包含"[kook]" * refactor: 添加读取本地文件时的路径安全检查 * refactor: 卡片消息解析失败时会打印错误信息 * refactor: 添加处理接收卡片消息内的图片url时的安全校验 * refactor: 安全处理ws需要重连的情况 * Revert "refactor: 使用Protocol替换Union类型" This reverts commit 58e0dceeb20c3d7dddb16f623fd3bbdcfa632173. * feat: 添加获取机器人名称的实现 * refactor: 让send_by_session发送主动消息时正确传入当前消息链的文本消息内容 * refactor: 统一处理适配器配置相关内容,处理仪表盘出传入配置,并添加仪表盘的kook适配器配置页面的i18n文本 * unittest: 添加kook适配器的单元测试,虽然没覆盖多少单测 * unittest: TEST_DATA_DIR用更安全的路径 * refactor: KookConfig使用了更好的默认值处理方式 * refactor: 移除kook_adapter 的config字段重复定义 * refactor: 隐藏获取kook gateway时url里的token,防止把token打印出来 * refactor: KookConfig.pretty_jsons使用*来屏蔽token内容 * bugfix: 修复主动发送消息时,调用了父方法`send_by_session`可能导致指标被重复上传的bug * refactor: 优化upload_asset的路径处理报错 * bugfix: 修复kook ws心跳间隔可能会出现负数时间的bug * refactor: KookClient移到KookPlatformAdapter.__init__里初始化 * bugfix: 修复处理base64 url 多替换了/而报错的bug * refactor: kook适配器上传文件失败时,会抛出错误 * chore: 移除一条注释 * refactor: 移除没用的return * refactor: 即使消息链中有消息发送失败了,也尽可能将其他消息发送出去,并把报错信息也发送出去 * refactor: 增强上传任务失败时的错误处理,使其发生错误时尽力而为发送其余消息 * refactor: 发送到消息频道的报错消息加了个⚠️,小巧思这块? * refactor: 咱们在写适配器啊,要什么小巧思呢,小巧思给上游插件开发弄不好么) * refactor: enhance Kook adapter with kmarkdown parsing and improve file URL handling * refactor: extract card message parsing logic into a separate method * feat: add kook_bot_nickname configuration to ignore messages from specific nicknames * refactor: remove commented-out code and clean up file upload error handling * fix: remove redundant prefix handling for file URLs in asset upload --------- Co-authored-by: Soulter <905617992@qq.com>
224 lines
5.3 KiB
Python
224 lines
5.3 KiB
Python
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
from astrbot.api.platform import AstrBotMessage, MessageType, PlatformMetadata, Unknown
|
|
from astrbot.api.event import MessageChain
|
|
from astrbot.core.message.components import (
|
|
File,
|
|
Image,
|
|
Plain,
|
|
Video,
|
|
At,
|
|
AtAll,
|
|
BaseMessageComponent,
|
|
Json,
|
|
Record,
|
|
Reply,
|
|
)
|
|
|
|
|
|
from astrbot.core.platform.sources.kook.kook_event import KookEvent
|
|
from astrbot.core.platform.sources.kook.kook_types import KookMessageType, OrderMessage
|
|
|
|
|
|
async def mock_kook_client(upload_asset_return: str, send_text_return: str):
|
|
# 1. Mock 掉整个 KookClient 类
|
|
client = MagicMock()
|
|
|
|
client.upload_asset = AsyncMock(return_value=upload_asset_return)
|
|
client.send_text = AsyncMock(return_value=send_text_return)
|
|
return client
|
|
|
|
|
|
def mock_file_message(input: str):
|
|
message = MagicMock(spec=File)
|
|
message.get_file = AsyncMock(return_value=input)
|
|
return message
|
|
|
|
|
|
def mock_record_message(input: str):
|
|
message = MagicMock(spec=Record)
|
|
message.text = input
|
|
message.convert_to_file_path = AsyncMock(return_value=input)
|
|
return message
|
|
|
|
|
|
def mock_astrbot_message():
|
|
message = AstrBotMessage()
|
|
message.type = MessageType.OTHER_MESSAGE
|
|
message.group_id = "test"
|
|
message.session_id = "test"
|
|
message.message_id = "test"
|
|
return message
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
"input_message,upload_asset_return, expected_output, expected_error",
|
|
[
|
|
(
|
|
Image("test image"),
|
|
"test image",
|
|
OrderMessage(
|
|
1,
|
|
text="test image",
|
|
type=KookMessageType.IMAGE,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
Video("test video"),
|
|
"test video",
|
|
OrderMessage(
|
|
1,
|
|
text="test video",
|
|
type=KookMessageType.VIDEO,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
mock_file_message("test file"),
|
|
"test file",
|
|
OrderMessage(
|
|
1,
|
|
text="test file",
|
|
type=KookMessageType.FILE,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
mock_record_message("./tests/file.wav"),
|
|
"./tests/file.wav",
|
|
OrderMessage(
|
|
1,
|
|
text='[{"type": "card", "modules": [{"src": "./tests/file.wav", "title": "./tests/file.wav", "type": "audio"}]}]',
|
|
type=KookMessageType.CARD,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
Plain("test plain"),
|
|
"test plain",
|
|
OrderMessage(
|
|
1,
|
|
text="test plain",
|
|
type=KookMessageType.KMARKDOWN,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
At(qq="test at"),
|
|
"test at",
|
|
OrderMessage(
|
|
1,
|
|
text="(met)test at(met)",
|
|
type=KookMessageType.KMARKDOWN,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
AtAll(qq="all"),
|
|
"test atAll",
|
|
OrderMessage(
|
|
1,
|
|
text="(met)all(met)",
|
|
type=KookMessageType.KMARKDOWN,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
Reply(id="test reply"),
|
|
"test reply",
|
|
OrderMessage(
|
|
1,
|
|
text="",
|
|
type=KookMessageType.KMARKDOWN,
|
|
reply_id="test reply",
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
Json(data={"test": "json"}),
|
|
"test json",
|
|
OrderMessage(
|
|
1,
|
|
text='[{"test": "json"}]',
|
|
type=KookMessageType.CARD,
|
|
),
|
|
None,
|
|
),
|
|
(
|
|
Unknown(text="test unknown"),
|
|
"test unknown",
|
|
None,
|
|
NotImplementedError,
|
|
),
|
|
],
|
|
)
|
|
async def test_kook_event_warp_message(
|
|
input_message: BaseMessageComponent,
|
|
upload_asset_return: str,
|
|
expected_output: OrderMessage,
|
|
expected_error: type[Exception] | None,
|
|
):
|
|
client = await mock_kook_client(
|
|
upload_asset_return,
|
|
"",
|
|
)
|
|
|
|
event = KookEvent(
|
|
"",
|
|
mock_astrbot_message(),
|
|
PlatformMetadata(
|
|
name="test",
|
|
id="test",
|
|
description="test",
|
|
),
|
|
"",
|
|
client,
|
|
)
|
|
|
|
if expected_error:
|
|
with pytest.raises(expected_error):
|
|
await event._wrap_message(1, input_message)
|
|
return
|
|
|
|
result = await event._wrap_message(1, input_message)
|
|
assert result == expected_output
|
|
|
|
|
|
# @pytest.mark.asyncio
|
|
# @pytest.mark.parametrize(
|
|
# "message_chain,send_text_expected_output,expected_error",
|
|
# [
|
|
# (
|
|
# MessageChain(
|
|
# chain=[
|
|
# Image(file="test image"),
|
|
# Plain(text="test plain"),
|
|
# ],
|
|
# ),
|
|
# ""
|
|
# ),
|
|
# ],
|
|
# )
|
|
# async def test_kook_event_send():
|
|
# client = await mock_kook_client(
|
|
# "",
|
|
# "",
|
|
# )
|
|
|
|
# event = KookEvent(
|
|
# "",
|
|
# mock_astrbot_message(),
|
|
# PlatformMetadata(
|
|
# name="test",
|
|
# id="test",
|
|
# description="test",
|
|
# ),
|
|
# "",
|
|
# client,
|
|
# )
|
|
|
|
# await event.send(message=mock_astrbot_message())
|