| """ |
| SSHOUT模块基础测试 |
| 测试SSHOUT集成基础功能 |
| """ |
| |
| import pytest |
| from unittest.mock import Mock, patch |
| from datetime import datetime |
| |
| import sys |
| from pathlib import Path |
| sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src")) |
| |
| |
| class TestSSHOUTBasicFunctions: |
| """SSHOUT基础功能测试""" |
| |
| def test_create_sshout_integration_api_mode(self): |
| """测试创建API模式的SSHOUT集成""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| mock_agent = Mock() |
| |
| # Mock配置管理器 |
| mock_config = { |
| 'connection_mode': 'api', |
| 'api_endpoint': 'wss://example.com', |
| 'username': 'testuser', |
| 'password': 'testpass' |
| } |
| |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| mock_config_manager = Mock() |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.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 is not None |
| |
| def test_create_sshout_integration_ssh_mode(self): |
| """测试创建SSH模式的SSHOUT集成""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| mock_agent = Mock() |
| |
| # Mock配置管理器 |
| mock_config = { |
| 'connection_mode': 'ssh', |
| 'server': { |
| 'hostname': 'sshout.example.com', |
| 'port': 22, |
| 'username': 'sshout' |
| } |
| } |
| |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| mock_config_manager = Mock() |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| with patch('claude_agent.sshout.SSHOUTIntegration') as mock_ssh_integration: |
| result = create_sshout_integration(mock_agent, "test_config") |
| |
| mock_ssh_integration.assert_called_once_with(mock_agent, "test_config") |
| assert result is not None |
| |
| def test_create_sshout_integration_default_mode(self): |
| """测试默认连接模式(API)""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| mock_agent = Mock() |
| |
| # Mock配置管理器 - 没有指定connection_mode |
| mock_config = { |
| 'api_endpoint': 'wss://example.com', |
| 'username': 'testuser' |
| } |
| |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| mock_config_manager = Mock() |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.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_sshout_integration_invalid_mode(self): |
| """测试无效的连接模式""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| mock_agent = Mock() |
| |
| # Mock配置管理器 - 无效的连接模式 |
| mock_config = { |
| 'connection_mode': 'invalid_mode' |
| } |
| |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| mock_config_manager = Mock() |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| with pytest.raises(ValueError, match="不支持的SSHOUT连接模式"): |
| create_sshout_integration(mock_agent) |
| |
| |
| class TestSSHOUTModuleImports: |
| """测试SSHOUT模块导入""" |
| |
| def test_import_all_components(self): |
| """测试导入所有SSHOUT组件""" |
| from claude_agent.sshout import ( |
| SSHOUTIntegration, |
| SSHOUTConnection, |
| SSHOUTMessage, |
| SSHOUTApiClient, |
| SSHOUTApiIntegration, |
| ApiSSHOUTMessage, |
| create_sshout_integration |
| ) |
| |
| # 验证所有组件都能正确导入 |
| 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 |
| assert create_sshout_integration is not None |
| |
| def test_module_all_exports(self): |
| """测试模块的__all__导出""" |
| import claude_agent.sshout as sshout_module |
| |
| expected_exports = [ |
| 'SSHOUTIntegration', |
| 'SSHOUTConnection', |
| 'SSHOUTMessage', |
| 'SSHOUTApiClient', |
| 'SSHOUTApiIntegration', |
| 'ApiSSHOUTMessage', |
| 'create_sshout_integration' |
| ] |
| |
| assert hasattr(sshout_module, '__all__') |
| assert set(sshout_module.__all__) == set(expected_exports) |
| |
| def test_function_existence(self): |
| """测试主要函数存在性""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| assert callable(create_sshout_integration) |
| |
| |
| class TestSSHOUTIntegrationBasic: |
| """SSHOUT集成基础测试""" |
| |
| def test_sshout_message_creation(self): |
| """测试SSHOUT消息创建""" |
| from claude_agent.sshout.integration import SSHOUTMessage |
| |
| message = SSHOUTMessage( |
| content="Hello SSHOUT", |
| username="testuser", |
| timestamp="2024-10-04T10:30:00" |
| ) |
| |
| assert message.content == "Hello SSHOUT" |
| assert message.username == "testuser" |
| assert message.timestamp == "2024-10-04T10:30:00" |
| |
| def test_sshout_connection_creation(self): |
| """测试SSHOUT连接创建""" |
| from claude_agent.sshout.integration import SSHOUTConnection |
| |
| connection = SSHOUTConnection( |
| hostname="sshout.example.com", |
| port=22, |
| username="testuser", |
| key_path="/path/to/key" |
| ) |
| |
| assert connection.hostname == "sshout.example.com" |
| assert connection.port == 22 |
| assert connection.username == "testuser" |
| assert connection.key_path == "/path/to/key" |
| |
| @pytest.mark.asyncio |
| async def test_sshout_integration_initialization(self): |
| """测试SSHOUT集成初始化""" |
| from claude_agent.sshout.integration import SSHOUTIntegration |
| |
| mock_agent = Mock() |
| |
| # Mock配置管理器 |
| with patch('claude_agent.sshout.integration.get_config_manager') as mock_get_config: |
| with patch('os.path.exists', return_value=True): # Mock密钥文件存在 |
| mock_config_manager = Mock() |
| mock_config_manager.get_sshout_config.return_value = { |
| 'server': { |
| 'hostname': 'test.sshout.com', |
| 'port': 22, |
| 'username': 'sshout' |
| }, |
| 'ssh_key': { |
| 'private_key_path': '/path/to/key' |
| }, |
| 'mention_patterns': ['@Claude', '@claude'] |
| } |
| mock_get_config.return_value = mock_config_manager |
| |
| integration = SSHOUTIntegration(mock_agent, "test_config") |
| |
| assert integration.agent == mock_agent |
| assert integration is not None |
| |
| |
| class TestSSHOUTApiClientBasic: |
| """SSHOUT API客户端基础测试""" |
| |
| def test_api_client_initialization(self): |
| """测试API客户端初始化""" |
| from claude_agent.sshout.api_client import SSHOUTApiClient |
| |
| client = SSHOUTApiClient( |
| hostname="sshout.example.com", |
| port=22, |
| username="testuser", |
| key_path="/path/to/key" |
| ) |
| |
| assert client.hostname == "sshout.example.com" |
| assert client.port == 22 |
| assert client.username == "testuser" |
| assert client.key_path == "/path/to/key" |
| assert client.connected is False |
| |
| def test_api_message_creation(self): |
| """测试API消息创建""" |
| from claude_agent.sshout.api_client import SSHOUTMessage as ApiSSHOUTMessage |
| |
| message = ApiSSHOUTMessage( |
| timestamp=datetime.now(), |
| from_user="testuser", |
| to_user="all", |
| message_type=1, |
| content="Hello API" |
| ) |
| |
| assert message.content == "Hello API" |
| assert message.from_user == "testuser" |
| assert message.to_user == "all" |
| assert message.message_type == 1 |
| |
| @pytest.mark.asyncio |
| async def test_api_integration_initialization(self): |
| """测试API集成初始化""" |
| from claude_agent.sshout.api_client import SSHOUTApiIntegration |
| |
| mock_agent = Mock() |
| |
| with patch('claude_agent.sshout.api_client.get_config_manager') as mock_get_config: |
| with patch('os.path.exists', return_value=True): # Mock密钥文件存在 |
| mock_config_manager = Mock() |
| mock_config_manager.get_sshout_config.return_value = { |
| 'server': { |
| 'hostname': 'sshout.example.com', |
| 'port': 22, |
| 'username': 'testuser' |
| }, |
| 'ssh_key': { |
| 'private_key_path': '/path/to/key' |
| }, |
| 'mention_patterns': ['@Claude'] |
| } |
| mock_get_config.return_value = mock_config_manager |
| |
| integration = SSHOUTApiIntegration(mock_agent, "test_config") |
| |
| assert integration.agent == mock_agent |
| assert integration is not None |
| |
| |
| class TestSSHOUTErrorHandling: |
| """SSHOUT错误处理测试""" |
| |
| def test_invalid_config_handling(self): |
| """测试无效配置处理""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| mock_agent = Mock() |
| |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| # 模拟配置管理器抛出异常 |
| mock_get_config.side_effect = Exception("配置文件未找到") |
| |
| with pytest.raises(Exception): |
| create_sshout_integration(mock_agent) |
| |
| def test_missing_config_values(self): |
| """测试缺失配置值处理""" |
| from claude_agent.sshout import create_sshout_integration |
| |
| mock_agent = Mock() |
| |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| mock_config_manager = Mock() |
| # 返回空配置 |
| mock_config_manager.get_sshout_config.return_value = {} |
| mock_get_config.return_value = mock_config_manager |
| |
| with patch('claude_agent.sshout.SSHOUTApiIntegration') as mock_api_integration: |
| # 应该使用默认的API模式 |
| result = create_sshout_integration(mock_agent) |
| mock_api_integration.assert_called_once_with(mock_agent, None) |