151 lines
5.1 KiB
Python
151 lines
5.1 KiB
Python
import os
|
|
from asyncio import Queue
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from astrbot.core.config.astrbot_config import AstrBotConfig
|
|
from astrbot.core.db.sqlite import SQLiteDatabase
|
|
from astrbot.core.star.context import Context
|
|
from astrbot.core.star.star import star_registry
|
|
from astrbot.core.star.star_handler import star_handlers_registry
|
|
from astrbot.core.star.star_manager import PluginManager
|
|
|
|
|
|
@pytest.fixture
|
|
def plugin_manager_pm(tmp_path):
|
|
"""Provides a fully isolated PluginManager instance for testing.
|
|
- Uses a temporary directory for plugins.
|
|
- Uses a temporary database.
|
|
- Creates a fresh context for each test.
|
|
"""
|
|
# Create temporary resources
|
|
temp_plugins_path = tmp_path / "plugins"
|
|
temp_plugins_path.mkdir()
|
|
temp_db_path = tmp_path / "test_db.db"
|
|
|
|
# Create fresh, isolated instances for the context
|
|
event_queue = Queue()
|
|
config = AstrBotConfig()
|
|
db = SQLiteDatabase(str(temp_db_path))
|
|
|
|
# Set the plugin store path in the config to the temporary directory
|
|
config.plugin_store_path = str(temp_plugins_path)
|
|
|
|
# Mock dependencies for the context
|
|
provider_manager = MagicMock()
|
|
platform_manager = MagicMock()
|
|
conversation_manager = MagicMock()
|
|
message_history_manager = MagicMock()
|
|
persona_manager = MagicMock()
|
|
astrbot_config_mgr = MagicMock()
|
|
knowledge_base_manager = MagicMock()
|
|
|
|
star_context = Context(
|
|
event_queue,
|
|
config,
|
|
db,
|
|
provider_manager,
|
|
platform_manager,
|
|
conversation_manager,
|
|
message_history_manager,
|
|
persona_manager,
|
|
astrbot_config_mgr,
|
|
knowledge_base_manager=knowledge_base_manager,
|
|
)
|
|
|
|
# Create the PluginManager instance
|
|
manager = PluginManager(star_context, config)
|
|
return manager
|
|
|
|
|
|
def test_plugin_manager_initialization(plugin_manager_pm: PluginManager):
|
|
assert plugin_manager_pm is not None
|
|
assert plugin_manager_pm.context is not None
|
|
assert plugin_manager_pm.config is not None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_plugin_manager_reload(plugin_manager_pm: PluginManager):
|
|
success, err_message = await plugin_manager_pm.reload()
|
|
assert success is True
|
|
assert err_message is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_install_plugin(plugin_manager_pm: PluginManager):
|
|
"""Tests successful plugin installation in an isolated environment."""
|
|
test_repo = "https://github.com/Soulter/astrbot_plugin_essential"
|
|
plugin_info = await plugin_manager_pm.install_plugin(test_repo)
|
|
plugin_path = os.path.join(
|
|
plugin_manager_pm.plugin_store_path,
|
|
"astrbot_plugin_essential",
|
|
)
|
|
|
|
assert plugin_info is not None
|
|
assert os.path.exists(plugin_path)
|
|
assert any(md.name == "astrbot_plugin_essential" for md in star_registry), (
|
|
"Plugin 'astrbot_plugin_essential' was not loaded into star_registry."
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_install_nonexistent_plugin(plugin_manager_pm: PluginManager):
|
|
"""Tests that installing a non-existent plugin raises an exception."""
|
|
with pytest.raises(Exception):
|
|
await plugin_manager_pm.install_plugin(
|
|
"https://github.com/Soulter/non_existent_repo",
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_plugin(plugin_manager_pm: PluginManager):
|
|
"""Tests updating an existing plugin in an isolated environment."""
|
|
# First, install the plugin
|
|
test_repo = "https://github.com/Soulter/astrbot_plugin_essential"
|
|
await plugin_manager_pm.install_plugin(test_repo)
|
|
|
|
# Then, update it
|
|
await plugin_manager_pm.update_plugin("astrbot_plugin_essential")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_nonexistent_plugin(plugin_manager_pm: PluginManager):
|
|
"""Tests that updating a non-existent plugin raises an exception."""
|
|
with pytest.raises(Exception):
|
|
await plugin_manager_pm.update_plugin("non_existent_plugin")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uninstall_plugin(plugin_manager_pm: PluginManager):
|
|
"""Tests successful plugin uninstallation in an isolated environment."""
|
|
# First, install the plugin
|
|
test_repo = "https://github.com/Soulter/astrbot_plugin_essential"
|
|
await plugin_manager_pm.install_plugin(test_repo)
|
|
plugin_path = os.path.join(
|
|
plugin_manager_pm.plugin_store_path,
|
|
"astrbot_plugin_essential",
|
|
)
|
|
assert os.path.exists(plugin_path) # Pre-condition
|
|
|
|
# Then, uninstall it
|
|
await plugin_manager_pm.uninstall_plugin("astrbot_plugin_essential")
|
|
|
|
assert not os.path.exists(plugin_path)
|
|
assert not any(md.name == "astrbot_plugin_essential" for md in star_registry), (
|
|
"Plugin 'astrbot_plugin_essential' was not unloaded from star_registry."
|
|
)
|
|
assert not any(
|
|
"astrbot_plugin_essential" in md.handler_module_path
|
|
for md in star_handlers_registry
|
|
), (
|
|
"Plugin 'astrbot_plugin_essential' handler was not unloaded from star_handlers_registry."
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_uninstall_nonexistent_plugin(plugin_manager_pm: PluginManager):
|
|
"""Tests that uninstalling a non-existent plugin raises an exception."""
|
|
with pytest.raises(Exception):
|
|
await plugin_manager_pm.uninstall_plugin("non_existent_plugin")
|