Skip to main content
Glama
test_mcp_tools.py5.9 kB
""" Integration tests for MCP tools. Tests the email search and draft functionality with threading support. """ from unittest.mock import MagicMock, patch # Import the underlying function from tools module from meeting_scheduler_mcp.tools import search_emails # The function is now plain, no wrapper needed search_emails_func = search_emails class TestMCPEmailTools: """Test suite for MCP email tools.""" @patch("meeting_scheduler_mcp.tools.IMAPEmailClient") def test_search_emails_with_metadata(self, mock_imap_client_class): """Test that search_emails_tool returns full email metadata including threading info.""" # Setup mock instance mock_client = MagicMock() mock_imap_client_class.return_value = mock_client # Configure context manager behavior mock_client.__enter__ = MagicMock(return_value=mock_client) mock_client.__exit__ = MagicMock(return_value=None) # Mock email IDs mock_client.search_emails.return_value = [b"1", b"2"] # Mock email metadata with threading information mock_client.get_email_metadata.side_effect = [ { "subject": "Meeting Request", "from": "client@example.com", "to": "me@example.com", "date": "Mon, 1 Jan 2024 10:00:00 +0000", "message_id": "<abc123@example.com>", "in_reply_to": "", "references": "", "body": "Can we schedule a meeting?", }, { "subject": "Re: Meeting Request", "from": "me@example.com", "to": "client@example.com", "date": "Mon, 1 Jan 2024 11:00:00 +0000", "message_id": "<def456@example.com>", "in_reply_to": "<abc123@example.com>", "references": "<abc123@example.com>", "body": "Yes, let's schedule it.", }, ] # Call the tool result = search_emails_func(mailbox="INBOX", criteria="UNSEEN") # Verify results assert isinstance(result, list) assert len(result) == 2 # Verify first email metadata email1 = result[0] assert email1["id"] == "1" assert email1["subject"] == "Meeting Request" assert email1["from"] == "client@example.com" assert email1["to"] == "me@example.com" assert email1["message_id"] == "<abc123@example.com>" assert email1["in_reply_to"] == "" assert email1["references"] == "" # Verify second email metadata (reply) email2 = result[1] assert email2["id"] == "2" assert email2["subject"] == "Re: Meeting Request" assert email2["message_id"] == "<def456@example.com>" assert email2["in_reply_to"] == "<abc123@example.com>" assert email2["references"] == "<abc123@example.com>" # Verify threading relationship original_message_id = email1["message_id"] reply = email2 assert reply["in_reply_to"] == original_message_id assert original_message_id in reply["references"] # Verify mock calls mock_client.search_emails.assert_called_once_with("INBOX", "UNSEEN") assert mock_client.get_email_metadata.call_count == 2 def test_email_threading_relationships(self): """Test logic for identifying email threading relationships.""" # Sample email data emails = [ { "id": "1", "message_id": "<msg1@example.com>", "in_reply_to": "", "references": "", }, { "id": "2", "message_id": "<msg2@example.com>", "in_reply_to": "<msg1@example.com>", "references": "<msg1@example.com>", }, { "id": "3", "message_id": "<msg3@example.com>", "in_reply_to": "<msg2@example.com>", "references": "<msg1@example.com> <msg2@example.com>", }, ] # Test finding replies original_msg_id = "<msg1@example.com>" replies = [email for email in emails if email["in_reply_to"] == original_msg_id] assert len(replies) == 1 assert replies[0]["id"] == "2" # Test finding entire thread thread = [emails[0]] # Start with original for email in emails[1:]: # Add replies if email["in_reply_to"] in [e["message_id"] for e in thread]: thread.append(email) assert len(thread) == 3 assert thread[0]["id"] == "1" # Original assert thread[1]["id"] == "2" # First reply assert thread[2]["id"] == "3" # Second reply def test_message_id_validation(self): """Test validation of Message-ID format.""" valid_message_ids = [ "<abc123@example.com>", "<12345.67890@example.org>", "<unique-id-12345@mail.server.com>", ] invalid_message_ids = [ "abc123@example.com", # Missing angle brackets "<>", # Empty "not-a-message-id", # No format "", # Empty string ] # Test valid formats for msg_id in valid_message_ids: assert msg_id.startswith("<") and msg_id.endswith(">") assert len(msg_id) > 2 # Not just <> content = msg_id[1:-1] # Remove angle brackets assert "@" in content # Should contain @ assert "." in content or content.count("@") > 1 # Should have domain # Test invalid formats for msg_id in invalid_message_ids: is_valid = ( msg_id.startswith("<") and msg_id.endswith(">") and len(msg_id) > 2 ) assert not is_valid

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/seb-schulz/meeting-scheduler-mcp'

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