11"""Test report_missing functionality."""
22
33import pytest
4+ from unittest .mock import MagicMock
5+ import time
46
57from mcpcat import MCPCatOptions , track
68
@@ -285,4 +287,133 @@ async def test_report_missing_with_invalid_types(self):
285287 )
286288 # Should convert to string and work
287289 assert result .content [0 ].text
288- assert "12345" in result .content [0 ].text
290+ assert "12345" in result .content [0 ].text
291+
292+ @pytest .mark .asyncio
293+ async def test_report_missing_publishes_event (self ):
294+ """Verify that calling report_missing tool publishes an event to the queue."""
295+ from mcpcat .modules .event_queue import EventQueue , set_event_queue
296+
297+ # Create a mock API client
298+ mock_api_client = MagicMock ()
299+ mock_api_client .publish_event = MagicMock (return_value = None )
300+
301+ # Create a new EventQueue with our mock
302+ test_queue = EventQueue (api_client = mock_api_client )
303+
304+ # Replace the global event queue
305+ set_event_queue (test_queue )
306+
307+ try :
308+ server = create_todo_server ()
309+ options = MCPCatOptions (enable_report_missing = True , enable_tracing = True )
310+ track (server , "test_project" , options )
311+
312+ async with create_test_client (server ) as client :
313+ # Call the report_missing tool
314+ await client .call_tool (
315+ "report_missing" ,
316+ {
317+ "missing_tool" : "image_resize" ,
318+ "description" : "Need to resize images to different dimensions"
319+ }
320+ )
321+
322+ # Give the event queue worker thread time to process
323+ time .sleep (1.0 )
324+
325+ # Verify that publish_event was called
326+ assert mock_api_client .publish_event .called
327+ assert mock_api_client .publish_event .call_count >= 1 # At least one call
328+
329+ # Find the tool call event
330+ tool_call_event = None
331+ for call in mock_api_client .publish_event .call_args_list :
332+ event = call [1 ]["publish_event_request" ]
333+ if event .event_type == "mcp:tools/call" and event .resource_name == "report_missing" :
334+ tool_call_event = event
335+ break
336+
337+ assert tool_call_event is not None , "No report_missing tool call event found"
338+
339+ # Verify event properties
340+ assert tool_call_event .project_id == "test_project"
341+
342+ # Verify the arguments contain our input
343+ assert tool_call_event .parameters ["arguments" ]["missing_tool" ] == "image_resize"
344+ assert tool_call_event .parameters ["arguments" ]["description" ] == "Need to resize images to different dimensions"
345+
346+ finally :
347+ # Clean up: restore original event queue
348+ from mcpcat .modules .event_queue import EventQueue , set_event_queue
349+ set_event_queue (EventQueue ())
350+
351+ @pytest .mark .asyncio
352+ async def test_multiple_tool_calls_publish_multiple_events (self ):
353+ """Verify that multiple tool calls result in multiple events being published."""
354+ from mcpcat .modules .event_queue import EventQueue , set_event_queue
355+
356+ # Create a mock API client
357+ mock_api_client = MagicMock ()
358+ mock_api_client .publish_event = MagicMock (return_value = None )
359+
360+ # Create a new EventQueue with our mock
361+ test_queue = EventQueue (api_client = mock_api_client )
362+
363+ # Replace the global event queue
364+ set_event_queue (test_queue )
365+
366+ try :
367+ server = create_todo_server ()
368+ options = MCPCatOptions (enable_report_missing = True , enable_tracing = True )
369+ track (server , "test_project" , options )
370+
371+ async with create_test_client (server ) as client :
372+ # Call report_missing tool
373+ await client .call_tool (
374+ "report_missing" ,
375+ {"missing_tool" : "tool1" , "description" : "desc1" }
376+ )
377+
378+ # Call a regular tool
379+ await client .call_tool (
380+ "add_todo" ,
381+ {"text" : "Test todo item" }
382+ )
383+
384+ # Call report_missing again
385+ await client .call_tool (
386+ "report_missing" ,
387+ {"missing_tool" : "tool2" , "description" : "desc2" }
388+ )
389+
390+ # Allow time for processing
391+ import time
392+ time .sleep (1.0 )
393+
394+ # Should have at least 3 tool call events (plus initialize and list_tools events)
395+ assert mock_api_client .publish_event .call_count >= 3
396+
397+ # Get all published events
398+ events = [call [1 ]["publish_event_request" ] for call in mock_api_client .publish_event .call_args_list ]
399+
400+ # Filter to just tool call events
401+ tool_events = [e for e in events if e .event_type == "mcp:tools/call" ]
402+
403+ # Should have exactly 3 tool calls
404+ assert len (tool_events ) == 3
405+
406+ # Verify event types and tool names
407+ assert tool_events [0 ].resource_name == "report_missing"
408+ assert tool_events [0 ].parameters ["arguments" ]["missing_tool" ] == "tool1"
409+
410+ assert tool_events [1 ].resource_name == "add_todo"
411+ assert tool_events [1 ].parameters ["arguments" ]["text" ] == "Test todo item"
412+
413+ assert tool_events [2 ].resource_name == "report_missing"
414+ assert tool_events [2 ].parameters ["arguments" ]["missing_tool" ] == "tool2"
415+
416+ finally :
417+ # Clean up: restore original event queue
418+ from mcpcat .modules .event_queue import EventQueue , set_event_queue
419+ set_event_queue (EventQueue ())
0 commit comments