blob: 9d3171483458794561b15e0b8b357784f2fa1d4e [file] [log] [blame] [raw]
"""
SSHOUT模块初始化和工厂函数的完整测试覆盖
"""
import pytest
from unittest.mock import Mock, patch
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../../src'))
from claude_agent.sshout import (
create_sshout_integration,
SSHOUTIntegration,
SSHOUTConnection,
SSHOUTMessage,
SSHOUTApiClient,
SSHOUTApiIntegration,
ApiSSHOUTMessage
)
class TestSSHOUTModuleInit:
"""测试SSHOUT模块初始化"""
def test_imports_available(self):
"""测试所有导入的类都可用"""
# 验证所有导出的类都存在
assert SSHOUTIntegration is not None
assert SSHOUTConnection is not None
assert SSHOUTMessage is not None
assert SSHOUTApiClient is not None
assert SSHOUTApiIntegration is not None
assert ApiSSHOUTMessage is not None
def test_all_exports(self):
"""测试__all__导出列表"""
from claude_agent.sshout import __all__
expected_exports = [
'SSHOUTIntegration',
'SSHOUTConnection',
'SSHOUTMessage',
'SSHOUTApiClient',
'SSHOUTApiIntegration',
'ApiSSHOUTMessage',
'create_sshout_integration'
]
assert __all__ == expected_exports
class TestCreateSSHOUTIntegration:
"""测试create_sshout_integration工厂函数"""
@pytest.fixture
def mock_agent(self):
"""创建模拟Agent"""
return Mock()
@pytest.fixture
def mock_config_manager(self):
"""创建模拟配置管理器"""
config_manager = Mock()
config_manager.get_sshout_config.return_value = {}
return config_manager
def test_create_api_integration_default(self, mock_agent, mock_config_manager):
"""测试创建API集成(默认模式)"""
# 默认配置使用API模式
mock_config_manager.get_sshout_config.return_value = {}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration:
result = create_sshout_integration(mock_agent)
# 应该创建API集成
mock_api_integration.assert_called_once_with(mock_agent, None)
assert result == mock_api_integration.return_value
def test_create_api_integration_explicit(self, mock_agent, mock_config_manager):
"""测试显式创建API集成"""
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': 'api'
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration:
result = create_sshout_integration(mock_agent, 'test_config')
mock_api_integration.assert_called_once_with(mock_agent, 'test_config')
assert result == mock_api_integration.return_value
def test_create_ssh_integration(self, mock_agent, mock_config_manager):
"""测试创建SSH集成"""
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': 'ssh'
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch('claude_agent.sshout.SSHOUTIntegration') as mock_ssh_integration:
result = create_sshout_integration(mock_agent, 'ssh_config')
mock_ssh_integration.assert_called_once_with(mock_agent, 'ssh_config')
assert result == mock_ssh_integration.return_value
def test_create_integration_invalid_mode(self, mock_agent, mock_config_manager):
"""测试创建集成 - 无效模式"""
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': 'invalid_mode'
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with pytest.raises(ValueError, match="不支持的SSHOUT连接模式: invalid_mode"):
create_sshout_integration(mock_agent)
def test_create_integration_with_config_name(self, mock_agent, mock_config_manager):
"""测试使用配置名称创建集成"""
config_name = "production"
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': 'api'
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager) as mock_get_config:
with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration:
result = create_sshout_integration(mock_agent, config_name)
# 应该使用指定的配置名称
mock_get_config.assert_called_once_with(config_name)
mock_api_integration.assert_called_once_with(mock_agent, config_name)
def test_create_integration_config_error(self, mock_agent):
"""测试配置加载错误"""
with patch('claude_agent.utils.config.get_config_manager', side_effect=Exception("配置加载失败")):
with pytest.raises(Exception, match="配置加载失败"):
create_sshout_integration(mock_agent)
def test_create_integration_missing_config(self, mock_agent, mock_config_manager):
"""测试缺失配置"""
# 配置管理器返回None
mock_config_manager.get_sshout_config.side_effect = Exception("配置不存在")
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with pytest.raises(Exception, match="配置不存在"):
create_sshout_integration(mock_agent)
def test_create_integration_none_agent(self, mock_config_manager):
"""测试None Agent参数"""
mock_config_manager.get_sshout_config.return_value = {}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration:
result = create_sshout_integration(None)
# 应该传递None给集成类
mock_api_integration.assert_called_once_with(None, None)
def test_create_integration_complex_config(self, mock_agent, mock_config_manager):
"""测试复杂配置"""
complex_config = {
'connection_mode': 'api',
'server': {
'hostname': 'test.example.com',
'port': 22333
},
'ssh_key': {
'private_key_path': '/path/to/key'
}
}
mock_config_manager.get_sshout_config.return_value = complex_config
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration:
result = create_sshout_integration(mock_agent)
# 应该正确创建API集成,配置细节由集成类处理
mock_api_integration.assert_called_once_with(mock_agent, None)
def test_create_integration_case_insensitive_mode(self, mock_agent, mock_config_manager):
"""测试连接模式的大小写敏感性"""
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': 'API' # 大写
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
# 这应该抛出错误,因为当前实现区分大小写
with pytest.raises(ValueError, match="不支持的SSHOUT连接模式: API"):
create_sshout_integration(mock_agent)
def test_create_integration_empty_config(self, mock_agent, mock_config_manager):
"""测试空配置"""
mock_config_manager.get_sshout_config.return_value = {}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration:
result = create_sshout_integration(mock_agent)
# 空配置应该默认为API模式
mock_api_integration.assert_called_once_with(mock_agent, None)
def test_create_integration_config_manager_call(self, mock_agent, mock_config_manager):
"""测试配置管理器调用"""
mock_config_manager.get_sshout_config.return_value = {'connection_mode': 'api'}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager) as mock_get_config:
with patch('claude_agent.sshout.SSHOUTApiIntegration'):
create_sshout_integration(mock_agent, 'test_config')
# 验证配置管理器被正确调用
mock_get_config.assert_called_once_with('test_config')
mock_config_manager.get_sshout_config.assert_called_once()
def test_create_integration_factory_pattern(self, mock_agent, mock_config_manager):
"""测试工厂模式的完整性"""
test_cases = [
('api', 'SSHOUTApiIntegration'),
('ssh', 'SSHOUTIntegration')
]
for mode, expected_class in test_cases:
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': mode
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with patch(f'claude_agent.sshout.{expected_class}') as mock_integration:
result = create_sshout_integration(mock_agent)
# 应该创建正确的集成类型
mock_integration.assert_called_once_with(mock_agent, None)
assert result == mock_integration.return_value
def test_module_docstring_consistency(self):
"""测试模块文档字符串的一致性"""
import claude_agent.sshout as sshout_module
# 验证模块有文档字符串
assert sshout_module.__doc__ is not None
assert "SSHOUT聊天室集成支持" in sshout_module.__doc__
assert "SSH模式" in sshout_module.__doc__
assert "API模式" in sshout_module.__doc__
def test_function_signature_consistency(self, mock_agent):
"""测试函数签名的一致性"""
# 测试可选参数的默认值
with patch('claude_agent.utils.config.get_config_manager') as mock_get_config:
# 设置正确的mock返回值
mock_config_manager = Mock()
mock_config_manager.get_sshout_config.return_value = {'connection_mode': 'api'}
mock_get_config.return_value = mock_config_manager
with patch('claude_agent.sshout.SSHOUTApiIntegration'):
# 不传config_name
create_sshout_integration(mock_agent)
mock_get_config.assert_called_with(None)
# 传入config_name
create_sshout_integration(mock_agent, "test")
mock_get_config.assert_called_with("test")
def test_integration_creation_edge_cases(self, mock_agent, mock_config_manager):
"""测试集成创建的边界情况"""
# 测试配置值为None的情况
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': None
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with pytest.raises(ValueError, match="不支持的SSHOUT连接模式: None"):
create_sshout_integration(mock_agent)
# 测试配置值为空字符串的情况
mock_config_manager.get_sshout_config.return_value = {
'connection_mode': ''
}
with patch('claude_agent.utils.config.get_config_manager', return_value=mock_config_manager):
with pytest.raises(ValueError, match="不支持的SSHOUT连接模式: "):
create_sshout_integration(mock_agent)