Skip to main content
Glama

MCP Server for Odoo

test_search_smart_defaults.py•6.19 kB
"""Test smart field selection for search_records.""" from unittest.mock import Mock import pytest from mcp_server_odoo.tools import OdooToolHandler class TestSearchSmartDefaults: """Test smart field selection for search_records when fields not specified.""" @pytest.fixture def tool_handler(self): """Create a tool handler with mocked dependencies.""" app = Mock() connection = Mock() access_controller = Mock() config = Mock() config.default_limit = 10 config.max_limit = 100 config.max_smart_fields = 15 return OdooToolHandler(app, connection, access_controller, config) @pytest.mark.asyncio async def test_search_with_no_fields_uses_smart_defaults(self, tool_handler): """Test that search_records uses smart defaults when fields is None.""" # Setup mocks tool_handler.connection.is_authenticated = True tool_handler.connection.search_count.return_value = 2 tool_handler.connection.search.return_value = [1, 2] # Mock fields_get to return field metadata tool_handler.connection.fields_get.return_value = { "id": {"type": "integer", "required": True}, "name": {"type": "char", "required": True, "searchable": True}, "email": {"type": "char", "searchable": True}, "phone": {"type": "char", "searchable": True}, "create_date": {"type": "datetime"}, "message_ids": {"type": "one2many"}, # Should be excluded "_barcode_scan": {"type": "char"}, # Should be excluded (technical) "image_1920": {"type": "binary"}, # Should be excluded (binary) } # Mock read to return records with only smart default fields tool_handler.connection.read.return_value = [ { "id": 1, "name": "Test 1", "email": "test1@example.com", "create_date": "20250607T10:00:00", }, { "id": 2, "name": "Test 2", "email": "test2@example.com", "create_date": "20250607T11:00:00", }, ] # Call the handler with fields=None handler = tool_handler._handle_search_tool await handler("res.partner", [], None, 10, 0, None) # Verify smart defaults were used # The read call should have been made with specific fields, not None tool_handler.connection.read.assert_called_once() call_args = tool_handler.connection.read.call_args fields_arg = call_args[0][2] # Third positional argument # Should have selected smart default fields assert fields_arg is not None assert isinstance(fields_arg, list) assert "id" in fields_arg assert "name" in fields_arg assert "email" in fields_arg # Should exclude technical/binary/relation fields assert "message_ids" not in fields_arg assert "_barcode_scan" not in fields_arg assert "image_1920" not in fields_arg @pytest.mark.asyncio async def test_search_with_specific_fields(self, tool_handler): """Test that search_records uses specified fields when provided.""" # Setup mocks tool_handler.connection.is_authenticated = True tool_handler.connection.search_count.return_value = 1 tool_handler.connection.search.return_value = [1] tool_handler.connection.read.return_value = [ {"id": 1, "name": "Test", "phone": "+1234567890"} ] # Call with specific fields handler = tool_handler._handle_search_tool fields = ["name", "phone"] await handler("res.partner", [], fields, 10, 0, None) # Verify specified fields were used tool_handler.connection.read.assert_called_once_with("res.partner", [1], fields) @pytest.mark.asyncio async def test_search_with_all_fields(self, tool_handler): """Test that search_records can fetch all fields when explicitly requested.""" # Setup mocks tool_handler.connection.is_authenticated = True tool_handler.connection.search_count.return_value = 1 tool_handler.connection.search.return_value = [1] tool_handler.connection.read.return_value = [ { "id": 1, "name": "Test", "email": "test@example.com", "phone": "+1234567890", "create_date": "20250607T10:00:00", "message_ids": [1, 2, 3], "_barcode_scan": "12345", "image_1920": "base64data...", # ... many more fields } ] # Call with __all__ to get all fields handler = tool_handler._handle_search_tool await handler("res.partner", [], ["__all__"], 10, 0, None) # Verify None was passed to read (which means all fields) tool_handler.connection.read.assert_called_once_with("res.partner", [1], None) @pytest.mark.asyncio async def test_search_smart_defaults_with_datetime_formatting(self, tool_handler): """Test that datetime fields are formatted even with smart defaults.""" # Setup mocks tool_handler.connection.is_authenticated = True tool_handler.connection.search_count.return_value = 1 tool_handler.connection.search.return_value = [1] # Mock fields_get tool_handler.connection.fields_get.return_value = { "id": {"type": "integer", "required": True}, "name": {"type": "char", "required": True}, "create_date": {"type": "datetime"}, } # Mock read with datetime that needs formatting tool_handler.connection.read.return_value = [ {"id": 1, "name": "Test", "create_date": "20250607T10:00:00"} ] # Call the handler handler = tool_handler._handle_search_tool result = await handler("res.partner", [], None, 10, 0, None) # Verify datetime was formatted assert result["records"][0]["create_date"] == "2025-06-07T10:00:00+00:00"

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/AlejandroLaraPolanco/mcp-odoo'

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