@@ -74,6 +74,11 @@ def mock_db():
74
74
def mock_request ():
75
75
"""Create a mock FastAPI request."""
76
76
request = MagicMock (spec = Request )
77
+
78
+ # FastAPI's Request always has a .scope dict; many admin helpers read "root_path".
79
+ request .scope = {"root_path" : "" }
80
+
81
+ # Pretend form() returns the full set of fields our admin helpers expect
77
82
request .form = AsyncMock (
78
83
return_value = {
79
84
"name" : "test-name" ,
@@ -102,12 +107,20 @@ def mock_request():
102
107
"activate" : "true" ,
103
108
}
104
109
)
110
+
111
+ # Basic template rendering stub
112
+ request .app = MagicMock () # ensure .app exists
113
+ request .app .state = MagicMock () # ensure .app.state exists
105
114
request .app .state .templates = MagicMock ()
106
- request .app .state .templates .TemplateResponse .return_value = HTMLResponse (content = "<html></html>" )
115
+ request .app .state .templates .TemplateResponse .return_value = HTMLResponse (
116
+ content = "<html></html>"
117
+ )
118
+
107
119
request .query_params = {"include_inactive" : "false" }
108
120
return request
109
121
110
122
123
+
111
124
class TestAdminServerRoutes :
112
125
"""Test admin routes for server management."""
113
126
@@ -195,18 +208,15 @@ async def test_admin_toggle_server(self, mock_toggle_status, mock_request, mock_
195
208
assert "/admin#catalog" in result .headers ["location" ]
196
209
197
210
@patch .object (ServerService , "delete_server" )
198
- async def test_admin_delete_server (self , mock_delete_server , mock_db ):
211
+ async def test_admin_delete_server (self , mock_delete_server , mock_request , mock_db ):
199
212
"""Test deleting a server through admin UI."""
200
- # Execute
201
- result = await admin_delete_server (1 , mock_db , "test-user" )
213
+ result = await admin_delete_server (1 , mock_request , mock_db , "test-user" )
202
214
203
- # Assert
204
215
mock_delete_server .assert_called_once_with (mock_db , 1 )
205
216
assert isinstance (result , RedirectResponse )
206
217
assert result .status_code == 303
207
218
assert "/admin#catalog" in result .headers ["location" ]
208
219
209
-
210
220
class TestAdminToolRoutes :
211
221
"""Test admin routes for tool management."""
212
222
@@ -309,12 +319,10 @@ async def test_admin_toggle_tool(self, mock_toggle_status, mock_request, mock_db
309
319
assert "/admin#tools" in result .headers ["location" ]
310
320
311
321
@patch .object (ToolService , "delete_tool" )
312
- async def test_admin_delete_tool (self , mock_delete_tool , mock_db ):
322
+ async def test_admin_delete_tool (self , mock_delete_tool , mock_request , mock_db ):
313
323
"""Test deleting a tool through admin UI."""
314
- # Execute
315
- result = await admin_delete_tool (1 , mock_db , "test-user" )
324
+ result = await admin_delete_tool (1 , mock_request , mock_db , "test-user" )
316
325
317
- # Assert
318
326
mock_delete_tool .assert_called_once_with (mock_db , 1 )
319
327
assert isinstance (result , RedirectResponse )
320
328
assert result .status_code == 303
@@ -399,12 +407,10 @@ async def test_admin_toggle_resource(self, mock_toggle_status, mock_request, moc
399
407
assert "/admin#resources" in result .headers ["location" ]
400
408
401
409
@patch .object (ResourceService , "delete_resource" )
402
- async def test_admin_delete_resource (self , mock_delete_resource , mock_db ):
410
+ async def test_admin_delete_resource (self , mock_delete_resource , mock_request , mock_db ):
403
411
"""Test deleting a resource through admin UI."""
404
- # Execute
405
- result = await admin_delete_resource ("/test/resource" , mock_db , "test-user" )
412
+ result = await admin_delete_resource ("/test/resource" , mock_request , mock_db , "test-user" )
406
413
407
- # Assert
408
414
mock_delete_resource .assert_called_once_with (mock_db , "/test/resource" )
409
415
assert isinstance (result , RedirectResponse )
410
416
assert result .status_code == 303
@@ -503,12 +509,10 @@ async def test_admin_toggle_prompt(self, mock_toggle_status, mock_request, mock_
503
509
assert "/admin#prompts" in result .headers ["location" ]
504
510
505
511
@patch .object (PromptService , "delete_prompt" )
506
- async def test_admin_delete_prompt (self , mock_delete_prompt , mock_db ):
512
+ async def test_admin_delete_prompt (self , mock_delete_prompt , mock_request , mock_db ):
507
513
"""Test deleting a prompt through admin UI."""
508
- # Execute
509
- result = await admin_delete_prompt ("test-prompt" , mock_db , "test-user" )
514
+ result = await admin_delete_prompt ("test-prompt" , mock_request , mock_db , "test-user" )
510
515
511
- # Assert
512
516
mock_delete_prompt .assert_called_once_with (mock_db , "test-prompt" )
513
517
assert isinstance (result , RedirectResponse )
514
518
assert result .status_code == 303
@@ -589,46 +593,39 @@ async def test_admin_toggle_gateway(self, mock_toggle_status, mock_request, mock
589
593
assert "/admin#gateways" in result .headers ["location" ]
590
594
591
595
@patch .object (GatewayService , "delete_gateway" )
592
- async def test_admin_delete_gateway (self , mock_delete_gateway , mock_db ):
596
+ async def test_admin_delete_gateway (self , mock_delete_gateway , mock_request , mock_db ):
593
597
"""Test deleting a gateway through admin UI."""
594
- # Execute
595
- result = await admin_delete_gateway (1 , mock_db , "test-user" )
598
+ result = await admin_delete_gateway (1 , mock_request , mock_db , "test-user" )
596
599
597
- # Assert
598
600
mock_delete_gateway .assert_called_once_with (mock_db , 1 )
599
601
assert isinstance (result , RedirectResponse )
600
602
assert result .status_code == 303
601
603
assert "/admin#gateways" in result .headers ["location" ]
602
604
603
-
604
605
class TestAdminRootRoutes :
605
606
"""Test admin routes for root management."""
606
607
607
- @patch . object ( RootService , " add_root" )
608
- async def test_admin_add_root (self , mock_add_root , mock_request , mock_db ):
608
+ @patch ( "mcpgateway.admin.root_service. add_root", new_callable = AsyncMock )
609
+ async def test_admin_add_root (self , mock_add_root , mock_request ):
609
610
"""Test adding a root through admin UI."""
610
- # Execute
611
- result = await admin_add_root (mock_request , mock_db , "test-user" )
611
+ result = await admin_add_root (mock_request , "test-user" )
612
612
613
- # Assert
614
- mock_add_root .assert_called_once_with ("/test/resource" , None )
613
+ # expect ("uri", "name") → "test-name" comes from the form fixture
614
+ mock_add_root .assert_called_once_with ("/test/resource" , "test-name" )
615
615
assert isinstance (result , RedirectResponse )
616
616
assert result .status_code == 303
617
617
assert "/admin#roots" in result .headers ["location" ]
618
618
619
- @patch . object ( RootService , " remove_root" )
620
- async def test_admin_delete_root (self , mock_remove_root , mock_db ):
619
+ @patch ( "mcpgateway.admin.root_service. remove_root", new_callable = AsyncMock )
620
+ async def test_admin_delete_root (self , mock_remove_root , mock_request ):
621
621
"""Test deleting a root through admin UI."""
622
- # Execute
623
- result = await admin_delete_root ("/test/root" , mock_db , "test-user" )
622
+ result = await admin_delete_root ("/test/root" , mock_request , "test-user" )
624
623
625
- # Assert
626
624
mock_remove_root .assert_called_once_with ("/test/root" )
627
625
assert isinstance (result , RedirectResponse )
628
626
assert result .status_code == 303
629
627
assert "/admin#roots" in result .headers ["location" ]
630
628
631
-
632
629
class TestAdminMetricsRoutes :
633
630
"""Test admin routes for metrics management."""
634
631
0 commit comments