@@ -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