diff --git a/tests/builtin_plugins/auto_update/test_check_update.py b/tests/builtin_plugins/auto_update/test_check_update.py index 8a505401..97ee18fa 100644 --- a/tests/builtin_plugins/auto_update/test_check_update.py +++ b/tests/builtin_plugins/auto_update/test_check_update.py @@ -207,7 +207,7 @@ def init_mocker_path(mocker: MockerFixture, tmp_path: Path): ) mocker.patch( - "zhenxun.builtin_plugins.auto_update._data_source.install_requirement", + "zhenxun.utils.manager.virtual_env_package_manager.VirtualEnvPackageManager.install_requirement", return_value=None, ) mock_tmp_path = mocker.patch( diff --git a/tests/builtin_plugins/plugin_store/test_add_plugin.py b/tests/builtin_plugins/plugin_store/test_add_plugin.py index 5a0edab8..1e30f3b1 100644 --- a/tests/builtin_plugins/plugin_store/test_add_plugin.py +++ b/tests/builtin_plugins/plugin_store/test_add_plugin.py @@ -15,7 +15,7 @@ from tests.config import BotId, GroupId, MessageId, UserId from tests.utils import _v11_group_message_event -@pytest.mark.parametrize("package_api", ["jsd", "gh"]) +@pytest.mark.parametrize("package_api", ["gh"]) @pytest.mark.parametrize("is_commit", [True, False]) async def test_add_plugin_basic( package_api: str, @@ -37,18 +37,14 @@ async def test_add_plugin_basic( new=tmp_path / "zhenxun", ) - if package_api != "jsd": - mocked_api["zhenxun_bot_plugins_metadata"].respond(404) - if package_api != "gh": - mocked_api["zhenxun_bot_plugins_tree"].respond(404) - + mocked_api["zhenxun_bot_plugins_metadata"].respond(404) if not is_commit: mocked_api["zhenxun_bot_plugins_commit"].respond(404) mocked_api["zhenxun_bot_plugins_commit_proxy"].respond(404) mocked_api["zhenxun_bot_plugins_index_commit"].respond(404) mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404) - plugin_id = 1 + plugin_id = "search_image" async with app.test_matcher(_matcher) as ctx: bot = create_bot(ctx) @@ -65,7 +61,7 @@ async def test_add_plugin_basic( ctx.receive_event(bot=bot, event=event) ctx.should_call_send( event=event, - message=Message(message=f"正在添加插件 Id: {plugin_id}"), + message=Message(message=f"正在添加插件 Module: {plugin_id}"), result=None, bot=bot, ) @@ -86,7 +82,7 @@ async def test_add_plugin_basic( assert (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file() -@pytest.mark.parametrize("package_api", ["jsd", "gh"]) +@pytest.mark.parametrize("package_api", ["gh"]) @pytest.mark.parametrize("is_commit", [True, False]) async def test_add_plugin_basic_commit_version( package_api: str, @@ -108,17 +104,13 @@ async def test_add_plugin_basic_commit_version( new=tmp_path / "zhenxun", ) - if package_api != "jsd": - mocked_api["zhenxun_bot_plugins_metadata_commit"].respond(404) - if package_api != "gh": - mocked_api["zhenxun_bot_plugins_tree_commit"].respond(404) - + mocked_api["zhenxun_bot_plugins_metadata_commit"].respond(404) if not is_commit: mocked_api["zhenxun_bot_plugins_commit"].respond(404) mocked_api["zhenxun_bot_plugins_commit_proxy"].respond(404) mocked_api["zhenxun_bot_plugins_index_commit"].respond(404) mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404) - plugin_id = 3 + plugin_id = "bilibili_sub" async with app.test_matcher(_matcher) as ctx: bot = create_bot(ctx) @@ -135,7 +127,7 @@ async def test_add_plugin_basic_commit_version( ctx.receive_event(bot=bot, event=event) ctx.should_call_send( event=event, - message=Message(message=f"正在添加插件 Id: {plugin_id}"), + message=Message(message=f"正在添加插件 Module: {plugin_id}"), result=None, bot=bot, ) @@ -159,7 +151,7 @@ async def test_add_plugin_basic_commit_version( assert (mock_base_path / "plugins" / "bilibili_sub" / "__init__.py").is_file() -@pytest.mark.parametrize("package_api", ["jsd", "gh"]) +@pytest.mark.parametrize("package_api", ["gh"]) @pytest.mark.parametrize("is_commit", [True, False]) async def test_add_plugin_basic_is_not_dir( package_api: str, @@ -181,10 +173,7 @@ async def test_add_plugin_basic_is_not_dir( new=tmp_path / "zhenxun", ) - if package_api != "jsd": - mocked_api["zhenxun_bot_plugins_metadata"].respond(404) - if package_api != "gh": - mocked_api["zhenxun_bot_plugins_tree"].respond(404) + mocked_api["zhenxun_bot_plugins_metadata"].respond(404) if not is_commit: mocked_api["zhenxun_bot_plugins_commit"].respond(404) @@ -192,7 +181,7 @@ async def test_add_plugin_basic_is_not_dir( mocked_api["zhenxun_bot_plugins_index_commit"].respond(404) mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404) - plugin_id = 0 + plugin_id = "jitang" async with app.test_matcher(_matcher) as ctx: bot = create_bot(ctx) @@ -209,7 +198,7 @@ async def test_add_plugin_basic_is_not_dir( ctx.receive_event(bot=bot, event=event) ctx.should_call_send( event=event, - message=Message(message=f"正在添加插件 Id: {plugin_id}"), + message=Message(message=f"正在添加插件 Module: {plugin_id}"), result=None, bot=bot, ) @@ -230,7 +219,7 @@ async def test_add_plugin_basic_is_not_dir( assert (mock_base_path / "plugins" / "alapi" / "jitang.py").is_file() -@pytest.mark.parametrize("package_api", ["jsd", "gh"]) +@pytest.mark.parametrize("package_api", ["gh"]) @pytest.mark.parametrize("is_commit", [True, False]) async def test_add_plugin_extra( package_api: str, @@ -252,10 +241,7 @@ async def test_add_plugin_extra( new=tmp_path / "zhenxun", ) - if package_api != "jsd": - mocked_api["zhenxun_github_sub_metadata"].respond(404) - if package_api != "gh": - mocked_api["zhenxun_github_sub_tree"].respond(404) + mocked_api["zhenxun_github_sub_metadata"].respond(404) if not is_commit: mocked_api["zhenxun_github_sub_commit"].respond(404) @@ -265,7 +251,7 @@ async def test_add_plugin_extra( mocked_api["zhenxun_bot_plugins_index_commit"].respond(404) mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404) - plugin_id = 4 + plugin_id = "github_sub" async with app.test_matcher(_matcher) as ctx: bot = create_bot(ctx) @@ -282,7 +268,7 @@ async def test_add_plugin_extra( ctx.receive_event(bot=bot, event=event) ctx.should_call_send( event=event, - message=Message(message=f"正在添加插件 Id: {plugin_id}"), + message=Message(message=f"正在添加插件 Module: {plugin_id}"), result=None, bot=bot, ) @@ -339,7 +325,7 @@ async def test_plugin_not_exist_add( ) ctx.should_call_send( event=event, - message=Message(message="插件ID不存在..."), + message=Message(message="添加插件 Id: -1 失败 e: 插件ID不存在..."), result=None, bot=bot, ) @@ -385,7 +371,9 @@ async def test_add_plugin_exist( ) ctx.should_call_send( event=event, - message=Message(message="插件 识图 已安装,无需重复安装"), + message=Message( + message="添加插件 Id: 1 失败 e: 插件 识图 已安装,无需重复安装" + ), result=None, bot=bot, ) diff --git a/tests/builtin_plugins/plugin_store/test_plugin_store.py b/tests/builtin_plugins/plugin_store/test_plugin_store.py deleted file mode 100644 index 4e8eae16..00000000 --- a/tests/builtin_plugins/plugin_store/test_plugin_store.py +++ /dev/null @@ -1,140 +0,0 @@ -from collections.abc import Callable -from pathlib import Path -from typing import cast - -from nonebot.adapters.onebot.v11 import Bot, Message -from nonebot.adapters.onebot.v11.event import GroupMessageEvent -from nonebug import App -from pytest_mock import MockerFixture -from respx import MockRouter - -from tests.builtin_plugins.plugin_store.utils import init_mocked_api -from tests.config import BotId, GroupId, MessageId, UserId -from tests.utils import _v11_group_message_event - - -async def test_plugin_store( - app: App, - mocker: MockerFixture, - mocked_api: MockRouter, - create_bot: Callable, - tmp_path: Path, -) -> None: - """ - 测试插件商店 - """ - from zhenxun.builtin_plugins.plugin_store import _matcher - from zhenxun.builtin_plugins.plugin_store.data_source import row_style - - init_mocked_api(mocked_api=mocked_api) - - mock_table_page = mocker.patch( - "zhenxun.builtin_plugins.plugin_store.data_source.ImageTemplate.table_page" - ) - mock_table_page_return = mocker.AsyncMock() - mock_table_page.return_value = mock_table_page_return - - mock_build_message = mocker.patch( - "zhenxun.builtin_plugins.plugin_store.MessageUtils.build_message" - ) - mock_build_message_return = mocker.AsyncMock() - mock_build_message.return_value = mock_build_message_return - - async with app.test_matcher(_matcher) as ctx: - bot = create_bot(ctx) - bot: Bot = cast(Bot, bot) - raw_message = "插件商店" - event: GroupMessageEvent = _v11_group_message_event( - message=raw_message, - self_id=BotId.QQ_BOT, - user_id=UserId.SUPERUSER, - group_id=GroupId.GROUP_ID_LEVEL_5, - message_id=MessageId.MESSAGE_ID_3, - to_me=True, - ) - ctx.receive_event(bot=bot, event=event) - mock_table_page.assert_awaited_once_with( - "插件列表", - "通过添加/移除插件 ID 来管理插件", - ["-", "ID", "名称", "简介", "作者", "版本", "类型"], - [ - ["", 0, "鸡汤", "喏,亲手为你煮的鸡汤", "HibiKier", "0.1", "普通插件"], - ["", 1, "识图", "以图搜图,看破本源", "HibiKier", "0.1", "普通插件"], - ["", 2, "网易云热评", "生了个人,我很抱歉", "HibiKier", "0.1", "普通插件"], - [ - "", - 3, - "B站订阅", - "非常便利的B站订阅通知", - "HibiKier", - "0.3-b101fbc", - "普通插件", - ], - [ - "", - 4, - "github订阅", - "订阅github用户或仓库", - "xuanerwa", - "0.7", - "普通插件", - ], - [ - "", - 5, - "Minecraft查服", - "Minecraft服务器状态查询,支持IPv6", - "molanp", - "1.13", - "普通插件", - ], - ], - text_style=row_style, - ) - mock_build_message.assert_called_once_with(mock_table_page_return) - mock_build_message_return.send.assert_awaited_once() - - assert mocked_api["basic_plugins"].called - assert mocked_api["extra_plugins"].called - - -async def test_plugin_store_fail( - app: App, - mocker: MockerFixture, - mocked_api: MockRouter, - create_bot: Callable, - tmp_path: Path, -) -> None: - """ - 测试插件商店 - """ - from zhenxun.builtin_plugins.plugin_store import _matcher - - init_mocked_api(mocked_api=mocked_api) - mocked_api.get( - "https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/b101fbc/plugins.json", - name="basic_plugins", - ).respond(404) - - async with app.test_matcher(_matcher) as ctx: - bot = create_bot(ctx) - bot: Bot = cast(Bot, bot) - raw_message = "插件商店" - event: GroupMessageEvent = _v11_group_message_event( - message=raw_message, - self_id=BotId.QQ_BOT, - user_id=UserId.SUPERUSER, - group_id=GroupId.GROUP_ID_LEVEL_5, - message_id=MessageId.MESSAGE_ID_3, - to_me=True, - ) - ctx.receive_event(bot=bot, event=event) - ctx.should_call_send( - event=event, - message=Message("获取插件列表失败..."), - result=None, - exception=None, - bot=bot, - ) - - assert mocked_api["basic_plugins"].called diff --git a/tests/builtin_plugins/plugin_store/test_remove_plugin.py b/tests/builtin_plugins/plugin_store/test_remove_plugin.py index 4d5e3ab1..fe2f92a9 100644 --- a/tests/builtin_plugins/plugin_store/test_remove_plugin.py +++ b/tests/builtin_plugins/plugin_store/test_remove_plugin.py @@ -96,7 +96,7 @@ async def test_plugin_not_exist_remove( ctx.receive_event(bot=bot, event=event) ctx.should_call_send( event=event, - message=Message(message="插件ID不存在..."), + message=Message(message="移除插件 Id: -1 失败 e: 插件ID不存在..."), result=None, bot=bot, ) diff --git a/tests/builtin_plugins/plugin_store/test_update_plugin.py b/tests/builtin_plugins/plugin_store/test_update_plugin.py index 2cb88d1b..39412de9 100644 --- a/tests/builtin_plugins/plugin_store/test_update_plugin.py +++ b/tests/builtin_plugins/plugin_store/test_update_plugin.py @@ -158,7 +158,7 @@ async def test_plugin_not_exist_update( ) ctx.should_call_send( event=event, - message=Message(message="插件ID不存在..."), + message=Message(message="更新插件 Id: -1 失败 e: 插件ID不存在..."), result=None, bot=bot, ) @@ -200,7 +200,9 @@ async def test_update_plugin_not_install( ) ctx.should_call_send( event=event, - message=Message(message="插件 识图 未安装,无法更新"), + message=Message( + message="更新插件 Id: 1 失败 e: 插件 识图 未安装,无法更新" + ), result=None, bot=bot, ) diff --git a/zhenxun/builtin_plugins/auto_update/_data_source.py b/zhenxun/builtin_plugins/auto_update/_data_source.py index b591acea..eca520d3 100644 --- a/zhenxun/builtin_plugins/auto_update/_data_source.py +++ b/zhenxun/builtin_plugins/auto_update/_data_source.py @@ -161,7 +161,6 @@ class UpdateManager: logger.debug(f"恢复旧的webui文件夹 {BACKUP_PATH}", COMMAND) BACKUP_PATH.rename(WEBUI_PATH) raise e - return "" @classmethod async def check_version(cls) -> str: diff --git a/zhenxun/builtin_plugins/plugin_store/data_source.py b/zhenxun/builtin_plugins/plugin_store/data_source.py index b952c9a8..4bb3b64f 100644 --- a/zhenxun/builtin_plugins/plugin_store/data_source.py +++ b/zhenxun/builtin_plugins/plugin_store/data_source.py @@ -164,7 +164,7 @@ class StoreManager: @classmethod async def get_plugin_by_value( cls, index_or_module: str, is_update: bool = False - ) -> StorePluginInfo: + ) -> tuple[StorePluginInfo, bool]: """获取插件信息 参数: @@ -177,19 +177,30 @@ class StoreManager: 返回: StorePluginInfo: 插件信息 + bool: 是否是外部插件 """ plugin_list, extra_plugin_list = await cls.get_data() - all_plugin_list = plugin_list + extra_plugin_list + plugin_info = None + is_external = False db_plugin_list = await cls.get_loaded_plugins("module") plugin_key = await cls._resolve_plugin_key(index_or_module) - plugin_info = next((p for p in all_plugin_list if p.module == plugin_key), None) + for p in plugin_list: + if p.module == plugin_key: + is_external = False + plugin_info = p + break + for p in extra_plugin_list: + if p.module == plugin_key: + is_external = True + plugin_info = p + break if not plugin_info: raise PluginStoreException(f"插件不存在: {plugin_key}") if not is_update and plugin_info.module in [p[0] for p in db_plugin_list]: raise PluginStoreException(f"插件 {plugin_info.name} 已安装,无需重复安装") if plugin_info.module not in [p[0] for p in db_plugin_list] and is_update: raise PluginStoreException(f"插件 {plugin_info.name} 未安装,无法更新") - return plugin_info + return plugin_info, is_external @classmethod async def add_plugin(cls, index_or_module: str) -> str: @@ -201,11 +212,9 @@ class StoreManager: 返回: str: 返回消息 """ - plugin_info = await cls.get_plugin_by_value(index_or_module) - is_external = True + plugin_info, is_external = await cls.get_plugin_by_value(index_or_module) if plugin_info.github_url is None: plugin_info.github_url = DEFAULT_GITHUB_URL - is_external = False version_split = plugin_info.version.split("-") if len(version_split) > 1: github_url_split = plugin_info.github_url.split("/tree/") @@ -301,7 +310,7 @@ class StoreManager: 返回: str: 返回消息 """ - plugin_info = await cls.get_plugin_by_value(index_or_module) + plugin_info, _ = await cls.get_plugin_by_value(index_or_module) path = BASE_PATH if plugin_info.github_url: path = BASE_PATH / "plugins" @@ -373,17 +382,15 @@ class StoreManager: 返回: str: 返回消息 """ - plugin_info = await cls.get_plugin_by_value(index_or_module, True) + plugin_info, is_external = await cls.get_plugin_by_value(index_or_module, True) logger.info(f"尝试更新插件 {plugin_info.name}", LOG_COMMAND) db_plugin_list = await cls.get_loaded_plugins("module", "version") suc_plugin = {p[0]: (p[1] or "Unknown") for p in db_plugin_list} logger.debug(f"当前插件列表: {suc_plugin}", LOG_COMMAND) if cls.check_version_is_new(plugin_info, suc_plugin): return f"插件 {plugin_info.name} 已是最新版本" - is_external = True if plugin_info.github_url is None: plugin_info.github_url = DEFAULT_GITHUB_URL - is_external = False await cls.install_plugin_with_repo( plugin_info.github_url, plugin_info.module_path, @@ -402,8 +409,9 @@ class StoreManager: 返回: str: 返回消息 """ - plugin_list: list[StorePluginInfo] = await cls.get_data() - plugin_name_list = [p.name for p in plugin_list] + plugin_list, extra_plugin_list = await cls.get_data() + all_plugin_list = plugin_list + extra_plugin_list + plugin_name_list = [p.name for p in all_plugin_list] update_failed_list = [] update_success_list = [] result = "--已更新{}个插件 {}个失败 {}个成功--" diff --git a/zhenxun/utils/repo_utils/file_manager.py b/zhenxun/utils/repo_utils/file_manager.py index 67c82192..53797bd6 100644 --- a/zhenxun/utils/repo_utils/file_manager.py +++ b/zhenxun/utils/repo_utils/file_manager.py @@ -207,13 +207,13 @@ class RepoFileManager: ) if repo_type is None: try: - return await self.get_aliyun_file_content( - repo_name, file_path, branch, ignore_error - ) - except Exception: return await self.get_github_file_content( repo_url, file_path, ignore_error ) + except Exception: + return await self.get_aliyun_file_content( + repo_name, file_path, branch, ignore_error + ) try: if repo_type == RepoType.GITHUB: @@ -257,17 +257,17 @@ class RepoFileManager: ) try: if repo_type is None: - # 尝试阿里云,失败则尝试GitHub + # 尝试GitHub,失败则尝试阿里云 try: - return await self._list_aliyun_directory_files( - repo_name, directory_path, branch, recursive + return await self._list_github_directory_files( + repo_url, directory_path, branch, recursive ) except Exception as e: logger.warning( - "获取阿里云目录文件失败,尝试GitHub", LOG_COMMAND, e=e + "获取GitHub目录文件失败,尝试阿里云", LOG_COMMAND, e=e ) - return await self._list_github_directory_files( - repo_url, directory_path, branch, recursive + return await self._list_aliyun_directory_files( + repo_name, directory_path, branch, recursive ) if repo_type == RepoType.GITHUB: return await self._list_github_directory_files( @@ -526,6 +526,7 @@ class RepoFileManager: content_bytes = content.encode("utf-8") else: content_bytes = content + logger.warning(f"写入文件: {local_path}") async with aiofiles.open(local_path, "wb") as f: await f.write(content_bytes) result.success = True