@@ -5349,7 +5349,6 @@ async def admin_edit_tool(
53495349 an error message if the update fails.
53505350
53515351 Examples:
5352- Examples:
53535352 >>> import asyncio
53545353 >>> from unittest.mock import AsyncMock, MagicMock
53555354 >>> from fastapi import Request
@@ -5484,7 +5483,6 @@ async def admin_edit_tool(
54845483
54855484 >>> # Restore original method
54865485 >>> tool_service.update_tool = original_update_tool
5487-
54885486 """
54895487 LOGGER .debug (f"User { get_user_email (user )} is editing tool ID { tool_id } " )
54905488 form = await request .form ()
@@ -6249,10 +6247,7 @@ async def admin_edit_gateway(
62496247 >>>
62506248 >>> async def test_admin_edit_gateway_success():
62516249 ... response = await admin_edit_gateway(gateway_id, mock_request_success, mock_db, mock_user)
6252- ... #print("Response:", response)
6253- ... #print("Status code:", response.status_code)
6254- ... #print("Body:", response.body)
6255- ... return isinstance(response, JSONResponse) and response.status_code == 200 and json.loads(response.body)["success"]
6250+ ... return isinstance(response, JSONResponse) and response.status_code == 200 and json.loads(response.body)["success"] is True
62566251 >>>
62576252 >>> asyncio.run(test_admin_edit_gateway_success())
62586253 True
@@ -7414,6 +7409,7 @@ async def admin_edit_prompt(
74147409 >>> asyncio.run(test_admin_edit_prompt_inactive())
74157410 True
74167411 >>> prompt_service.update_prompt = original_update_prompt
7412+
74177413 """
74187414 LOGGER .debug (f"User { get_user_email (user )} is editing prompt { prompt_id } " )
74197415 form = await request .form ()
@@ -9251,7 +9247,7 @@ async def admin_list_a2a_agents(
92519247
92529248 Examples:
92539249 >>> import asyncio
9254- >>> from unittest.mock import AsyncMock, MagicMock
9250+ >>> from unittest.mock import AsyncMock, MagicMock, patch
92559251 >>> from mcpgateway.schemas import A2AAgentRead, A2AAgentMetrics
92569252 >>> from datetime import datetime, timezone
92579253 >>>
@@ -9287,28 +9283,28 @@ async def admin_list_a2a_agents(
92879283 ... )
92889284 ... )
92899285 >>>
9290- >>> original_list_agents_for_user = a2a_service.list_agents_for_user
9291- >>> a2a_service.list_agents_for_user = AsyncMock(return_value=[mock_agent])
9292- >>>
92939286 >>> async def test_admin_list_a2a_agents_active():
9294- ... result = await admin_list_a2a_agents(include_inactive=False, db=mock_db, user=mock_user)
9295- ... return len(result) > 0 and isinstance(result[0], dict) and result[0]['name'] == "Agent1"
9287+ ... fake_service = MagicMock()
9288+ ... fake_service.list_agents_for_user = AsyncMock(return_value=[mock_agent])
9289+ ... with patch("mcpgateway.admin.a2a_service", new=fake_service):
9290+ ... result = await admin_list_a2a_agents(include_inactive=False, db=mock_db, user=mock_user)
9291+ ... return len(result) > 0 and isinstance(result[0], dict) and result[0]['name'] == "Agent1"
92969292 >>>
92979293 >>> asyncio.run(test_admin_list_a2a_agents_active())
92989294 True
92999295 >>>
9300- >>> a2a_service.list_agents_for_user = AsyncMock(side_effect=Exception("A2A error"))
93019296 >>> async def test_admin_list_a2a_agents_exception():
9302- ... try:
9303- ... await admin_list_a2a_agents(False, db=mock_db, user=mock_user)
9304- ... return False
9305- ... except Exception as e:
9306- ... return "A2A error" in str(e)
9297+ ... fake_service = MagicMock()
9298+ ... fake_service.list_agents_for_user = AsyncMock(side_effect=Exception("A2A error"))
9299+ ... with patch("mcpgateway.admin.a2a_service", new=fake_service):
9300+ ... try:
9301+ ... await admin_list_a2a_agents(False, db=mock_db, user=mock_user)
9302+ ... return False
9303+ ... except Exception as e:
9304+ ... return "A2A error" in str(e)
93079305 >>>
93089306 >>> asyncio.run(test_admin_list_a2a_agents_exception())
93099307 True
9310- >>>
9311- >>> a2a_service.list_agents_for_user = original_list_agents_for_user
93129308 """
93139309 if a2a_service is None :
93149310 LOGGER .warning ("A2A features are disabled, returning empty list" )
@@ -9562,48 +9558,81 @@ async def admin_edit_a2a_agent(
95629558 Returns:
95639559 JSONResponse: A JSON response indicating success or failure.
95649560
9565- Example:
9566- >>> import asyncio, json
9567- >>> from unittest.mock import AsyncMock, MagicMock
9568- >>> from fastapi import Request
9569- >>> from fastapi.responses import JSONResponse
9570- >>> from starlette.datastructures import FormData
9571- >>> import types, mcpgateway.admin as admin_mod
9572- >>> mock_db = MagicMock()
9573- >>> mock_user = {"email": "[email protected] "} 9574- >>> agent_id = "agent-123"
9575- >>> form_data_success = FormData([
9576- ... ("name", "Updated Agent"),
9577- ... ("endpoint_url", "http://example.com/agent"),
9578- ... ("agent_type", "generic"),
9579- ... ("auth_type", "basic"),
9580- ... ("auth_username", "user"),
9581- ... ("auth_password", "pass"),
9582- ... ])
9583- >>> mock_request_success = MagicMock(spec=Request, scope={"root_path": ""})
9584- >>> mock_request_success.form = AsyncMock(return_value=form_data_success)
9585- >>> admin_mod.get_user_email = lambda u: u["email"]
9586- >>> admin_mod.get_oauth_encryption = lambda secret: types.SimpleNamespace(encrypt_secret=lambda s: f"enc({s})")
9587- >>> admin_mod.settings = types.SimpleNamespace(auth_encryption_secret="dummy-secret")
9588- >>> admin_mod.LOGGER = MagicMock()
9589- >>> admin_mod.TeamManagementService = lambda db: types.SimpleNamespace(
9590- ... verify_team_for_user=AsyncMock(return_value="11111111-1111-1111-1111-111111111111")
9591- ... )
9592- >>> admin_mod.MetadataCapture = types.SimpleNamespace(extract_modification_metadata=lambda req, u, _: {
9593- ... "modified_by": "[email protected] ", 9594- ... "modified_from_ip": "127.0.0.1",
9595- ... "modified_via": "UI",
9596- ... "modified_user_agent": "pytest"
9597- ... })
9598- >>> admin_mod.a2a_service = types.SimpleNamespace(update_agent=AsyncMock(return_value=True))
9599- >>>
9600- >>> async def test_admin_edit_a2a_agent_success():
9601- ... response = await admin_mod.admin_edit_a2a_agent(agent_id, mock_request_success, mock_db, mock_user)
9602- ... body = json.loads(response.body)
9603- ... return isinstance(response, JSONResponse) and response.status_code == 200 and body["success"] is True
9604- >>>
9605- >>> asyncio.run(test_admin_edit_a2a_agent_success())
9606- True
9561+ Examples:
9562+ >>> import asyncio, json
9563+ >>> from unittest.mock import AsyncMock, MagicMock, patch
9564+ >>> from fastapi import Request
9565+ >>> from fastapi.responses import JSONResponse
9566+ >>> from starlette.datastructures import FormData
9567+ >>>
9568+ >>> mock_db = MagicMock()
9569+ >>> mock_user = {"email": "test_admin_user", "db": mock_db}
9570+ >>> agent_id = "agent-123"
9571+ >>>
9572+ >>> # Happy path: edit A2A agent successfully
9573+ >>> form_data_success = FormData([
9574+ ... ("name", "Updated Agent"),
9575+ ... ("endpoint_url", "http://updated-agent.com"),
9576+ ... ("agent_type", "generic"),
9577+ ... ("auth_type", "basic"),
9578+ ... ("auth_username", "user"),
9579+ ... ("auth_password", "pass"),
9580+ ... ])
9581+ >>> mock_request_success = MagicMock(spec=Request, scope={"root_path": ""})
9582+ >>> mock_request_success.form = AsyncMock(return_value=form_data_success)
9583+ >>> original_update_agent = a2a_service.update_agent
9584+ >>> a2a_service.update_agent = AsyncMock()
9585+ >>>
9586+ >>> async def test_admin_edit_a2a_agent_success():
9587+ ... response = await admin_edit_a2a_agent(agent_id, mock_request_success, mock_db, mock_user)
9588+ ... body = json.loads(response.body)
9589+ ... return isinstance(response, JSONResponse) and response.status_code == 200 and body["success"] is True
9590+ >>>
9591+ >>> asyncio.run(test_admin_edit_a2a_agent_success())
9592+ True
9593+ >>>
9594+ >>> # Error path: simulate exception during update
9595+ >>> form_data_error = FormData([
9596+ ... ("name", "Error Agent"),
9597+ ... ("endpoint_url", "http://error-agent.com"),
9598+ ... ("auth_type", "basic"),
9599+ ... ("auth_username", "user"),
9600+ ... ("auth_password", "pass"),
9601+ ... ])
9602+ >>> mock_request_error = MagicMock(spec=Request, scope={"root_path": ""})
9603+ >>> mock_request_error.form = AsyncMock(return_value=form_data_error)
9604+ >>> a2a_service.update_agent = AsyncMock(side_effect=Exception("Update failed"))
9605+ >>>
9606+ >>> async def test_admin_edit_a2a_agent_exception():
9607+ ... response = await admin_edit_a2a_agent(agent_id, mock_request_error, mock_db, mock_user)
9608+ ... body = json.loads(response.body)
9609+ ... return isinstance(response, JSONResponse) and response.status_code == 500 and body["success"] is False and "Update failed" in body["message"]
9610+ >>>
9611+ >>> asyncio.run(test_admin_edit_a2a_agent_exception())
9612+ True
9613+ >>>
9614+ >>> # Validation error path: e.g., invalid URL
9615+ >>> form_data_validation = FormData([
9616+ ... ("name", "Bad URL Agent"),
9617+ ... ("endpoint_url", "invalid-url"),
9618+ ... ("auth_type", "basic"),
9619+ ... ("auth_username", "user"),
9620+ ... ("auth_password", "pass"),
9621+ ... ])
9622+ >>> mock_request_validation = MagicMock(spec=Request, scope={"root_path": ""})
9623+ >>> mock_request_validation.form = AsyncMock(return_value=form_data_validation)
9624+ >>>
9625+ >>> async def test_admin_edit_a2a_agent_validation():
9626+ ... response = await admin_edit_a2a_agent(agent_id, mock_request_validation, mock_db, mock_user)
9627+ ... body = json.loads(response.body)
9628+ ... return isinstance(response, JSONResponse) and response.status_code in (422, 400) and body["success"] is False
9629+ >>>
9630+ >>> asyncio.run(test_admin_edit_a2a_agent_validation())
9631+ True
9632+ >>>
9633+ >>> # Restore original method
9634+ >>> a2a_service.update_agent = original_update_agent
9635+
96079636 """
96089637
96099638 try :
0 commit comments