新增了插件相关的完整领域模型、应用服务、基础设施实现,包括: 1. 插件状态、注册模式、来源等基础枚举和数据结构 2. 插件清单解析、发现、加载工具类 3. 插件注册表领域服务和内存存储实现 4. 插件相关的命令、查询、事件定义 5. 插件REST API接口和DTO映射 6. 集成了原有通道适配器到插件系统 7. 新增内置插件注册和自动发现能力
84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from yuxi.channel.startup import get_container, init_channel, register_channel_middleware, shutdown_channel
|
|
|
|
|
|
class TestInitChannel:
|
|
@pytest.mark.asyncio
|
|
async def test_init_channel_sets_global_container(self, tmp_path):
|
|
config_file = tmp_path / "channel_config.yaml"
|
|
config_file.write_text("{}")
|
|
|
|
mock_container = MagicMock()
|
|
mock_container.shutdown = AsyncMock()
|
|
|
|
with patch(
|
|
"yuxi.channel.startup.ChannelContainerFactory.create", new_callable=AsyncMock, return_value=mock_container
|
|
):
|
|
container = await init_channel(
|
|
redis_url="redis://localhost:6379/0",
|
|
config_yaml_path=str(config_file),
|
|
)
|
|
|
|
assert container is mock_container
|
|
assert get_container() is mock_container
|
|
|
|
await shutdown_channel()
|
|
|
|
|
|
class TestShutdownChannel:
|
|
@pytest.mark.asyncio
|
|
async def test_shutdown_channel_calls_shutdown(self):
|
|
mock_container = MagicMock()
|
|
mock_container.shutdown = AsyncMock()
|
|
|
|
with patch(
|
|
"yuxi.channel.startup.ChannelContainerFactory.create", new_callable=AsyncMock, return_value=mock_container
|
|
):
|
|
await init_channel(redis_url="redis://localhost:6379/0")
|
|
|
|
await shutdown_channel()
|
|
|
|
mock_container.shutdown.assert_awaited_once()
|
|
assert get_container() is None
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shutdown_channel_with_provided_container(self):
|
|
mock_container = MagicMock()
|
|
mock_container.shutdown = AsyncMock()
|
|
|
|
await shutdown_channel(mock_container)
|
|
|
|
mock_container.shutdown.assert_awaited_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shutdown_channel_handles_none(self):
|
|
await shutdown_channel(None)
|
|
|
|
|
|
class TestGetContainer:
|
|
def test_get_container_returns_none_initially(self):
|
|
assert get_container() is None
|
|
|
|
|
|
class TestRegisterChannelMiddleware:
|
|
def test_register_channel_middleware_sets_state(self):
|
|
mock_container = MagicMock()
|
|
|
|
with patch("yuxi.channel.startup._container", mock_container):
|
|
app = MagicMock()
|
|
register_channel_middleware(app)
|
|
|
|
assert app.state.channel is mock_container
|
|
|
|
def test_register_channel_middleware_skips_when_no_container(self):
|
|
with patch("yuxi.channel.startup._container", None):
|
|
app = MagicMock()
|
|
register_channel_middleware(app)
|
|
|
|
assert not hasattr(app.state, "channel")
|