ForcePilot/backend/test/unit/channel/startup/test_channel_config.py
Kris 6c95dc006a test: 新增渠道模块全链路单元测试用例与目录结构
完成渠道模块的单元测试目录搭建,新增多个领域模型、端口、中间件、事件、服务以及基础设施层的单元测试文件,同时补充了conftest.py的环境变量配置,完善测试基础环境。
2026-05-30 21:55:35 +08:00

196 lines
5.7 KiB
Python

from __future__ import annotations
import pytest
from yuxi.channel.infrastructure.config.channel_config import ChannelConfig
class TestChannelConfig:
@pytest.fixture
def config_file(self, tmp_path):
yaml_path = tmp_path / "channel_config.yaml"
yaml_path.write_text("""
auth:
token: "test_token"
password: "test_password"
max_attempts: 3
lockout_seconds: 600
feishu:
mode: "webhook"
app_id: "test_app_id"
app_secret: "test_app_secret"
verification_token: "test_verification_token"
ws_enabled: true
dingtalk:
mode: "webhook"
client_id: "test_client_id"
client_secret: "test_client_secret"
ws_enabled: true
web:
sse_enabled: true
max_connections: 500
hooks:
mappings:
- match_path: "/test"
default_agent_id: 1
worker:
num_workers: 2
max_concurrent: 10
poll_timeout_ms: 3000
outbox_poll_interval: 3.0
default_agent_config_id: 2
access_policies:
web:
dm_policy: "allowlist"
allow_from:
- "user1"
allow_from:
web:
- "user1"
- "user2"
keyword_blocklist:
- "badword1"
- "badword2"
mention_gate:
default_require_mention: false
mention_patterns:
- "@bot"
""")
return str(yaml_path)
def test_load_config(self, config_file):
config = ChannelConfig(config_file)
assert config.auth_token == "test_token"
assert config.auth_password == "test_password"
assert config.max_auth_attempts == 3
assert config.lockout_seconds == 600
def test_feishu_config(self, config_file):
config = ChannelConfig(config_file)
feishu = config.get_channel_config("feishu")
assert feishu["mode"] == "webhook"
assert feishu["app_id"] == "test_app_id"
def test_dingtalk_config(self, config_file):
config = ChannelConfig(config_file)
dingtalk = config.get_channel_config("dingtalk")
assert dingtalk["mode"] == "webhook"
assert dingtalk["client_id"] == "test_client_id"
def test_web_config(self, config_file):
config = ChannelConfig(config_file)
web = config.get_channel_config("web")
assert web["sse_enabled"] is True
assert web["max_connections"] == 500
def test_hook_mappings(self, config_file):
config = ChannelConfig(config_file)
mappings = config.hook_mappings
assert len(mappings) == 1
assert mappings[0]["match_path"] == "/test"
def test_access_policies(self, config_file):
config = ChannelConfig(config_file)
policies = config.access_policies
assert "web" in policies
def test_allow_from(self, config_file):
config = ChannelConfig(config_file)
allow_from = config.allow_from
assert "web" in allow_from
def test_keyword_blocklist(self, config_file):
config = ChannelConfig(config_file)
blocklist = config.keyword_blocklist
assert "badword1" in blocklist
assert "badword2" in blocklist
def test_mention_gate_config(self, config_file):
config = ChannelConfig(config_file)
mention_config = config.mention_gate_config
assert mention_config["default_require_mention"] is False
assert "@bot" in mention_config["mention_patterns"]
def test_feishu_verification_token(self, config_file):
config = ChannelConfig(config_file)
assert config.feishu_verification_token == "test_verification_token"
def test_feishu_ws_config_webhook_mode(self, config_file):
config = ChannelConfig(config_file)
assert config.feishu_ws_config is None
def test_dingtalk_ws_config_webhook_mode(self, config_file):
config = ChannelConfig(config_file)
assert config.dingtalk_ws_config is None
def test_raw_data(self, config_file):
config = ChannelConfig(config_file)
raw = config.raw_data
assert "auth" in raw
assert "feishu" in raw
@pytest.mark.asyncio
async def test_reload(self, config_file):
config = ChannelConfig(config_file)
await config.reload()
assert config.auth_token == "test_token"
@pytest.mark.asyncio
async def test_on_config_updated(self, config_file):
config = ChannelConfig(config_file)
updated = await config.on_config_updated({"auth": {"token": "new_token"}})
assert "auth_token" in updated
assert config.auth_token == "new_token"
def test_missing_file(self, tmp_path):
yaml_path = tmp_path / "missing.yaml"
config = ChannelConfig(str(yaml_path))
assert config.raw_data == {}
assert config.auth_token is None
def test_default_values(self, tmp_path):
yaml_path = tmp_path / "empty.yaml"
yaml_path.write_text("{}")
config = ChannelConfig(str(yaml_path))
assert config.max_auth_attempts == 5
assert config.lockout_seconds == 300
assert config.keyword_blocklist == set()
assert config.hook_mappings == []
assert config.access_policies == {}
assert config.allow_from == {}
def test_feishu_ws_config_websocket_mode(self, tmp_path):
yaml_path = tmp_path / "ws_config.yaml"
yaml_path.write_text("""
feishu:
mode: "websocket"
app_id: "test"
app_secret: "test"
""")
config = ChannelConfig(str(yaml_path))
ws_config = config.feishu_ws_config
assert ws_config is not None
assert ws_config["mode"] == "websocket"
def test_dingtalk_ws_config_websocket_mode(self, tmp_path):
yaml_path = tmp_path / "ws_config.yaml"
yaml_path.write_text("""
dingtalk:
mode: "websocket"
client_id: "test"
client_secret: "test"
""")
config = ChannelConfig(str(yaml_path))
ws_config = config.dingtalk_ws_config
assert ws_config is not None
assert ws_config["mode"] == "websocket"