@@ -1006,6 +1006,76 @@ def test_get_run_with_results(
10061006 assert "Hello world" in texts
10071007 assert "Good morning" in texts
10081008
1009+ @patch ("app.api.routes.tts_evaluations.evaluation.get_cloud_storage" )
1010+ def test_get_run_with_signed_urls_and_null_object_store_url (
1011+ self ,
1012+ mock_get_cloud_storage : MagicMock ,
1013+ client : TestClient ,
1014+ user_api_key_header : dict [str , str ],
1015+ db : Session ,
1016+ user_api_key : TestAuthContext ,
1017+ test_dataset_with_samples : EvaluationDataset ,
1018+ ) -> None :
1019+ """Test that signed URL generation handles results with null object_store_url."""
1020+ dataset = test_dataset_with_samples
1021+
1022+ mock_storage = MagicMock ()
1023+ mock_storage .get_signed_url .return_value = (
1024+ "https://signed-url.example.com/audio.wav"
1025+ )
1026+ mock_get_cloud_storage .return_value = mock_storage
1027+
1028+ run = create_tts_run (
1029+ session = db ,
1030+ run_name = "signed_url_null_test" ,
1031+ dataset_id = dataset .id ,
1032+ dataset_name = dataset .name ,
1033+ org_id = user_api_key .organization_id ,
1034+ project_id = user_api_key .project_id ,
1035+ models = ["gemini-2.5-pro-preview-tts" ],
1036+ total_items = 2 ,
1037+ )
1038+
1039+ # Result with valid S3 URL
1040+ create_test_tts_result (
1041+ db = db ,
1042+ evaluation_run_id = run .id ,
1043+ organization_id = user_api_key .organization_id ,
1044+ project_id = user_api_key .project_id ,
1045+ sample_text = "Completed result" ,
1046+ status = JobStatus .SUCCESS .value ,
1047+ object_store_url = "s3://bucket/audio/test.wav" ,
1048+ )
1049+ # Result with null object_store_url (failed)
1050+ create_test_tts_result (
1051+ db = db ,
1052+ evaluation_run_id = run .id ,
1053+ organization_id = user_api_key .organization_id ,
1054+ project_id = user_api_key .project_id ,
1055+ sample_text = "Failed result" ,
1056+ status = JobStatus .FAILED .value ,
1057+ object_store_url = None ,
1058+ )
1059+
1060+ response = client .get (
1061+ f"/api/v1/evaluations/tts/runs/{ run .id } " ,
1062+ params = {"include_results" : True , "include_signed_url" : True },
1063+ headers = user_api_key_header ,
1064+ )
1065+
1066+ assert response .status_code == 200 , response .text
1067+ data = response .json ()["data" ]
1068+ assert data ["results_total" ] == 2
1069+
1070+ results_by_text = {r ["sample_text" ]: r for r in data ["results" ]}
1071+ assert results_by_text ["Completed result" ]["signed_url" ] is not None
1072+ assert results_by_text ["Failed result" ]["signed_url" ] is None
1073+
1074+ # get_signed_url should only be called for the result with a valid URL
1075+ mock_storage .get_signed_url .assert_called_once_with (
1076+ "s3://bucket/audio/test.wav"
1077+ )
1078+
10091079 def test_get_run_without_results (
10101080 self ,
10111081 client : TestClient ,
0 commit comments