Skip to main content
Glama

MCP Server for Odoo

test_write_operations.py•8.13 kB
"""Tests for OdooConnection write operations (create, write, unlink).""" import os from unittest.mock import Mock, patch import pytest from mcp_server_odoo.config import OdooConfig from mcp_server_odoo.odoo_connection import OdooConnection, OdooConnectionError class TestWriteOperations: """Test write operations in OdooConnection.""" @pytest.fixture def mock_config(self): """Create mock config.""" config = Mock(spec=OdooConfig) config.url = os.getenv("ODOO_URL", "http://localhost:8069") config.db = "test" config.username = "test" config.password = "test" config.api_key = None config.uses_api_key = False config.uses_credentials = True config.is_yolo_enabled = False config.yolo_mode = "off" config.get_endpoint_paths.return_value = { "db": "/mcp/xmlrpc/db", "common": "/mcp/xmlrpc/common", "object": "/mcp/xmlrpc/object", } return config @pytest.fixture def mock_performance_manager(self, mock_config): """Create mock performance manager.""" manager = Mock() # Create a proper context manager mock cm = Mock() cm.__enter__ = Mock(return_value=None) cm.__exit__ = Mock(return_value=None) manager.monitor.track_operation.return_value = cm manager.invalidate_record_cache = Mock() manager.get_optimized_connection = Mock(return_value=Mock()) return manager @pytest.fixture def connection(self, mock_config, mock_performance_manager): """Create OdooConnection with mocks.""" conn = OdooConnection(mock_config, performance_manager=mock_performance_manager) conn._connected = True conn._authenticated = True conn._uid = 2 conn._database = "test" conn._auth_method = "password" return conn def test_create_record(self, connection): """Test creating a record.""" model = "res.partner" values = {"name": "Test Partner", "email": "test@example.com"} expected_id = 123 with patch.object(connection, "execute_kw", return_value=expected_id) as mock_execute: result = connection.create(model, values) assert result == expected_id mock_execute.assert_called_once_with(model, "create", [values], {}) connection._performance_manager.invalidate_record_cache.assert_called_once_with(model) def test_create_record_error(self, connection): """Test create record with error.""" model = "res.partner" values = {"name": "Test"} with patch.object( connection, "execute_kw", side_effect=OdooConnectionError("Create failed") ): with pytest.raises(OdooConnectionError, match="Create failed"): connection.create(model, values) def test_write_records(self, connection): """Test updating records.""" model = "res.partner" ids = [123, 124] values = {"email": "updated@example.com"} with patch.object(connection, "execute_kw", return_value=True) as mock_execute: result = connection.write(model, ids, values) assert result is True mock_execute.assert_called_once_with(model, "write", [ids, values], {}) # Should invalidate cache for each record assert connection._performance_manager.invalidate_record_cache.call_count == 2 connection._performance_manager.invalidate_record_cache.assert_any_call(model, 123) connection._performance_manager.invalidate_record_cache.assert_any_call(model, 124) def test_write_single_record(self, connection): """Test updating a single record.""" model = "res.partner" ids = [123] values = {"name": "Updated Name"} with patch.object(connection, "execute_kw", return_value=True): result = connection.write(model, ids, values) assert result is True connection._performance_manager.invalidate_record_cache.assert_called_once_with( model, 123 ) def test_write_records_error(self, connection): """Test write records with error.""" model = "res.partner" ids = [123] values = {"name": "Test"} with patch.object( connection, "execute_kw", side_effect=OdooConnectionError("Write failed") ): with pytest.raises(OdooConnectionError, match="Write failed"): connection.write(model, ids, values) def test_unlink_records(self, connection): """Test deleting records.""" model = "res.partner" ids = [123, 124, 125] with patch.object(connection, "execute_kw", return_value=True) as mock_execute: result = connection.unlink(model, ids) assert result is True mock_execute.assert_called_once_with(model, "unlink", [ids], {}) # Should invalidate cache for each record assert connection._performance_manager.invalidate_record_cache.call_count == 3 connection._performance_manager.invalidate_record_cache.assert_any_call(model, 123) connection._performance_manager.invalidate_record_cache.assert_any_call(model, 124) connection._performance_manager.invalidate_record_cache.assert_any_call(model, 125) def test_unlink_single_record(self, connection): """Test deleting a single record.""" model = "res.partner" ids = [123] with patch.object(connection, "execute_kw", return_value=True): result = connection.unlink(model, ids) assert result is True connection._performance_manager.invalidate_record_cache.assert_called_once_with( model, 123 ) def test_unlink_records_error(self, connection): """Test unlink records with error.""" model = "res.partner" ids = [123] with patch.object( connection, "execute_kw", side_effect=OdooConnectionError("Delete failed") ): with pytest.raises(OdooConnectionError, match="Delete failed"): connection.unlink(model, ids) def test_write_operations_performance_tracking(self, connection): """Test that write operations track performance.""" # Test create with patch.object(connection, "execute_kw", return_value=123): connection.create("res.partner", {"name": "Test"}) connection._performance_manager.monitor.track_operation.assert_called_with( "create_res.partner" ) # Test write with patch.object(connection, "execute_kw", return_value=True): connection.write("res.partner", [123], {"name": "Updated"}) connection._performance_manager.monitor.track_operation.assert_called_with( "write_res.partner" ) # Test unlink with patch.object(connection, "execute_kw", return_value=True): connection.unlink("res.partner", [123]) connection._performance_manager.monitor.track_operation.assert_called_with( "unlink_res.partner" ) def test_write_operations_not_authenticated(self, connection): """Test write operations when not authenticated.""" connection._authenticated = False # Since execute_kw checks authentication, the error is raised from there with pytest.raises(OdooConnectionError, match="Not authenticated"): connection.create("res.partner", {"name": "Test"}) # Reset for next test connection._authenticated = False with pytest.raises(OdooConnectionError, match="Not authenticated"): connection.write("res.partner", [123], {"name": "Test"}) # Reset for next test connection._authenticated = False with pytest.raises(OdooConnectionError, match="Not authenticated"): connection.unlink("res.partner", [123])

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