Skip to content

Commit 836eb9a

Browse files
committed
added doctests for a2a_services for doctest coverage
Signed-off-by: Satya <[email protected]>
1 parent c457bb7 commit 836eb9a

File tree

1 file changed

+111
-45
lines changed

1 file changed

+111
-45
lines changed

mcpgateway/services/a2a_service.py

Lines changed: 111 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,41 @@ async def list_agents(self, db: Session, cursor: Optional[str] = None, include_i
304304
305305
Returns:
306306
List of agent data.
307+
308+
Examples:
309+
>>> from mcpgateway.services.a2a_service import A2AAgentService
310+
>>> from unittest.mock import MagicMock
311+
>>> from mcpgateway.schemas import A2AAgentRead
312+
>>> import asyncio
313+
314+
>>> service = A2AAgentService()
315+
>>> db = MagicMock()
316+
317+
>>> # Mock a single agent object returned by the DB
318+
>>> agent_obj = MagicMock()
319+
>>> db.execute.return_value.scalars.return_value.all.return_value = [agent_obj]
320+
321+
>>> # Mock the A2AAgentRead schema to return a masked string
322+
>>> mocked_agent_read = MagicMock()
323+
>>> mocked_agent_read.masked.return_value = 'agent_read'
324+
>>> A2AAgentRead.model_validate = MagicMock(return_value=mocked_agent_read)
325+
326+
>>> # Run the service method
327+
>>> result = asyncio.run(service.list_agents(db))
328+
>>> result == ['agent_read']
329+
True
330+
331+
>>> # Test include_inactive parameter (same mock works)
332+
>>> result_with_inactive = asyncio.run(service.list_agents(db, include_inactive=True))
333+
>>> result_with_inactive == ['agent_read']
334+
True
335+
336+
>>> # Test empty result
337+
>>> db.execute.return_value.scalars.return_value.all.return_value = []
338+
>>> empty_result = asyncio.run(service.list_agents(db))
339+
>>> empty_result
340+
[]
341+
307342
"""
308343
query = select(DbA2AAgent)
309344

@@ -411,6 +446,72 @@ async def get_agent(self, db: Session, agent_id: str, include_inactive: bool = T
411446
412447
Raises:
413448
A2AAgentNotFoundError: If the agent is not found.
449+
450+
Examples:
451+
>>> from unittest.mock import MagicMock
452+
>>> from datetime import datetime
453+
>>> import asyncio
454+
>>> from mcpgateway.schemas import A2AAgentRead
455+
>>> from mcpgateway.services.a2a_service import A2AAgentService, A2AAgentNotFoundError
456+
457+
>>> service = A2AAgentService()
458+
>>> db = MagicMock()
459+
460+
>>> # Create a mock agent
461+
>>> agent_mock = MagicMock()
462+
>>> agent_mock.enabled = True
463+
>>> agent_mock.id = "agent_id"
464+
>>> agent_mock.name = "Test Agent"
465+
>>> agent_mock.slug = "test-agent"
466+
>>> agent_mock.description = "A2A test agent"
467+
>>> agent_mock.endpoint_url = "https://example.com"
468+
>>> agent_mock.agent_type = "rest"
469+
>>> agent_mock.protocol_version = "v1"
470+
>>> agent_mock.capabilities = {}
471+
>>> agent_mock.config = {}
472+
>>> agent_mock.reachable = True
473+
>>> agent_mock.created_at = datetime.now()
474+
>>> agent_mock.updated_at = datetime.now()
475+
>>> agent_mock.last_interaction = None
476+
>>> agent_mock.tags = []
477+
>>> agent_mock.metrics = MagicMock()
478+
>>> agent_mock.metrics.success_rate = 1.0
479+
>>> agent_mock.metrics.failure_rate = 0.0
480+
>>> agent_mock.metrics.last_error = None
481+
>>> agent_mock.auth_type = None
482+
>>> agent_mock.auth_value = None
483+
>>> agent_mock.oauth_config = None
484+
>>> agent_mock.created_by = "user"
485+
>>> agent_mock.created_from_ip = "127.0.0.1"
486+
>>> agent_mock.created_via = "ui"
487+
>>> agent_mock.created_user_agent = "test-agent"
488+
>>> agent_mock.modified_by = "user"
489+
>>> agent_mock.modified_from_ip = "127.0.0.1"
490+
>>> agent_mock.modified_via = "ui"
491+
>>> agent_mock.modified_user_agent = "test-agent"
492+
>>> agent_mock.import_batch_id = None
493+
>>> agent_mock.federation_source = None
494+
>>> agent_mock.team_id = "team-1"
495+
>>> agent_mock.team = "Team 1"
496+
>>> agent_mock.owner_email = "[email protected]"
497+
>>> agent_mock.visibility = "public"
498+
499+
>>> db.get.return_value = agent_mock
500+
501+
>>> # Mock _db_to_schema to simplify test
502+
>>> service._db_to_schema = lambda db, db_agent: 'agent_read'
503+
504+
>>> # Test with active agent
505+
>>> result = asyncio.run(service.get_agent(db, 'agent_id'))
506+
>>> result
507+
'agent_read'
508+
509+
>>> # Test with inactive agent but include_inactive=True
510+
>>> agent_mock.enabled = False
511+
>>> result_inactive = asyncio.run(service.get_agent(db, 'agent_id', include_inactive=True))
512+
>>> result_inactive
513+
'agent_read'
514+
414515
"""
415516
query = select(DbA2AAgent).where(DbA2AAgent.id == agent_id)
416517
agent = db.execute(query).scalar_one_or_none()
@@ -817,12 +918,8 @@ def _db_to_schema(self, db: Session, db_agent: DbA2AAgent) -> A2AAgentRead:
817918
if not db_agent:
818919
raise A2AAgentNotFoundError("Agent not found")
819920

820-
# assign teams attribute to agent
821921
setattr(db_agent, "team", self._get_team_name(db, getattr(db_agent, "team_id", None)))
822922

823-
# Prepare the agent (encode auth_value, enrich team, etc.)
824-
# db_agent = self._prepare_a2a_agent_for_read(db_agent)
825-
826923
# ✅ Compute metrics
827924
total_executions = len(db_agent.metrics)
828925
successful_executions = sum(1 for m in db_agent.metrics if m.is_success)
@@ -849,44 +946,13 @@ def _db_to_schema(self, db: Session, db_agent: DbA2AAgent) -> A2AAgentRead:
849946
last_execution_time=last_execution_time,
850947
)
851948

