Jeremiah Lowin commited on
Commit
20ffbf8
·
1 Parent(s): 7a8d3bf

Fix middleware tests

Browse files
src/fastmcp/server/server.py CHANGED
@@ -439,7 +439,6 @@ class FastMCP(Generic[LifespanResultT]):
439
  """
440
  List all available tools, in the format expected by the low-level MCP
441
  server.
442
-
443
  """
444
 
445
  async def _handler(
 
439
  """
440
  List all available tools, in the format expected by the low-level MCP
441
  server.
 
442
  """
443
 
444
  async def _handler(
tests/server/middleware/test_middleware.py CHANGED
@@ -70,16 +70,33 @@ class RecordingMiddleware(Middleware):
70
  return calls
71
 
72
  def assert_called(
73
- self, hook: str | None = None, method: str | None = None, times: int = 1
 
 
 
 
74
  ) -> bool:
75
  """Assert that a hook was called a specific number of times."""
 
 
 
 
 
 
76
  calls = self.get_calls(hook=hook, method=method)
77
  actual_times = len(calls)
78
  identifier = dict(hook=hook, method=method)
79
- assert actual_times == times, (
80
- f"Expected {times} calls for {identifier}, "
81
- f"but was called {actual_times} times"
82
- )
 
 
 
 
 
 
 
83
  return True
84
 
85
  def assert_not_called(self, hook: str | None = None, method: str | None = None):
@@ -154,11 +171,11 @@ class TestMiddlewareHooks:
154
  async with Client(mcp_server) as client:
155
  await client.call_tool("add", {"a": 1, "b": 2})
156
 
157
- assert recording_middleware.assert_called(times=3)
158
- assert recording_middleware.assert_called(method="tools/call", times=3)
159
- assert recording_middleware.assert_called(hook="on_message", times=1)
160
- assert recording_middleware.assert_called(hook="on_request", times=1)
161
- assert recording_middleware.assert_called(hook="on_call_tool", times=1)
162
 
163
  async def test_read_resource(
164
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
@@ -166,11 +183,11 @@ class TestMiddlewareHooks:
166
  async with Client(mcp_server) as client:
167
  await client.read_resource("resource://test")
168
 
169
- assert recording_middleware.assert_called(times=3)
170
- assert recording_middleware.assert_called(method="resources/read", times=3)
171
- assert recording_middleware.assert_called(hook="on_message", times=1)
172
- assert recording_middleware.assert_called(hook="on_request", times=1)
173
- assert recording_middleware.assert_called(hook="on_read_resource", times=1)
174
 
175
  async def test_read_resource_template(
176
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
@@ -178,11 +195,11 @@ class TestMiddlewareHooks:
178
  async with Client(mcp_server) as client:
179
  await client.read_resource("resource://test-template/1")
180
 
181
- assert recording_middleware.assert_called(times=3)
182
- assert recording_middleware.assert_called(method="resources/read", times=3)
183
- assert recording_middleware.assert_called(hook="on_message", times=1)
184
- assert recording_middleware.assert_called(hook="on_request", times=1)
185
- assert recording_middleware.assert_called(hook="on_read_resource", times=1)
186
 
187
  async def test_get_prompt(
188
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
@@ -190,11 +207,11 @@ class TestMiddlewareHooks:
190
  async with Client(mcp_server) as client:
191
  await client.get_prompt("test_prompt", {"x": "test"})
192
 
193
- assert recording_middleware.assert_called(times=3)
194
- assert recording_middleware.assert_called(method="prompts/get", times=3)
195
- assert recording_middleware.assert_called(hook="on_message", times=1)
196
- assert recording_middleware.assert_called(hook="on_request", times=1)
197
- assert recording_middleware.assert_called(hook="on_get_prompt", times=1)
198
 
199
  async def test_list_tools(
200
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
@@ -202,11 +219,11 @@ class TestMiddlewareHooks:
202
  async with Client(mcp_server) as client:
203
  await client.list_tools()
204
 
205
- assert recording_middleware.assert_called(times=3)
206
- assert recording_middleware.assert_called(method="tools/list", times=3)
207
- assert recording_middleware.assert_called(hook="on_message", times=1)
208
- assert recording_middleware.assert_called(hook="on_request", times=1)
209
- assert recording_middleware.assert_called(hook="on_list_tools", times=1)
210
 
211
  async def test_list_resources(
212
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
@@ -214,11 +231,11 @@ class TestMiddlewareHooks:
214
  async with Client(mcp_server) as client:
215
  await client.list_resources()
216
 
217
- assert recording_middleware.assert_called(times=3)
218
- assert recording_middleware.assert_called(method="resources/list", times=3)
219
- assert recording_middleware.assert_called(hook="on_message", times=1)
220
- assert recording_middleware.assert_called(hook="on_request", times=1)
221
- assert recording_middleware.assert_called(hook="on_list_resources", times=1)
222
 
223
  async def test_list_resource_templates(
224
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
@@ -226,14 +243,14 @@ class TestMiddlewareHooks:
226
  async with Client(mcp_server) as client:
227
  await client.list_resource_templates()
228
 
229
- assert recording_middleware.assert_called(times=3)
230
  assert recording_middleware.assert_called(
231
- method="resources/templates/list", times=3
232
  )
233
- assert recording_middleware.assert_called(hook="on_message", times=1)
234
- assert recording_middleware.assert_called(hook="on_request", times=1)
235
  assert recording_middleware.assert_called(
236
- hook="on_list_resource_templates", times=1
237
  )
238
 
239
  async def test_list_prompts(
@@ -242,11 +259,11 @@ class TestMiddlewareHooks:
242
  async with Client(mcp_server) as client:
243
  await client.list_prompts()
244
 
245
- assert recording_middleware.assert_called(times=3)
246
- assert recording_middleware.assert_called(method="prompts/list", times=3)
247
- assert recording_middleware.assert_called(hook="on_message", times=1)
248
- assert recording_middleware.assert_called(hook="on_request", times=1)
249
- assert recording_middleware.assert_called(hook="on_list_prompts", times=1)
250
 
251
 
252
  class TestNestedMiddlewareHooks:
@@ -303,13 +320,13 @@ class TestNestedMiddlewareHooks:
303
  async with Client(mcp_server) as client:
304
  await client.call_tool("add", {"a": 1, "b": 2})
305
 
306
- assert recording_middleware.assert_called(times=3)
307
- assert recording_middleware.assert_called(method="tools/call", times=3)
308
- assert recording_middleware.assert_called(hook="on_message", times=1)
309
- assert recording_middleware.assert_called(hook="on_request", times=1)
310
- assert recording_middleware.assert_called(hook="on_call_tool", times=1)
311
 
312
- assert nested_middleware.assert_called(times=0)
313
 
314
  async def test_call_tool_on_nested_server(
315
  self,
@@ -323,17 +340,17 @@ class TestNestedMiddlewareHooks:
323
  async with Client(mcp_server) as client:
324
  await client.call_tool("nested_add", {"a": 1, "b": 2})
325
 
326
- assert recording_middleware.assert_called(times=3)
327
- assert recording_middleware.assert_called(method="tools/call", times=3)
328
- assert recording_middleware.assert_called(hook="on_message", times=1)
329
- assert recording_middleware.assert_called(hook="on_request", times=1)
330
- assert recording_middleware.assert_called(hook="on_call_tool", times=1)
331
 
332
- assert nested_middleware.assert_called(times=3)
333
- assert nested_middleware.assert_called(method="tools/call", times=3)
334
- assert nested_middleware.assert_called(hook="on_message", times=1)
335
- assert nested_middleware.assert_called(hook="on_request", times=1)
336
- assert nested_middleware.assert_called(hook="on_call_tool", times=1)
337
 
338
  async def test_read_resource_on_parent_server(
339
  self,
@@ -347,11 +364,11 @@ class TestNestedMiddlewareHooks:
347
  async with Client(mcp_server) as client:
348
  await client.read_resource("resource://test")
349
 
350
- assert recording_middleware.assert_called(times=3)
351
- assert recording_middleware.assert_called(method="resources/read", times=3)
352
- assert recording_middleware.assert_called(hook="on_message", times=1)
353
- assert recording_middleware.assert_called(hook="on_request", times=1)
354
- assert recording_middleware.assert_called(hook="on_read_resource", times=1)
355
 
356
  assert nested_middleware.assert_called(times=0)
357
 
@@ -367,17 +384,17 @@ class TestNestedMiddlewareHooks:
367
  async with Client(mcp_server) as client:
368
  await client.read_resource("resource://nested/test")
369
 
370
- assert recording_middleware.assert_called(times=3)
371
- assert recording_middleware.assert_called(method="resources/read", times=3)
372
- assert recording_middleware.assert_called(hook="on_message", times=1)
373
- assert recording_middleware.assert_called(hook="on_request", times=1)
374
- assert recording_middleware.assert_called(hook="on_read_resource", times=1)
375
 
376
- assert nested_middleware.assert_called(times=3)
377
- assert nested_middleware.assert_called(method="resources/read", times=3)
378
- assert nested_middleware.assert_called(hook="on_message", times=1)
379
- assert nested_middleware.assert_called(hook="on_request", times=1)
380
- assert nested_middleware.assert_called(hook="on_read_resource", times=1)
381
 
382
  async def test_read_resource_template_on_parent_server(
383
  self,
@@ -391,11 +408,11 @@ class TestNestedMiddlewareHooks:
391
  async with Client(mcp_server) as client:
392
  await client.read_resource("resource://test-template/1")
393
 
394
- assert recording_middleware.assert_called(times=3)
395
- assert recording_middleware.assert_called(method="resources/read", times=3)
396
- assert recording_middleware.assert_called(hook="on_message", times=1)
397
- assert recording_middleware.assert_called(hook="on_request", times=1)
398
- assert recording_middleware.assert_called(hook="on_read_resource", times=1)
399
 
400
  assert nested_middleware.assert_called(times=0)
401
 
@@ -411,17 +428,17 @@ class TestNestedMiddlewareHooks:
411
  async with Client(mcp_server) as client:
412
  await client.read_resource("resource://nested/test-template/1")
413
 
414
- assert recording_middleware.assert_called(times=3)
415
- assert recording_middleware.assert_called(method="resources/read", times=3)
416
- assert recording_middleware.assert_called(hook="on_message", times=1)
417
- assert recording_middleware.assert_called(hook="on_request", times=1)
418
- assert recording_middleware.assert_called(hook="on_read_resource", times=1)
419
 
420
- assert nested_middleware.assert_called(times=3)
421
- assert nested_middleware.assert_called(method="resources/read", times=3)
422
- assert nested_middleware.assert_called(hook="on_message", times=1)
423
- assert nested_middleware.assert_called(hook="on_request", times=1)
424
- assert nested_middleware.assert_called(hook="on_read_resource", times=1)
425
 
426
  async def test_get_prompt_on_parent_server(
427
  self,
@@ -435,11 +452,11 @@ class TestNestedMiddlewareHooks:
435
  async with Client(mcp_server) as client:
436
  await client.get_prompt("test_prompt", {"x": "test"})
437
 
438
- assert recording_middleware.assert_called(times=3)
439
- assert recording_middleware.assert_called(method="prompts/get", times=3)
440
- assert recording_middleware.assert_called(hook="on_message", times=1)
441
- assert recording_middleware.assert_called(hook="on_request", times=1)
442
- assert recording_middleware.assert_called(hook="on_get_prompt", times=1)
443
 
444
  assert nested_middleware.assert_called(times=0)
445
 
@@ -455,17 +472,17 @@ class TestNestedMiddlewareHooks:
455
  async with Client(mcp_server) as client:
456
  await client.get_prompt("nested_test_prompt", {"x": "test"})
457
 
458
- assert recording_middleware.assert_called(times=3)
459
- assert recording_middleware.assert_called(method="prompts/get", times=3)
460
- assert recording_middleware.assert_called(hook="on_message", times=1)
461
- assert recording_middleware.assert_called(hook="on_request", times=1)
462
- assert recording_middleware.assert_called(hook="on_get_prompt", times=1)
463
 
464
- assert nested_middleware.assert_called(times=3)
465
- assert nested_middleware.assert_called(method="prompts/get", times=3)
466
- assert nested_middleware.assert_called(hook="on_message", times=1)
467
- assert nested_middleware.assert_called(hook="on_request", times=1)
468
- assert nested_middleware.assert_called(hook="on_get_prompt", times=1)
469
 
470
  async def test_list_tools_on_nested_server(
471
  self,
@@ -479,17 +496,17 @@ class TestNestedMiddlewareHooks:
479
  async with Client(mcp_server) as client:
480
  await client.list_tools()
481
 
482
- assert recording_middleware.assert_called(times=3)
483
- assert recording_middleware.assert_called(method="tools/list", times=3)
484
- assert recording_middleware.assert_called(hook="on_message", times=1)
485
- assert recording_middleware.assert_called(hook="on_request", times=1)
486
- assert recording_middleware.assert_called(hook="on_list_tools", times=1)
487
 
488
- assert nested_middleware.assert_called(times=3)
489
- assert nested_middleware.assert_called(method="tools/list", times=3)
490
- assert nested_middleware.assert_called(hook="on_message", times=1)
491
- assert nested_middleware.assert_called(hook="on_request", times=1)
492
- assert nested_middleware.assert_called(hook="on_list_tools", times=1)
493
 
494
  async def test_list_resources_on_nested_server(
495
  self,
@@ -503,17 +520,17 @@ class TestNestedMiddlewareHooks:
503
  async with Client(mcp_server) as client:
504
  await client.list_resources()
505
 
506
- assert recording_middleware.assert_called(times=3)
507
- assert recording_middleware.assert_called(method="resources/list", times=3)
508
- assert recording_middleware.assert_called(hook="on_message", times=1)
509
- assert recording_middleware.assert_called(hook="on_request", times=1)
510
- assert recording_middleware.assert_called(hook="on_list_resources", times=1)
511
 
512
- assert nested_middleware.assert_called(times=3)
513
- assert nested_middleware.assert_called(method="resources/list", times=3)
514
- assert nested_middleware.assert_called(hook="on_message", times=1)
515
- assert nested_middleware.assert_called(hook="on_request", times=1)
516
- assert nested_middleware.assert_called(hook="on_list_resources", times=1)
517
 
518
  async def test_list_resource_templates_on_nested_server(
519
  self,
@@ -527,24 +544,24 @@ class TestNestedMiddlewareHooks:
527
  async with Client(mcp_server) as client:
528
  await client.list_resource_templates()
529
 
530
- assert recording_middleware.assert_called(times=3)
531
  assert recording_middleware.assert_called(
532
- method="resources/templates/list", times=3
533
  )
534
- assert recording_middleware.assert_called(hook="on_message", times=1)
535
- assert recording_middleware.assert_called(hook="on_request", times=1)
536
  assert recording_middleware.assert_called(
537
- hook="on_list_resource_templates", times=1
538
  )
539
 
540
- assert nested_middleware.assert_called(times=3)
541
  assert nested_middleware.assert_called(
542
- method="resources/templates/list", times=3
543
  )
544
- assert nested_middleware.assert_called(hook="on_message", times=1)
545
- assert nested_middleware.assert_called(hook="on_request", times=1)
546
  assert nested_middleware.assert_called(
547
- hook="on_list_resource_templates", times=1
548
  )
549
 
550
 
@@ -558,10 +575,10 @@ class TestProxyServer:
558
  async with Client(proxy_server) as client:
559
  await client.call_tool("add", {"a": 1, "b": 2})
560
 
561
- assert recording_middleware.assert_called(times=6)
562
- assert recording_middleware.assert_called(method="tools/call", times=3)
563
- assert recording_middleware.assert_called(method="tools/list", times=3)
564
- assert recording_middleware.assert_called(hook="on_message", times=2)
565
- assert recording_middleware.assert_called(hook="on_request", times=2)
566
- assert recording_middleware.assert_called(hook="on_call_tool", times=1)
567
- assert recording_middleware.assert_called(hook="on_list_tools", times=1)
 
70
  return calls
71
 
72
  def assert_called(
73
+ self,
74
+ hook: str | None = None,
75
+ method: str | None = None,
76
+ times: int | None = None,
77
+ at_least: int | None = None,
78
  ) -> bool:
79
  """Assert that a hook was called a specific number of times."""
80
+
81
+ if times is not None and at_least is not None:
82
+ raise ValueError("Cannot specify both times and at_least")
83
+ elif times is None and at_least is None:
84
+ times = 1
85
+
86
  calls = self.get_calls(hook=hook, method=method)
87
  actual_times = len(calls)
88
  identifier = dict(hook=hook, method=method)
89
+
90
+ if times is not None:
91
+ assert actual_times == times, (
92
+ f"Expected {times} calls for {identifier}, "
93
+ f"but was called {actual_times} times"
94
+ )
95
+ elif at_least is not None:
96
+ assert actual_times >= at_least, (
97
+ f"Expected at least {at_least} calls for {identifier}, "
98
+ f"but was called {actual_times} times"
99
+ )
100
  return True
101
 
102
  def assert_not_called(self, hook: str | None = None, method: str | None = None):
 
171
  async with Client(mcp_server) as client:
172
  await client.call_tool("add", {"a": 1, "b": 2})
173
 
174
+ assert recording_middleware.assert_called(at_least=9)
175
+ assert recording_middleware.assert_called(method="tools/call", at_least=3)
176
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
177
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
178
+ assert recording_middleware.assert_called(hook="on_call_tool", at_least=1)
179
 
180
  async def test_read_resource(
181
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
 
183
  async with Client(mcp_server) as client:
184
  await client.read_resource("resource://test")
185
 
186
+ assert recording_middleware.assert_called(at_least=3)
187
+ assert recording_middleware.assert_called(method="resources/read", at_least=3)
188
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
189
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
190
+ assert recording_middleware.assert_called(hook="on_read_resource", at_least=1)
191
 
192
  async def test_read_resource_template(
193
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
 
195
  async with Client(mcp_server) as client:
196
  await client.read_resource("resource://test-template/1")
197
 
198
+ assert recording_middleware.assert_called(at_least=3)
199
+ assert recording_middleware.assert_called(method="resources/read", at_least=3)
200
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
201
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
202
+ assert recording_middleware.assert_called(hook="on_read_resource", at_least=1)
203
 
204
  async def test_get_prompt(
205
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
 
207
  async with Client(mcp_server) as client:
208
  await client.get_prompt("test_prompt", {"x": "test"})
209
 
210
+ assert recording_middleware.assert_called(at_least=3)
211
+ assert recording_middleware.assert_called(method="prompts/get", at_least=3)
212
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
213
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
214
+ assert recording_middleware.assert_called(hook="on_get_prompt", at_least=1)
215
 
216
  async def test_list_tools(
217
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
 
219
  async with Client(mcp_server) as client:
220
  await client.list_tools()
221
 
222
+ assert recording_middleware.assert_called(at_least=3)
223
+ assert recording_middleware.assert_called(method="tools/list", at_least=3)
224
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
225
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
226
+ assert recording_middleware.assert_called(hook="on_list_tools", at_least=1)
227
 
228
  async def test_list_resources(
229
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
 
231
  async with Client(mcp_server) as client:
232
  await client.list_resources()
233
 
234
+ assert recording_middleware.assert_called(at_least=3)
235
+ assert recording_middleware.assert_called(method="resources/list", at_least=3)
236
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
237
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
238
+ assert recording_middleware.assert_called(hook="on_list_resources", at_least=1)
239
 
240
  async def test_list_resource_templates(
241
  self, mcp_server: FastMCP, recording_middleware: RecordingMiddleware
 
243
  async with Client(mcp_server) as client:
244
  await client.list_resource_templates()
245
 
246
+ assert recording_middleware.assert_called(at_least=3)
247
  assert recording_middleware.assert_called(
248
+ method="resources/templates/list", at_least=3
249
  )
250
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
251
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
252
  assert recording_middleware.assert_called(
253
+ hook="on_list_resource_templates", at_least=1
254
  )
255
 
256
  async def test_list_prompts(
 
259
  async with Client(mcp_server) as client:
260
  await client.list_prompts()
261
 
262
+ assert recording_middleware.assert_called(at_least=3)
263
+ assert recording_middleware.assert_called(method="prompts/list", at_least=3)
264
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
265
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
266
+ assert recording_middleware.assert_called(hook="on_list_prompts", at_least=1)
267
 
268
 
269
  class TestNestedMiddlewareHooks:
 
320
  async with Client(mcp_server) as client:
321
  await client.call_tool("add", {"a": 1, "b": 2})
322
 
323
+ assert recording_middleware.assert_called(at_least=3)
324
+ assert recording_middleware.assert_called(method="tools/call", at_least=3)
325
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
326
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
327
+ assert recording_middleware.assert_called(hook="on_call_tool", at_least=1)
328
 
329
+ assert nested_middleware.assert_called(method="tools/call", times=0)
330
 
331
  async def test_call_tool_on_nested_server(
332
  self,
 
340
  async with Client(mcp_server) as client:
341
  await client.call_tool("nested_add", {"a": 1, "b": 2})
342
 
343
+ assert recording_middleware.assert_called(at_least=3)
344
+ assert recording_middleware.assert_called(method="tools/call", at_least=3)
345
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
346
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
347
+ assert recording_middleware.assert_called(hook="on_call_tool", at_least=1)
348
 
349
+ assert nested_middleware.assert_called(at_least=3)
350
+ assert nested_middleware.assert_called(method="tools/call", at_least=3)
351
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
352
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
353
+ assert nested_middleware.assert_called(hook="on_call_tool", at_least=1)
354
 
355
  async def test_read_resource_on_parent_server(
356
  self,
 
364
  async with Client(mcp_server) as client:
365
  await client.read_resource("resource://test")
366
 
367
+ assert recording_middleware.assert_called(at_least=3)
368
+ assert recording_middleware.assert_called(method="resources/read", at_least=3)
369
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
370
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
371
+ assert recording_middleware.assert_called(hook="on_read_resource", at_least=1)
372
 
373
  assert nested_middleware.assert_called(times=0)
374
 
 
384
  async with Client(mcp_server) as client:
385
  await client.read_resource("resource://nested/test")
386
 
387
+ assert recording_middleware.assert_called(at_least=3)
388
+ assert recording_middleware.assert_called(method="resources/read", at_least=3)
389
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
390
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
391
+ assert recording_middleware.assert_called(hook="on_read_resource", at_least=1)
392
 
393
+ assert nested_middleware.assert_called(at_least=3)
394
+ assert nested_middleware.assert_called(method="resources/read", at_least=3)
395
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
396
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
397
+ assert nested_middleware.assert_called(hook="on_read_resource", at_least=1)
398
 
399
  async def test_read_resource_template_on_parent_server(
400
  self,
 
408
  async with Client(mcp_server) as client:
409
  await client.read_resource("resource://test-template/1")
410
 
411
+ assert recording_middleware.assert_called(at_least=3)
412
+ assert recording_middleware.assert_called(method="resources/read", at_least=3)
413
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
414
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
415
+ assert recording_middleware.assert_called(hook="on_read_resource", at_least=1)
416
 
417
  assert nested_middleware.assert_called(times=0)
418
 
 
428
  async with Client(mcp_server) as client:
429
  await client.read_resource("resource://nested/test-template/1")
430
 
431
+ assert recording_middleware.assert_called(at_least=3)
432
+ assert recording_middleware.assert_called(method="resources/read", at_least=3)
433
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
434
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
435
+ assert recording_middleware.assert_called(hook="on_read_resource", at_least=1)
436
 
437
+ assert nested_middleware.assert_called(at_least=3)
438
+ assert nested_middleware.assert_called(method="resources/read", at_least=3)
439
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
440
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
441
+ assert nested_middleware.assert_called(hook="on_read_resource", at_least=1)
442
 
443
  async def test_get_prompt_on_parent_server(
444
  self,
 
452
  async with Client(mcp_server) as client:
453
  await client.get_prompt("test_prompt", {"x": "test"})
454
 
455
+ assert recording_middleware.assert_called(at_least=3)
456
+ assert recording_middleware.assert_called(method="prompts/get", at_least=3)
457
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
458
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
459
+ assert recording_middleware.assert_called(hook="on_get_prompt", at_least=1)
460
 
461
  assert nested_middleware.assert_called(times=0)
462
 
 
472
  async with Client(mcp_server) as client:
473
  await client.get_prompt("nested_test_prompt", {"x": "test"})
474
 
475
+ assert recording_middleware.assert_called(at_least=3)
476
+ assert recording_middleware.assert_called(method="prompts/get", at_least=3)
477
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
478
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
479
+ assert recording_middleware.assert_called(hook="on_get_prompt", at_least=1)
480
 
481
+ assert nested_middleware.assert_called(at_least=3)
482
+ assert nested_middleware.assert_called(method="prompts/get", at_least=3)
483
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
484
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
485
+ assert nested_middleware.assert_called(hook="on_get_prompt", at_least=1)
486
 
487
  async def test_list_tools_on_nested_server(
488
  self,
 
496
  async with Client(mcp_server) as client:
497
  await client.list_tools()
498
 
499
+ assert recording_middleware.assert_called(at_least=3)
500
+ assert recording_middleware.assert_called(method="tools/list", at_least=3)
501
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
502
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
503
+ assert recording_middleware.assert_called(hook="on_list_tools", at_least=1)
504
 
505
+ assert nested_middleware.assert_called(at_least=3)
506
+ assert nested_middleware.assert_called(method="tools/list", at_least=3)
507
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
508
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
509
+ assert nested_middleware.assert_called(hook="on_list_tools", at_least=1)
510
 
511
  async def test_list_resources_on_nested_server(
512
  self,
 
520
  async with Client(mcp_server) as client:
521
  await client.list_resources()
522
 
523
+ assert recording_middleware.assert_called(at_least=3)
524
+ assert recording_middleware.assert_called(method="resources/list", at_least=3)
525
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
526
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
527
+ assert recording_middleware.assert_called(hook="on_list_resources", at_least=1)
528
 
529
+ assert nested_middleware.assert_called(at_least=3)
530
+ assert nested_middleware.assert_called(method="resources/list", at_least=3)
531
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
532
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
533
+ assert nested_middleware.assert_called(hook="on_list_resources", at_least=1)
534
 
535
  async def test_list_resource_templates_on_nested_server(
536
  self,
 
544
  async with Client(mcp_server) as client:
545
  await client.list_resource_templates()
546
 
547
+ assert recording_middleware.assert_called(at_least=3)
548
  assert recording_middleware.assert_called(
549
+ method="resources/templates/list", at_least=3
550
  )
551
+ assert recording_middleware.assert_called(hook="on_message", at_least=1)
552
+ assert recording_middleware.assert_called(hook="on_request", at_least=1)
553
  assert recording_middleware.assert_called(
554
+ hook="on_list_resource_templates", at_least=1
555
  )
556
 
557
+ assert nested_middleware.assert_called(at_least=3)
558
  assert nested_middleware.assert_called(
559
+ method="resources/templates/list", at_least=3
560
  )
561
+ assert nested_middleware.assert_called(hook="on_message", at_least=1)
562
+ assert nested_middleware.assert_called(hook="on_request", at_least=1)
563
  assert nested_middleware.assert_called(
564
+ hook="on_list_resource_templates", at_least=1
565
  )
566
 
567
 
 
575
  async with Client(proxy_server) as client:
576
  await client.call_tool("add", {"a": 1, "b": 2})
577
 
578
+ assert recording_middleware.assert_called(at_least=6)
579
+ assert recording_middleware.assert_called(method="tools/call", at_least=3)
580
+ assert recording_middleware.assert_called(method="tools/list", at_least=3)
581
+ assert recording_middleware.assert_called(hook="on_message", at_least=2)
582
+ assert recording_middleware.assert_called(hook="on_request", at_least=2)
583
+ assert recording_middleware.assert_called(hook="on_call_tool", at_least=1)
584
+ assert recording_middleware.assert_called(hook="on_list_tools", at_least=1)