Spaces:
Build error
Build error
"""Unit tests for ProcessingResultDto""" | |
import pytest | |
from datetime import datetime | |
from src.application.dtos.processing_result_dto import ProcessingResultDto | |
class TestProcessingResultDto: | |
"""Test cases for ProcessingResultDto""" | |
def test_valid_success_processing_result_dto(self): | |
"""Test creating a valid successful ProcessingResultDto""" | |
dto = ProcessingResultDto( | |
success=True, | |
original_text="Hello world", | |
translated_text="Hola mundo", | |
audio_path="/tmp/output.wav", | |
processing_time=5.2, | |
metadata={"correlation_id": "test-123"} | |
) | |
assert dto.success is True | |
assert dto.original_text == "Hello world" | |
assert dto.translated_text == "Hola mundo" | |
assert dto.audio_path == "/tmp/output.wav" | |
assert dto.processing_time == 5.2 | |
assert dto.metadata == {"correlation_id": "test-123"} | |
assert dto.error_message is None | |
assert dto.error_code is None | |
assert isinstance(dto.timestamp, datetime) | |
def test_valid_error_processing_result_dto(self): | |
"""Test creating a valid error ProcessingResultDto""" | |
dto = ProcessingResultDto( | |
success=False, | |
error_message="Processing failed", | |
error_code="STT_ERROR", | |
processing_time=2.1, | |
metadata={"correlation_id": "test-456"} | |
) | |
assert dto.success is False | |
assert dto.error_message == "Processing failed" | |
assert dto.error_code == "STT_ERROR" | |
assert dto.processing_time == 2.1 | |
assert dto.metadata == {"correlation_id": "test-456"} | |
assert dto.original_text is None | |
assert dto.translated_text is None | |
assert dto.audio_path is None | |
assert isinstance(dto.timestamp, datetime) | |
def test_processing_result_dto_with_defaults(self): | |
"""Test creating ProcessingResultDto with default values""" | |
dto = ProcessingResultDto(success=True, original_text="Test") | |
assert dto.success is True | |
assert dto.original_text == "Test" | |
assert dto.translated_text is None | |
assert dto.audio_path is None | |
assert dto.processing_time == 0.0 | |
assert dto.error_message is None | |
assert dto.error_code is None | |
assert dto.metadata == {} | |
assert isinstance(dto.timestamp, datetime) | |
def test_processing_result_dto_with_explicit_timestamp(self): | |
"""Test creating ProcessingResultDto with explicit timestamp""" | |
test_timestamp = datetime(2023, 1, 1, 12, 0, 0) | |
dto = ProcessingResultDto( | |
success=True, | |
original_text="Test", | |
timestamp=test_timestamp | |
) | |
assert dto.timestamp == test_timestamp | |
def test_invalid_success_type_validation(self): | |
"""Test validation with invalid success type""" | |
with pytest.raises(ValueError, match="Success must be a boolean value"): | |
ProcessingResultDto( | |
success="true", # String instead of boolean | |
original_text="Test" | |
) | |
def test_negative_processing_time_validation(self): | |
"""Test validation with negative processing time""" | |
with pytest.raises(ValueError, match="Processing time cannot be negative"): | |
ProcessingResultDto( | |
success=True, | |
original_text="Test", | |
processing_time=-1.0 | |
) | |
def test_successful_processing_without_output_validation(self): | |
"""Test validation for successful processing without any output""" | |
with pytest.raises(ValueError, match="Successful processing must have at least one output"): | |
ProcessingResultDto( | |
success=True, | |
# No original_text, translated_text, or audio_path | |
) | |
def test_failed_processing_without_error_message_validation(self): | |
"""Test validation for failed processing without error message""" | |
with pytest.raises(ValueError, match="Failed processing must include an error message"): | |
ProcessingResultDto( | |
success=False, | |
# No error_message | |
) | |
def test_invalid_error_code_validation(self): | |
"""Test validation with invalid error code""" | |
with pytest.raises(ValueError, match="Invalid error code"): | |
ProcessingResultDto( | |
success=False, | |
error_message="Test error", | |
error_code="INVALID_CODE" | |
) | |
def test_valid_error_codes(self): | |
"""Test all valid error codes""" | |
valid_error_codes = [ | |
'STT_ERROR', 'TRANSLATION_ERROR', 'TTS_ERROR', | |
'AUDIO_FORMAT_ERROR', 'VALIDATION_ERROR', 'SYSTEM_ERROR' | |
] | |
for error_code in valid_error_codes: | |
# Should not raise exception | |
dto = ProcessingResultDto( | |
success=False, | |
error_message="Test error", | |
error_code=error_code | |
) | |
assert dto.error_code == error_code | |
def test_invalid_metadata_type_validation(self): | |
"""Test validation with invalid metadata type""" | |
with pytest.raises(ValueError, match="Metadata must be a dictionary"): | |
ProcessingResultDto( | |
success=True, | |
original_text="Test", | |
metadata="invalid" # String instead of dict | |
) | |
def test_has_text_output_property(self): | |
"""Test has_text_output property""" | |
# With original text only | |
dto1 = ProcessingResultDto(success=True, original_text="Test") | |
assert dto1.has_text_output is True | |
# With translated text only | |
dto2 = ProcessingResultDto(success=True, translated_text="Prueba") | |
assert dto2.has_text_output is True | |
# With both texts | |
dto3 = ProcessingResultDto(success=True, original_text="Test", translated_text="Prueba") | |
assert dto3.has_text_output is True | |
# With no text | |
dto4 = ProcessingResultDto(success=True, audio_path="/tmp/test.wav") | |
assert dto4.has_text_output is False | |
def test_has_audio_output_property(self): | |
"""Test has_audio_output property""" | |
# With audio path | |
dto1 = ProcessingResultDto(success=True, audio_path="/tmp/test.wav") | |
assert dto1.has_audio_output is True | |
# Without audio path | |
dto2 = ProcessingResultDto(success=True, original_text="Test") | |
assert dto2.has_audio_output is False | |
def test_is_complete_property(self): | |
"""Test is_complete property""" | |
# Successful processing | |
dto1 = ProcessingResultDto(success=True, original_text="Test") | |
assert dto1.is_complete is True | |
# Failed processing with error message | |
dto2 = ProcessingResultDto(success=False, error_message="Error") | |
assert dto2.is_complete is True | |
# This shouldn't happen due to validation, but test the logic | |
dto3 = ProcessingResultDto.__new__(ProcessingResultDto) | |
dto3.success = False | |
dto3.error_message = None | |
assert dto3.is_complete is False | |
def test_add_metadata_method(self): | |
"""Test add_metadata method""" | |
dto = ProcessingResultDto(success=True, original_text="Test") | |
dto.add_metadata("key1", "value1") | |
dto.add_metadata("key2", 123) | |
assert dto.metadata["key1"] == "value1" | |
assert dto.metadata["key2"] == 123 | |
def test_add_metadata_method_with_none_metadata(self): | |
"""Test add_metadata method when metadata is None""" | |
dto = ProcessingResultDto.__new__(ProcessingResultDto) | |
dto.success = True | |
dto.original_text = "Test" | |
dto.metadata = None | |
dto.add_metadata("key", "value") | |
assert dto.metadata == {"key": "value"} | |
def test_get_metadata_method(self): | |
"""Test get_metadata method""" | |
dto = ProcessingResultDto( | |
success=True, | |
original_text="Test", | |
metadata={"existing_key": "existing_value"} | |
) | |
# Get existing key | |
assert dto.get_metadata("existing_key") == "existing_value" | |
# Get non-existing key with default | |
assert dto.get_metadata("non_existing", "default") == "default" | |
# Get non-existing key without default | |
assert dto.get_metadata("non_existing") is None | |
def test_get_metadata_method_with_none_metadata(self): | |
"""Test get_metadata method when metadata is None""" | |
dto = ProcessingResultDto.__new__(ProcessingResultDto) | |
dto.success = True | |
dto.original_text = "Test" | |
dto.metadata = None | |
assert dto.get_metadata("key", "default") == "default" | |
assert dto.get_metadata("key") is None | |
def test_to_dict_method(self): | |
"""Test to_dict method""" | |
test_timestamp = datetime(2023, 1, 1, 12, 0, 0) | |
dto = ProcessingResultDto( | |
success=True, | |
original_text="Hello world", | |
translated_text="Hola mundo", | |
audio_path="/tmp/output.wav", | |
processing_time=5.2, | |
error_message=None, | |
error_code=None, | |
metadata={"correlation_id": "test-123"}, | |
timestamp=test_timestamp | |
) | |
result = dto.to_dict() | |
assert result['success'] is True | |
assert result['original_text'] == "Hello world" | |
assert result['translated_text'] == "Hola mundo" | |
assert result['audio_path'] == "/tmp/output.wav" | |
assert result['processing_time'] == 5.2 | |
assert result['error_message'] is None | |
assert result['error_code'] is None | |
assert result['metadata'] == {"correlation_id": "test-123"} | |
assert result['timestamp'] == test_timestamp.isoformat() | |
assert result['has_text_output'] is True | |
assert result['has_audio_output'] is True | |
assert result['is_complete'] is True | |
def test_to_dict_method_with_none_timestamp(self): | |
"""Test to_dict method with None timestamp""" | |
dto = ProcessingResultDto.__new__(ProcessingResultDto) | |
dto.success = True | |
dto.original_text = "Test" | |
dto.translated_text = None | |
dto.audio_path = None | |
dto.processing_time = 0.0 | |
dto.error_message = None | |
dto.error_code = None | |
dto.metadata = {} | |
dto.timestamp = None | |
result = dto.to_dict() | |
assert result['timestamp'] is None | |
def test_success_result_class_method(self): | |
"""Test success_result class method""" | |
result = ProcessingResultDto.success_result( | |
original_text="Hello world", | |
translated_text="Hola mundo", | |
audio_path="/tmp/output.wav", | |
processing_time=3.5, | |
metadata={"test": "value"} | |
) | |
assert isinstance(result, ProcessingResultDto) | |
assert result.success is True | |
assert result.original_text == "Hello world" | |
assert result.translated_text == "Hola mundo" | |
assert result.audio_path == "/tmp/output.wav" | |
assert result.processing_time == 3.5 | |
assert result.metadata == {"test": "value"} | |
assert result.error_message is None | |
assert result.error_code is None | |
def test_success_result_class_method_with_defaults(self): | |
"""Test success_result class method with default values""" | |
result = ProcessingResultDto.success_result(original_text="Test") | |
assert result.success is True | |
assert result.original_text == "Test" | |
assert result.translated_text is None | |
assert result.audio_path is None | |
assert result.processing_time == 0.0 | |
assert result.metadata is None | |
def test_error_result_class_method(self): | |
"""Test error_result class method""" | |
result = ProcessingResultDto.error_result( | |
error_message="Processing failed", | |
error_code="STT_ERROR", | |
processing_time=2.1, | |
metadata={"correlation_id": "test-456"} | |
) | |
assert isinstance(result, ProcessingResultDto) | |
assert result.success is False | |
assert result.error_message == "Processing failed" | |
assert result.error_code == "STT_ERROR" | |
assert result.processing_time == 2.1 | |
assert result.metadata == {"correlation_id": "test-456"} | |
assert result.original_text is None | |
assert result.translated_text is None | |
assert result.audio_path is None | |
def test_error_result_class_method_with_defaults(self): | |
"""Test error_result class method with default values""" | |
result = ProcessingResultDto.error_result("Test error") | |
assert result.success is False | |
assert result.error_message == "Test error" | |
assert result.error_code is None | |
assert result.processing_time == 0.0 | |
assert result.metadata is None | |
def test_from_dict_class_method(self): | |
"""Test from_dict class method""" | |
test_timestamp = datetime(2023, 1, 1, 12, 0, 0) | |
data = { | |
'success': True, | |
'original_text': 'Hello world', | |
'translated_text': 'Hola mundo', | |
'audio_path': '/tmp/output.wav', | |
'processing_time': 5.2, | |
'error_message': None, | |
'error_code': None, | |
'metadata': {'correlation_id': 'test-123'}, | |
'timestamp': test_timestamp.isoformat() | |
} | |
dto = ProcessingResultDto.from_dict(data) | |
assert dto.success is True | |
assert dto.original_text == 'Hello world' | |
assert dto.translated_text == 'Hola mundo' | |
assert dto.audio_path == '/tmp/output.wav' | |
assert dto.processing_time == 5.2 | |
assert dto.error_message is None | |
assert dto.error_code is None | |
assert dto.metadata == {'correlation_id': 'test-123'} | |
assert dto.timestamp == test_timestamp | |
def test_from_dict_class_method_with_z_timestamp(self): | |
"""Test from_dict class method with Z-suffixed timestamp""" | |
data = { | |
'success': True, | |
'original_text': 'Test', | |
'timestamp': '2023-01-01T12:00:00Z' | |
} | |
dto = ProcessingResultDto.from_dict(data) | |
assert dto.timestamp == datetime(2023, 1, 1, 12, 0, 0) | |
def test_from_dict_class_method_with_defaults(self): | |
"""Test from_dict class method with default values""" | |
data = { | |
'success': True, | |
'original_text': 'Test' | |
} | |
dto = ProcessingResultDto.from_dict(data) | |
assert dto.success is True | |
assert dto.original_text == 'Test' | |
assert dto.translated_text is None | |
assert dto.audio_path is None | |
assert dto.processing_time == 0.0 | |
assert dto.error_message is None | |
assert dto.error_code is None | |
assert dto.metadata is None | |
assert dto.timestamp is None | |
def test_validation_called_on_init(self): | |
"""Test that validation is called during initialization""" | |
# This should trigger validation and raise an error | |
with pytest.raises(ValueError): | |
ProcessingResultDto( | |
success="invalid", # Invalid type | |
original_text="Test" | |
) | |
def test_metadata_default_initialization(self): | |
"""Test that metadata is initialized to empty dict if None""" | |
dto = ProcessingResultDto( | |
success=True, | |
original_text="Test", | |
metadata=None | |
) | |
assert dto.metadata == {} | |
def test_timestamp_default_initialization(self): | |
"""Test that timestamp is initialized to current time if None""" | |
before = datetime.utcnow() | |
dto = ProcessingResultDto( | |
success=True, | |
original_text="Test", | |
timestamp=None | |
) | |
after = datetime.utcnow() | |
assert before <= dto.timestamp <= after |