852-
return A2AAgentRead(
853-
id=db_agent.id,
854-
name=db_agent.name,
855-
slug=db_agent.slug,
856-
description=db_agent.description,
857-
endpoint_url=db_agent.endpoint_url,
858-
agent_type=db_agent.agent_type,
859-
protocol_version=db_agent.protocol_version,
860-
capabilities=db_agent.capabilities,
861-
config=db_agent.config,
862-
auth_type=db_agent.auth_type,
863-
auth_username=None,
864-
auth_password=None,
865-
auth_token=None,
866-
auth_header_key=None,
867-
auth_header_value=None,
868-
auth_value=db_agent.auth_value, # encoded_auth_value,
869-
oauth_config=db_agent.oauth_config,
870-
enabled=db_agent.enabled,
871-
reachable=db_agent.reachable,
872-
created_at=db_agent.created_at,
873-
updated_at=db_agent.updated_at,
874-
last_interaction=db_agent.last_interaction,
875-
tags=db_agent.tags,
876-
metrics=metrics,
877-
created_by=db_agent.created_by,
878-
created_from_ip=db_agent.created_from_ip,
879-
created_via=db_agent.created_via,
880-
created_user_agent=db_agent.created_user_agent,
881-
modified_by=db_agent.modified_by,
882-
modified_from_ip=db_agent.modified_from_ip,
883-
modified_via=db_agent.modified_via,
884-
modified_user_agent=db_agent.modified_user_agent,
885-
import_batch_id=db_agent.import_batch_id,
886-
federation_source=db_agent.federation_source,
887-
version=db_agent.version,
888-
visibility=db_agent.visibility,
889-
team_id=db_agent.team_id,
890-
team=getattr(db_agent, "team", None),
891-
owner_email=db_agent.owner_email,
892-
).masked()
949+
# Build dict from ORM model
950+
agent_data = {k: getattr(db_agent, k, None) for k in A2AAgentRead.model_fields.keys()}
951+
agent_data["metrics"] = metrics
952+
agent_data["team"] = getattr(db_agent, "team", None)
953+
954+
# Validate using Pydantic model
955+
validated_agent = A2AAgentRead.model_validate(agent_data)
956+
957+
# Return masked version (like GatewayRead)
958+
return validated_agent.masked()

0 commit comments

Comments
 (0)