新增了Twitch、Telegram、Discord、Slack、Mattermost、WeChat、Zalo等多渠道的单元测试用例,覆盖了令牌处理、速率限制、消息去重、会话解析、格式转换、安全策略等模块 同时在测试配置中添加了测试用的OpenAI API密钥环境变量
129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from yuxi.channels.services.doctor import ConfigDoctor, DiagnosisIssue
|
|
|
|
|
|
class TestDiagnosisIssue:
|
|
def test_create_issue(self):
|
|
issue = DiagnosisIssue(
|
|
severity="error",
|
|
channel_id="wx",
|
|
category="credential",
|
|
message="Missing app_id",
|
|
)
|
|
assert issue.severity == "error"
|
|
assert issue.channel_id == "wx"
|
|
assert issue.category == "credential"
|
|
assert issue.message == "Missing app_id"
|
|
assert issue.auto_fixable is False
|
|
|
|
def test_auto_fixable_flag(self):
|
|
issue = DiagnosisIssue(
|
|
severity="warning",
|
|
channel_id="tg",
|
|
category="connectivity",
|
|
message="Timeout",
|
|
auto_fixable=True,
|
|
)
|
|
assert issue.auto_fixable is True
|
|
|
|
|
|
def _make_channel_manager_mock():
|
|
manager = MagicMock()
|
|
manager._registry = MagicMock()
|
|
manager._registry.list_channels.return_value = ["wx", "tg"]
|
|
manager._registry.get.return_value = MagicMock()
|
|
manager._channels_config = {
|
|
"wx": {
|
|
"enabled": True,
|
|
"required_fields": ["app_id", "app_secret"],
|
|
"app_id": "test_id",
|
|
},
|
|
"tg": {
|
|
"enabled": True,
|
|
"token": "test_token",
|
|
},
|
|
}
|
|
manager._adapters = {}
|
|
return manager
|
|
|
|
|
|
class TestConfigDoctor:
|
|
@pytest.mark.asyncio
|
|
async def test_diagnose_all_channels(self):
|
|
manager = _make_channel_manager_mock()
|
|
doctor = ConfigDoctor(manager)
|
|
issues = await doctor.diagnose()
|
|
assert len(issues) >= 1
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_diagnose_single_channel(self):
|
|
manager = _make_channel_manager_mock()
|
|
doctor = ConfigDoctor(manager)
|
|
issues = await doctor.diagnose(channel_id="wx")
|
|
|
|
missing_secret = [i for i in issues if "app_secret" in i.message]
|
|
assert len(missing_secret) == 1
|
|
assert missing_secret[0].severity == "error"
|
|
assert missing_secret[0].category == "credential"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_diagnose_missing_required_fields(self):
|
|
manager = _make_channel_manager_mock()
|
|
manager._channels_config["wx"]["required_fields"] = ["app_id", "app_secret", "token"]
|
|
|
|
doctor = ConfigDoctor(manager)
|
|
issues = await doctor.diagnose(channel_id="wx")
|
|
|
|
credential_issues = [i for i in issues if i.category == "credential"]
|
|
assert any("app_secret" in i.message for i in credential_issues)
|
|
assert any("token" in i.message for i in credential_issues)
|
|
assert not any("app_id" in i.message for i in credential_issues)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_diagnose_no_adapter_registered(self):
|
|
manager = MagicMock()
|
|
manager._registry.list_channels.return_value = ["unknown"]
|
|
manager._registry.get.return_value = None
|
|
manager._channels_config = {"unknown": {"enabled": True}}
|
|
manager._adapters = {}
|
|
|
|
doctor = ConfigDoctor(manager)
|
|
issues = await doctor.diagnose(channel_id="unknown")
|
|
|
|
registry_issues = [i for i in issues if i.category == "registry"]
|
|
assert len(registry_issues) == 1
|
|
assert registry_issues[0].severity == "error"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_auto_fix_non_fixable_returns_false(self):
|
|
manager = _make_channel_manager_mock()
|
|
doctor = ConfigDoctor(manager)
|
|
issue = DiagnosisIssue(
|
|
severity="error", channel_id="wx", category="credential", message="missing", auto_fixable=False
|
|
)
|
|
result = await doctor.auto_fix(issue)
|
|
assert result is False
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_auto_fix_connectivity_restarts_channel(self):
|
|
manager = _make_channel_manager_mock()
|
|
manager.restart_channel = AsyncMock()
|
|
doctor = ConfigDoctor(manager)
|
|
issue = DiagnosisIssue(
|
|
severity="error", channel_id="wx", category="connectivity", message="timeout", auto_fixable=True
|
|
)
|
|
result = await doctor.auto_fix(issue)
|
|
assert result is True
|
|
manager.restart_channel.assert_called_once_with("wx")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_suggest_migration_returns_empty_list(self):
|
|
manager = _make_channel_manager_mock()
|
|
doctor = ConfigDoctor(manager)
|
|
suggestions = await doctor.suggest_migration()
|
|
assert suggestions == [] |