@@ -324,38 +324,38 @@ async def test_tool_audio_helper(self, tmp_path: Path):
324324 # Check structured content - Image return type should NOT have structured output
325325 assert result .structuredContent is None
326326
327- @pytest .mark .anyio
328- async def test_tool_audio_suffix_detection (self , tmp_path : Path ):
329- # Test different audio file extensions
330- test_cases = [
327+ @pytest .mark .parametrize (
328+ "filename,expected_mime_type" ,
329+ [
331330 ("test.wav" , "audio/wav" ),
332331 ("test.mp3" , "audio/mpeg" ),
333332 ("test.ogg" , "audio/ogg" ),
334333 ("test.flac" , "audio/flac" ),
335334 ("test.aac" , "audio/aac" ),
336335 ("test.m4a" , "audio/mp4" ),
337336 ("test.unknown" , "application/octet-stream" ), # Unknown extension fallback
338- ]
339-
337+ ],
338+ )
339+ @pytest .mark .anyio
340+ async def test_tool_audio_suffix_detection (self , tmp_path : Path , filename : str , expected_mime_type : str ):
341+ """Test that Audio helper correctly detects MIME types from file suffixes"""
340342 mcp = FastMCP ()
341343 mcp .add_tool (audio_tool_fn )
342- async with client_session (mcp ._mcp_server ) as client :
343- for filename , expected_mime_type in test_cases :
344- # Create a test audio file with the specific extension
345- audio_path = tmp_path / filename
346- audio_path .write_bytes (b"fake audio data" )
344+
345+ # Create a test audio file with the specific extension
346+ audio_path = tmp_path / filename
347+ audio_path .write_bytes (b"fake audio data" )
347348
348- result = await client .call_tool ("audio_tool_fn" , {"path" : str (audio_path )})
349- assert len (result .content ) == 1
350- content = result .content [0 ]
351- assert isinstance (content , AudioContent )
352- assert content .type == "audio"
353- assert content .mimeType == expected_mime_type , (
354- f"Expected { expected_mime_type } for { filename } , got { content .mimeType } "
355- )
356- # Verify base64 encoding
357- decoded = base64 .b64decode (content .data )
358- assert decoded == b"fake audio data"
349+ async with client_session (mcp ._mcp_server ) as client :
350+ result = await client .call_tool ("audio_tool_fn" , {"path" : str (audio_path )})
351+ assert len (result .content ) == 1
352+ content = result .content [0 ]
353+ assert isinstance (content , AudioContent )
354+ assert content .type == "audio"
355+ assert content .mimeType == expected_mime_type
356+ # Verify base64 encoding
357+ decoded = base64 .b64decode (content .data )
358+ assert decoded == b"fake audio data"
359359
360360 @pytest .mark .anyio
361361 async def test_tool_mixed_content (self ):
@@ -389,17 +389,22 @@ async def test_tool_mixed_content(self):
389389 assert structured_result [i ][key ] == value
390390
391391 @pytest .mark .anyio
392- async def test_tool_mixed_list_with_image (self , tmp_path : Path ):
392+ async def test_tool_mixed_list_with_audio_and_image (self , tmp_path : Path ):
393393 """Test that lists containing Image objects and other types are handled
394394 correctly"""
395395 # Create a test image
396396 image_path = tmp_path / "test.png"
397397 image_path .write_bytes (b"test image data" )
398398
399+ # Create a test audio
400+ audio_path = tmp_path / "test.wav"
401+ audio_path .write_bytes (b"test audio data" )
402+
399403 def mixed_list_fn () -> list :
400404 return [
401405 "text message" ,
402406 Image (image_path ),
407+ Audio (audio_path ),
403408 {"key" : "value" },
404409 TextContent (type = "text" , text = "direct content" ),
405410 ]
@@ -418,56 +423,20 @@ def mixed_list_fn() -> list:
418423 assert isinstance (content2 , ImageContent )
419424 assert content2 .mimeType == "image/png"
420425 assert base64 .b64decode (content2 .data ) == b"test image data"
421- # Check dict conversion
422- content3 = result .content [2 ]
423- assert isinstance (content3 , TextContent )
424- assert '"key": "value"' in content3 .text
425- # Check direct TextContent
426- content4 = result .content [3 ]
427- assert isinstance (content4 , TextContent )
428- assert content4 .text == "direct content"
429- # Check structured content - untyped list with Image objects should NOT have structured output
430- assert result .structuredContent is None
431-
432- @pytest .mark .anyio
433- async def test_tool_mixed_list_with_audio (self , tmp_path : Path ):
434- """Test that lists containing Audio objects and other types are handled
435- correctly"""
436- # Create a test audio
437- audio_path = tmp_path / "test.wav"
438- audio_path .write_bytes (b"test audio data" )
439-
440- def mixed_list_fn () -> list :
441- return [
442- "text message" ,
443- Audio (audio_path ),
444- {"key" : "value" },
445- TextContent (type = "text" , text = "direct content" ),
446- ]
447-
448- mcp = FastMCP ()
449- mcp .add_tool (mixed_list_fn )
450- async with client_session (mcp ._mcp_server ) as client :
451- result = await client .call_tool ("mixed_list_fn" , {})
452- assert len (result .content ) == 4
453- # Check text conversion
454- content1 = result .content [0 ]
455- assert isinstance (content1 , TextContent )
456- assert content1 .text == "text message"
457426 # Check audio conversion
458- content2 = result .content [1 ]
459- assert isinstance (content2 , AudioContent )
460- assert content2 .mimeType == "audio/wav"
461- assert base64 .b64decode (content2 .data ) == b"test audio data"
462- # Check dict conversion
463427 content3 = result .content [2 ]
464- assert isinstance (content3 , TextContent )
465- assert '"key": "value"' in content3 .text
466- # Check direct TextContent
428+ assert isinstance (content3 , AudioContent )
429+ assert content3 .mimeType == "audio/wav"
430+ assert base64 .b64decode (content3 .data ) == b"test audio data"
431+ # Check dict conversion
467432 content4 = result .content [3 ]
468433 assert isinstance (content4 , TextContent )
469- assert content4 .text == "direct content"
470- # Check structured content - untyped list with Audio objects should NOT have structured output
434+ assert '"key": "value"' in content4 .text
435+ # Check direct TextContent
436+ content5 = result .content [4 ]
437+ assert isinstance (content5 , TextContent )
438+ assert content5 .text == "direct content"
439+ # Check structured content - untyped list with Image objects should NOT have structured output
471440 assert result .structuredContent is None
472441
473442 @pytest .mark .anyio
0 commit comments