Skip to content

Commit 132df57

Browse files
committed
✨ Unit test: Truncation information of files that are too large is displayed to the user #1119
1 parent ac11152 commit 132df57

File tree

4 files changed

+725
-99
lines changed

4 files changed

+725
-99
lines changed

backend/services/file_management_service.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,12 @@ async def process_image_file(query: str, filename: str, file_content: bytes, ten
284284
"""
285285
Process image file, convert to text using external API
286286
"""
287-
image_stream = BytesIO(file_content)
288-
text = convert_image_to_text(query, image_stream, tenant_id, language)
289-
290-
return f"Image file {filename} content: {text}"
287+
try:
288+
image_stream = BytesIO(file_content)
289+
text = convert_image_to_text(query, image_stream, tenant_id, language)
290+
return f"Image file {filename} content: {text}"
291+
except Exception as e:
292+
return f"Image file {filename} content: Error processing image file {filename}: {str(e)}"
291293

292294

293295
async def process_text_file(query: str, filename: str, file_content: bytes, tenant_id: str, language: str = 'zh') -> tuple[str, Optional[str]]:
@@ -325,16 +327,22 @@ async def process_text_file(query: str, filename: str, file_content: bytes, tena
325327
f"File processing failed (status code: {response.status_code}): {error_detail}")
326328

327329
except Exception as e:
328-
raise Exception(f"Error processing file: {str(e)}")
330+
return f"File {filename} content: Error processing text file {filename}: {str(e)}", None
329331

330-
text, truncation_percentage = convert_long_text_to_text(query, raw_text, tenant_id, language)
331-
return f"File {filename} content: {text}", truncation_percentage
332+
try:
333+
text, truncation_percentage = convert_long_text_to_text(query, raw_text, tenant_id, language)
334+
return f"File {filename} content: {text}", truncation_percentage
335+
except Exception as e:
336+
return f"File {filename} content: Error processing text file {filename}: {str(e)}", None
332337

333338

334339
def get_file_description(files: List[UploadFile]) -> str:
335340
"""
336341
Generate file description text
337342
"""
343+
if not files:
344+
return "User provided some reference files:\nNo files provided"
345+
338346
description = "User provided some reference files:\n"
339347
for file in files:
340348
ext = os.path.splitext(file.filename or "")[1].lower()

test/backend/app/test_file_management_app.py

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -545,85 +545,6 @@ async def mock_generator(*args, **kwargs):
545545
assert response is not None
546546

547547

548-
@pytest.mark.asyncio
549-
async def test_process_image_file(mock_files):
550-
# Import directly in the test to use the already established mocks
551-
from backend.services.file_management_service import process_image_file
552-
553-
with patch("backend.services.file_management_service.convert_image_to_text") as mock_convert:
554-
# Configure mock
555-
mock_convert.return_value = "Extracted text from image"
556-
557-
# Test the function
558-
result = await process_image_file(
559-
query="Test query",
560-
filename="test.jpg",
561-
file_content=mock_files["mock_image_content"],
562-
tenant_id="tenant123"
563-
)
564-
565-
# Assertions
566-
assert "Image file test.jpg content" in result
567-
assert "Extracted text from image" in result
568-
569-
570-
@pytest.mark.asyncio
571-
async def test_process_text_file(mock_files):
572-
# Import directly in the test to use the already established mocks
573-
from backend.services.file_management_service import process_text_file
574-
575-
# Mock multiple functions to ensure complete coverage of all call paths
576-
with patch('backend.utils.config_utils.get_model_name_from_config', return_value="test-model"), \
577-
patch('backend.utils.attachment_utils.get_model_name_from_config', return_value="test-model"), \
578-
patch('backend.utils.attachment_utils.convert_long_text_to_text', return_value="Processed text content"), \
579-
patch('backend.services.file_management_service.convert_long_text_to_text', return_value="Processed text content"):
580-
581-
with patch('httpx.AsyncClient') as mock_client:
582-
# Setup mock response for httpx client
583-
mock_response = MagicMock()
584-
mock_response.status_code = 200
585-
mock_response.json.return_value = {
586-
"text": "Extracted raw text from file"}
587-
588-
mock_client_instance = MagicMock()
589-
mock_client_instance.post.return_value = asyncio.Future()
590-
mock_client_instance.post.return_value.set_result(mock_response)
591-
mock_client.return_value.__aenter__.return_value = mock_client_instance
592-
593-
# Test the function
594-
result, truncation_percentage = await process_text_file(
595-
query="Test query",
596-
filename="test.txt",
597-
file_content=mock_files["mock_file_content"],
598-
tenant_id="tenant123",
599-
language="en"
600-
)
601-
602-
# Assertions
603-
assert "File test.txt content" in result
604-
assert truncation_percentage is None
605-
606-
607-
def test_get_file_description(mock_files):
608-
# Import directly in the test to use the already established mocks
609-
from backend.services.file_management_service import get_file_description
610-
611-
# Create mock UploadFile objects
612-
text_file = MagicMock()
613-
text_file.filename = "document.txt"
614-
615-
image_file = MagicMock()
616-
image_file.filename = "photo.jpg"
617-
618-
# Test the function
619-
result = get_file_description([text_file, image_file])
620-
621-
# Assertions
622-
assert "User provided some reference files" in result
623-
assert "Image file photo.jpg" in result
624-
assert "File document.txt" in result
625-
626-
627548
def test_options_route():
628549
# Create test client
629550
with TestClient(app) as client:

0 commit comments

Comments
 (0)