Skip to main content
Glama
test_configuration.py9.14 kB
""" Tests for OPNsense MCP Server configuration domain. This module tests the configuration tools including connection setup and API endpoint discovery. """ import pytest import json import sys from unittest.mock import AsyncMock, Mock, patch, MagicMock from mcp.server.fastmcp import FastMCP # Mock the circular import with proper FastMCP instance mock_mcp = FastMCP("test-server") mock_server_state = MagicMock() mock_main = MagicMock() mock_main.mcp = mock_mcp mock_main.server_state = mock_server_state sys.modules['src.opnsense_mcp.main'] = mock_main from src.opnsense_mcp.core.exceptions import ( ConfigurationError, AuthenticationError, NetworkError, APIError, ValidationError ) from src.opnsense_mcp.domains.configuration import ( configure_opnsense_connection, get_api_endpoints, get_opnsense_client ) @pytest.mark.asyncio class TestConfigureOPNsenseConnection: """Test configure_opnsense_connection tool.""" async def test_successful_configuration(self, mock_mcp_context): """Test successful OPNsense connection configuration.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_state.initialize = AsyncMock() result = await configure_opnsense_connection( ctx=mock_mcp_context, url="https://192.168.1.1", api_key="test_key", api_secret="test_secret", verify_ssl=False ) assert "configured successfully" in result mock_state.initialize.assert_called_once() mock_mcp_context.info.assert_called_once() async def test_configuration_with_ssl_verification(self, mock_mcp_context): """Test configuration with SSL verification enabled.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_state.initialize = AsyncMock() result = await configure_opnsense_connection( ctx=mock_mcp_context, url="https://opnsense.example.com", api_key="key", api_secret="secret", verify_ssl=True ) assert "configured successfully" in result async def test_authentication_error_handling(self, mock_mcp_context): """Test handling of authentication errors.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_state.initialize = AsyncMock(side_effect=AuthenticationError("Invalid credentials")) result = await configure_opnsense_connection( ctx=mock_mcp_context, url="https://192.168.1.1", api_key="wrong_key", api_secret="wrong_secret", verify_ssl=False ) assert "Authentication Error" in result assert "Invalid credentials" in result mock_mcp_context.error.assert_called_once() async def test_network_error_handling(self, mock_mcp_context): """Test handling of network errors.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_state.initialize = AsyncMock(side_effect=NetworkError("Cannot connect")) result = await configure_opnsense_connection( ctx=mock_mcp_context, url="https://192.168.1.1", api_key="key", api_secret="secret" ) assert "Network Error" in result assert "Cannot connect" in result async def test_validation_error_handling(self, mock_mcp_context): """Test handling of validation errors.""" with patch('src.opnsense_mcp.domains.configuration.OPNsenseConfig') as MockConfig: MockConfig.side_effect = ValidationError("Invalid URL format") result = await configure_opnsense_connection( ctx=mock_mcp_context, url="invalid-url", api_key="key", api_secret="secret" ) assert "Configuration Error" in result async def test_generic_error_handling(self, mock_mcp_context): """Test handling of unexpected errors.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_state.initialize = AsyncMock(side_effect=Exception("Unexpected error")) result = await configure_opnsense_connection( ctx=mock_mcp_context, url="https://192.168.1.1", api_key="key", api_secret="secret" ) assert "Error:" in result @pytest.mark.asyncio class TestGetAPIEndpoints: """Test get_api_endpoints tool.""" async def test_get_all_endpoints(self, mock_mcp_context): """Test getting all API endpoints.""" mock_response = { "Firewall": {"routes": ["/firewall/filter/searchRule"]}, "System": {"routes": ["/core/system/info"]} } with patch('src.opnsense_mcp.domains.configuration.get_opnsense_client') as mock_get_client: mock_client = Mock() mock_client.request = AsyncMock(return_value=mock_response) mock_get_client.return_value = mock_client result = await get_api_endpoints(ctx=mock_mcp_context) # Should return JSON with all modules result_data = json.loads(result) assert "Firewall" in result_data assert "System" in result_data async def test_get_filtered_endpoints(self, mock_mcp_context): """Test getting filtered API endpoints by module.""" mock_response = { "Firewall": {"routes": ["/firewall/filter/searchRule"]}, "System": {"routes": ["/core/system/info"]} } with patch('src.opnsense_mcp.domains.configuration.get_opnsense_client') as mock_get_client: mock_client = Mock() mock_client.request = AsyncMock(return_value=mock_response) mock_get_client.return_value = mock_client result = await get_api_endpoints(ctx=mock_mcp_context, module="Firewall") # Should return JSON with only Firewall module result_data = json.loads(result) assert "routes" in result_data assert "/firewall/filter/searchRule" in result_data["routes"] async def test_nonexistent_module_returns_available_list(self, mock_mcp_context): """Test requesting non-existent module returns available modules.""" mock_response = { "Firewall": {}, "System": {} } with patch('src.opnsense_mcp.domains.configuration.get_opnsense_client') as mock_get_client: mock_client = Mock() mock_client.request = AsyncMock(return_value=mock_response) mock_get_client.return_value = mock_client result = await get_api_endpoints(ctx=mock_mcp_context, module="NonExistent") assert "not found" in result assert "Available modules" in result assert "Firewall" in result async def test_configuration_error_handling(self, mock_mcp_context): """Test handling of configuration errors.""" with patch('src.opnsense_mcp.domains.configuration.get_opnsense_client') as mock_get_client: mock_get_client.side_effect = ConfigurationError("Not configured") result = await get_api_endpoints(ctx=mock_mcp_context) assert "Configuration Error" in result mock_mcp_context.error.assert_called_once() async def test_api_error_handling(self, mock_mcp_context): """Test handling of API errors.""" with patch('src.opnsense_mcp.domains.configuration.get_opnsense_client') as mock_get_client: mock_client = Mock() mock_client.request = AsyncMock(side_effect=APIError("API error")) mock_get_client.return_value = mock_client result = await get_api_endpoints(ctx=mock_mcp_context) assert "Error:" in result @pytest.mark.asyncio class TestGetOPNsenseClient: """Test get_opnsense_client helper function.""" async def test_get_client_from_server_state(self): """Test getting client from server state.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_client = Mock() mock_state.get_client = AsyncMock(return_value=mock_client) result = await get_opnsense_client() assert result == mock_client mock_state.get_client.assert_called_once() async def test_get_client_raises_configuration_error(self): """Test that get_client raises ConfigurationError when not configured.""" with patch('src.opnsense_mcp.domains.configuration.server_state') as mock_state: mock_state.get_client = AsyncMock(side_effect=ConfigurationError("Not configured")) with pytest.raises(ConfigurationError): await get_opnsense_client()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/floriangrousset/opnsense-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server