From 017426501caf4b9fc4c0ae465f1e5edf12875dd7 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 22 Nov 2024 11:20:55 +0800 Subject: [PATCH] fix: test --- astrbot/bootstrap.py | 5 +++ tests/mocks/onebot.py | 6 +-- tests/test_http_server.py | 51 ----------------------- tests/test_message.py | 88 ++++++++++++++++++++++++++++++++------- 4 files changed, 82 insertions(+), 68 deletions(-) delete mode 100644 tests/test_http_server.py diff --git a/astrbot/bootstrap.py b/astrbot/bootstrap.py index c47b30349..ceeff0877 100644 --- a/astrbot/bootstrap.py +++ b/astrbot/bootstrap.py @@ -1,6 +1,7 @@ import asyncio import traceback import os +import threading from astrbot.message.handler import MessageHandler from astrbot.db.sqlite import SQLiteDatabase from dashboard.server import AstrBotDashboard @@ -82,6 +83,10 @@ class AstrBotBootstrap(): dashboard_server_task = asyncio.create_task(self.dashboard.run(), name="dashboard") if self.test_mode: + def run_dashboard(): + asyncio.run(self.dashboard.run()) + dashboard_thread = threading.Thread(target=run_dashboard, name="dashboard_thread", daemon=False) + dashboard_thread.start() return # load plugins, plugins' commands. diff --git a/tests/mocks/onebot.py b/tests/mocks/onebot.py index 1b204c507..eed5b0193 100644 --- a/tests/mocks/onebot.py +++ b/tests/mocks/onebot.py @@ -4,8 +4,8 @@ from aiocqhttp import Event class MockOneBotMessage(): def __init__(self): # 这些数据不是敏感的 - self.group_event_sample = Event.from_payload({'self_id': 3430871669, 'user_id': 905617992, 'time': 1723882500, 'message_id': -2147480159, 'message_seq': -2147480159, 'real_id': -2147480159, 'message_type': 'group', 'sender': {'user_id': 905617992, 'nickname': 'Soulter', 'card': '', 'role': 'owner'}, 'raw_message': '[CQ:at,qq=3430871669] just reply me `ok`', 'font': 14, 'sub_type': 'normal', 'message': [{'data': {'qq': '3430871669'}, 'type': 'at'}, {'data': {'text': ' just reply me `ok`'}, 'type': 'text'}], 'message_format': 'array', 'post_type': 'message', 'group_id': 849750470}) - self.friend_event_sample = Event.from_payload({'self_id': 3430871669, 'user_id': 905617992, 'time': 1723882599, 'message_id': -2147480157, 'message_seq': -2147480157, 'real_id': -2147480157, 'message_type': 'private', 'sender': {'user_id': 905617992, 'nickname': 'Soulter', 'card': ''}, 'raw_message': 'just reply me `ok`', 'font': 14, 'sub_type': 'friend', 'message': [{'data': {'text': 'just reply me `ok`'}, 'type': 'text'}], 'message_format': 'array', 'post_type': 'message'}) + self.group_event_sample = Event.from_payload({'self_id': 3430871669, 'user_id': 'test', 'time': 1723882500, 'message_id': -2147480159, 'message_seq': -2147480159, 'real_id': -2147480159, 'message_type': 'group', 'sender': {'user_id': 'test', 'nickname': 'Soulter', 'card': '', 'role': 'owner'}, 'raw_message': '[CQ:at,qq=3430871669] just reply me `ok`', 'font': 14, 'sub_type': 'normal', 'message': [{'data': {'qq': '3430871669'}, 'type': 'at'}, {'data': {'text': ' just reply me `ok`'}, 'type': 'text'}], 'message_format': 'array', 'post_type': 'message', 'group_id': 849750470}) + self.friend_event_sample = Event.from_payload({'self_id': 3430871669, 'user_id': 'test', 'time': 1723882599, 'message_id': -2147480157, 'message_seq': -2147480157, 'real_id': -2147480157, 'message_type': 'private', 'sender': {'user_id': 'test', 'nickname': 'Soulter', 'card': ''}, 'raw_message': 'just reply me `ok`', 'font': 14, 'sub_type': 'friend', 'message': [{'data': {'text': 'just reply me `ok`'}, 'type': 'text'}], 'message_format': 'array', 'post_type': 'message'}) def create_random_group_message(self): return self.group_event_sample @@ -14,5 +14,5 @@ class MockOneBotMessage(): return self.friend_event_sample def create_msg(self, text: str): - self.group_event_sample.message = [{'data': {'qq': '3430871669'}, 'type': 'at'}, {'data': {'text': text}, 'type': 'text'}] + self.group_event_sample.message = [{'data': {'qq': 'test'}, 'type': 'at'}, {'data': {'text': text}, 'type': 'text'}] return self.group_event_sample \ No newline at end of file diff --git a/tests/test_http_server.py b/tests/test_http_server.py deleted file mode 100644 index b26ca1f31..000000000 --- a/tests/test_http_server.py +++ /dev/null @@ -1,51 +0,0 @@ - -import aiohttp -import pytest - -BASE_URL = "http://0.0.0.0:6185/api" - -async def get_url(url): - async with aiohttp.ClientSession() as session: - async with session.get(url) as response: - return await response.json() - -async def post_url(url, data): - async with aiohttp.ClientSession() as session: - async with session.post(url, json=data) as response: - return await response.json() - -class TestHTTPServer: - @pytest.mark.asyncio - async def test_config(self): - configs = await get_url(f"{BASE_URL}/configs") - assert 'data' in configs and 'metadata' in configs['data'] \ - and 'config' in configs['data'] - config = configs['data']['config'] - # test post config - await post_url(f"{BASE_URL}/astrbot-configs", config) - # text post config with invalid data - assert 'rate_limit' in config['platform_settings'] - config['platform_settings']['rate_limit'] = "invalid" - ret = await post_url(f"{BASE_URL}/astrbot-configs", config) - assert 'status' in ret and ret['status'] == 'error' - - @pytest.mark.asyncio - async def test_update(self): - await get_url(f"{BASE_URL}/check_update") - - @pytest.mark.asyncio - async def test_plugins(self): - pname = "astrbot_plugin_bilibili" - url = f"https://github.com/Soulter/{pname}" - - await get_url(f"{BASE_URL}/extensions") - - # test install plugin - await post_url(f"{BASE_URL}/extensions/install", { - "url": url - }) - - # test uninstall plugin - await post_url(f"{BASE_URL}/extensions/uninstall", { - "name": pname - }) \ No newline at end of file diff --git a/tests/test_message.py b/tests/test_message.py index 368d2faa5..e40bd21ed 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -1,4 +1,4 @@ -import asyncio +import asyncio, aiohttp import pytest import os @@ -52,14 +52,6 @@ class TestBasicMessageHandle(): abm = qq_official._parse_from_qqofficial(guild_message, MessageType.GUILD_MESSAGE) ret = await qq_official.handle_msg(abm) print(ret) - - # 有共同性,为了节约开销,不测试频道私聊。 - # @pytest.mark.asyncio - # async def test_qqofficial_private_message(self): - # private_message = MockQQOfficialMessage().create_random_direct_message() - # abm = qq_official._parse_from_qqofficial(private_message, MessageType.FRIEND_MESSAGE) - # ret = await qq_official.handle_msg(abm) - # print(ret) @pytest.mark.asyncio async def test_aiocqhttp_group_message(self): @@ -75,7 +67,7 @@ class TestBasicMessageHandle(): ret = await aiocqhttp.handle_msg(abm) print(ret) -class TestInteralCommandHsandle(): +class TestInteralCommandHandle(): def create(self, text: str): event = MockOneBotMessage().create_msg(text) abm = aiocqhttp.convert_message(event) @@ -140,10 +132,10 @@ class TestInteralCommandHsandle(): await self.fast_test(f"/plugin i {url}") await self.fast_test(f"/plugin u {url}") await self.fast_test(f"/plugin d {pname}") - -class TestLLMChat(): + @pytest.mark.asyncio - async def test_llm_chat(self): + async def test_llm(self): + await self.fast_test("/reset") os.environ["TEST_LLM"] = "on" ret = await llm_provider.text_chat("Just reply `ok`", "test") print(ret) @@ -152,4 +144,72 @@ class TestLLMChat(): ret = await aiocqhttp.handle_msg(abm) print(ret) os.environ["TEST_LLM"] = "off" - \ No newline at end of file + await self.fast_test("/reset") + await self.fast_test("/status") + await self.fast_test("/his") + await self.fast_test("/switch") + await self.fast_test("/set") + await self.fast_test("/set list") + await self.fast_test("/unset") + +BASE_URL = "http://0.0.0.0:6185/api" +class TestHTTPServer: + + async def get_url(self, url): + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + return await response.json(), response.status + + async def post_url(self, url, data): + async with aiohttp.ClientSession() as session: + async with session.post(url, json=data) as response: + return await response.json(), response.status + + @pytest.mark.asyncio + async def test_config(self): + configs, status = await self.get_url(f"{BASE_URL}/config/get") + assert status == 200 + assert 'data' in configs and 'metadata' in configs['data'] \ + and 'config' in configs['data'] + config = configs['data']['config'] + # test post config + await self.post_url(f"{BASE_URL}/config/astrbot/update", config) + # text post config with invalid data + assert 'rate_limit' in config['platform_settings'] + config['platform_settings']['rate_limit'] = "invalid" + ret, status = await self.post_url(f"{BASE_URL}/config/astrbot/update", config) + assert status == 200 + assert 'status' in ret and ret['status'] == 'error' + + @pytest.mark.asyncio + async def test_update(self): + _, status = await self.get_url(f"{BASE_URL}/update/check") + assert status == 200 + + @pytest.mark.asyncio + async def test_stats(self): + _, status = await self.get_url(f"{BASE_URL}/stat/get") + _, status = await self.get_url(f"{BASE_URL}/stat/version") + _, status = await self.get_url(f"{BASE_URL}/stat/start-time") + assert status == 200 + + @pytest.mark.asyncio + async def test_plugins(self): + pname = "astrbot_plugin_bilibili" + url = f"https://github.com/Soulter/{pname}" + + _, status = await self.get_url(f"{BASE_URL}/plugin/get") + + # test install plugin + _, status = await self.post_url(f"{BASE_URL}/plugin/install", { + "url": url + }) + + # test uninstall plugin + _, status = await self.post_url(f"{BASE_URL}/plugin/uninstall", { + "name": pname + }) + + assert status == 200 + + bootstrap.context.running = False