arcade-mcp/toolkits/google/tests/test_contacts.py
Renato Byrro 75da4bf8b0
Make search_contacts interface more LLM-friendly (#272)
Break down `search_contacts` into `search_contacts_by_name` and
`search_contacts_by_email`. The search_contacts' `query` argument was
not clear enough for LLMs.
2025-02-28 16:47:03 -03:00

94 lines
3.4 KiB
Python

from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from arcade.sdk import ToolContext
from arcade_google.tools.contacts import create_contact
@pytest.fixture
def mock_context():
context = AsyncMock(spec=ToolContext)
context.authorization = MagicMock()
context.authorization.token = "mock_token" # noqa: S105
return context
@pytest.mark.asyncio
async def test_create_contact_success(mock_context):
# Test create_contact with all parameters (given, family names and email)
created_contact_data = {"resourceName": "people/123", "etag": "abc"}
create_contact_call = MagicMock()
create_contact_call.execute.return_value = created_contact_data
people_mock = MagicMock()
people_mock.createContact.return_value = create_contact_call
service_mock = MagicMock()
service_mock.people.return_value = people_mock
with patch("arcade_google.tools.contacts.build", return_value=service_mock) as mock_build:
result = await create_contact(
mock_context,
given_name="Alice",
family_name="Smith",
email="alice@example.com",
)
assert "contact" in result
assert result["contact"] == created_contact_data
# Verify that the createContact API was called with the correct body contents.
expected_body = {
"names": [{"givenName": "Alice", "familyName": "Smith"}],
"emailAddresses": [{"value": "alice@example.com", "type": "work"}],
}
people_mock.createContact.assert_called_once_with(
body=expected_body, personFields="names,emailAddresses"
)
mock_build.assert_called_once()
@pytest.mark.asyncio
async def test_create_contact_success_without_optional(mock_context):
# Test create_contact without optional parameters family_name and email.
created_contact_data = {"resourceName": "people/456", "etag": "def"}
create_contact_call = MagicMock()
create_contact_call.execute.return_value = created_contact_data
people_mock = MagicMock()
people_mock.createContact.return_value = create_contact_call
service_mock = MagicMock()
service_mock.people.return_value = people_mock
with patch("arcade_google.tools.contacts.build", return_value=service_mock):
result = await create_contact(mock_context, given_name="Bob", family_name=None, email=None)
assert "contact" in result
assert result["contact"] == created_contact_data
# Expected body should only include the givenName when family_name and email are omitted.
expected_body = {"names": [{"givenName": "Bob"}]}
people_mock.createContact.assert_called_once_with(
body=expected_body, personFields="names,emailAddresses"
)
@pytest.mark.asyncio
async def test_create_contact_error(mock_context):
# Simulate an error thrown by createContact
error_call = MagicMock()
error_call.execute.side_effect = Exception("Create error")
people_mock = MagicMock()
people_mock.createContact.return_value = error_call
service_mock = MagicMock()
service_mock.people.return_value = people_mock
with (
patch("arcade_google.tools.contacts.build", return_value=service_mock),
pytest.raises(Exception, match="Error in execution of CreateContact"),
):
await create_contact(mock_context, given_name="Alice", family_name="Doe", email=None)