33from unittest .mock import AsyncMock , MagicMock , patch
44
55import pytest
6- from a2a .types import UnsupportedOperationError
6+ from a2a .types import InternalError , UnsupportedOperationError
77from a2a .utils .errors import ServerError
88
99from strands .agent .agent_result import AgentResult as SAAgentResult
@@ -56,8 +56,6 @@ def test_get_file_format_from_mime_type():
5656 # Test document formats
5757 assert executor ._get_file_format_from_mime_type ("application/pdf" , "document" ) == "pdf"
5858 assert executor ._get_file_format_from_mime_type ("text/plain" , "document" ) == "txt"
59- markdown_result = executor ._get_file_format_from_mime_type ("text/markdown" , "document" )
60- assert markdown_result in ["markdown" , "md" ]
6159 assert executor ._get_file_format_from_mime_type ("application/unknown" , "document" ) == "txt"
6260
6361 # Test None/empty cases
@@ -490,15 +488,7 @@ async def mock_stream(content_blocks):
490488async def test_execute_streaming_mode_fallback_to_text_extraction (
491489 mock_strands_agent , mock_request_context , mock_event_queue
492490):
493- """Test that execute falls back to text extraction when no A2A parts are available."""
494-
495- async def mock_stream (content_blocks ):
496- """Mock streaming function that yields data events."""
497- yield {"data" : "Test chunk" }
498- yield {"result" : MagicMock (spec = SAAgentResult )}
499-
500- # Setup mock agent streaming
501- mock_strands_agent .stream_async = MagicMock (return_value = mock_stream ([]))
491+ """Test that execute raises ServerError when no A2A parts are available."""
502492
503493 # Create executor
504494 executor = StrandsA2AExecutor (mock_strands_agent )
@@ -515,14 +505,11 @@ async def mock_stream(content_blocks):
515505 mock_request_context .message = mock_message
516506 mock_request_context .get_user_input .return_value = "Fallback input"
517507
518- await executor .execute (mock_request_context , mock_event_queue )
508+ with pytest .raises (ServerError ) as excinfo :
509+ await executor .execute (mock_request_context , mock_event_queue )
519510
520- # Verify agent was called with fallback ContentBlock
521- mock_strands_agent .stream_async .assert_called_once ()
522- call_args = mock_strands_agent .stream_async .call_args [0 ][0 ]
523- assert isinstance (call_args , list )
524- assert len (call_args ) == 1
525- assert call_args [0 ]["text" ] == "Fallback input"
511+ # Verify the error is a ServerError containing an InternalError
512+ assert isinstance (excinfo .value .error , InternalError )
526513
527514
528515@pytest .mark .asyncio
@@ -825,6 +812,26 @@ def non_serializable():
825812 assert isinstance (result , list )
826813
827814
815+ @pytest .mark .asyncio
816+ async def test_execute_streaming_mode_raises_error_for_empty_content_blocks (mock_strands_agent , mock_event_queue , mock_request_context ):
817+ """Test that execute raises ServerError when content blocks are empty after conversion."""
818+ executor = StrandsA2AExecutor (mock_strands_agent )
819+
820+ # Create a mock message with parts that will result in empty content blocks
821+ # This could happen if all parts fail to convert or are invalid
822+ mock_message = MagicMock ()
823+ mock_message .parts = [MagicMock ()] # Has parts but they won't convert to valid content blocks
824+ mock_request_context .message = mock_message
825+
826+ # Mock the conversion to return empty list
827+ with patch .object (executor , '_convert_a2a_parts_to_content_blocks' , return_value = []):
828+ with pytest .raises (ServerError ) as excinfo :
829+ await executor .execute (mock_request_context , mock_event_queue )
830+
831+ # Verify the error is a ServerError containing an InternalError
832+ assert isinstance (excinfo .value .error , InternalError )
833+
834+
828835@pytest .mark .asyncio
829836async def test_execute_with_mixed_part_types (mock_strands_agent , mock_request_context , mock_event_queue ):
830837 """Test execute with a message containing mixed A2A part types."""
0 commit comments