"""Unit tests for TranslationRequest value object.""" import pytest from src.domain.models.translation_request import TranslationRequest from src.domain.models.text_content import TextContent class TestTranslationRequest: """Test cases for TranslationRequest value object.""" @pytest.fixture def sample_text_content(self): """Sample text content for testing.""" return TextContent( text="Hello, world!", language="en" ) def test_valid_translation_request_creation(self, sample_text_content): """Test creating valid TranslationRequest instance.""" request = TranslationRequest( source_text=sample_text_content, target_language="es", source_language="en" ) assert request.source_text == sample_text_content assert request.target_language == "es" assert request.source_language == "en" assert request.effective_source_language == "en" assert request.is_auto_detect_source is False def test_translation_request_without_source_language(self, sample_text_content): """Test creating TranslationRequest without explicit source language.""" request = TranslationRequest( source_text=sample_text_content, target_language="es" ) assert request.source_language is None assert request.effective_source_language == "en" # From TextContent assert request.is_auto_detect_source is True def test_non_text_content_source_raises_error(self): """Test that non-TextContent source raises TypeError.""" with pytest.raises(TypeError, match="Source text must be a TextContent instance"): TranslationRequest( source_text="not a TextContent", # type: ignore target_language="es" ) def test_non_string_target_language_raises_error(self, sample_text_content): """Test that non-string target language raises TypeError.""" with pytest.raises(TypeError, match="Target language must be a string"): TranslationRequest( source_text=sample_text_content, target_language=123 # type: ignore ) def test_empty_target_language_raises_error(self, sample_text_content): """Test that empty target language raises ValueError.""" with pytest.raises(ValueError, match="Target language cannot be empty"): TranslationRequest( source_text=sample_text_content, target_language="" ) def test_whitespace_target_language_raises_error(self, sample_text_content): """Test that whitespace-only target language raises ValueError.""" with pytest.raises(ValueError, match="Target language cannot be empty"): TranslationRequest( source_text=sample_text_content, target_language=" " ) def test_invalid_target_language_format_raises_error(self, sample_text_content): """Test that invalid target language format raises ValueError.""" invalid_codes = ["e", "ENG", "en-us", "en-USA", "123", "en_US"] for code in invalid_codes: with pytest.raises(ValueError, match="Invalid target language code format"): TranslationRequest( source_text=sample_text_content, target_language=code ) def test_valid_target_language_codes(self, sample_text_content): """Test valid target language code formats.""" valid_codes = ["es", "fr", "de", "zh", "ja", "en-US", "fr-FR", "zh-CN"] for code in valid_codes: request = TranslationRequest( source_text=sample_text_content, target_language=code ) assert request.target_language == code def test_non_string_source_language_raises_error(self, sample_text_content): """Test that non-string source language raises TypeError.""" with pytest.raises(TypeError, match="Source language must be a string"): TranslationRequest( source_text=sample_text_content, target_language="es", source_language=123 # type: ignore ) def test_empty_source_language_raises_error(self, sample_text_content): """Test that empty source language raises ValueError.""" with pytest.raises(ValueError, match="Source language cannot be empty string"): TranslationRequest( source_text=sample_text_content, target_language="es", source_language="" ) def test_whitespace_source_language_raises_error(self, sample_text_content): """Test that whitespace-only source language raises ValueError.""" with pytest.raises(ValueError, match="Source language cannot be empty string"): TranslationRequest( source_text=sample_text_content, target_language="es", source_language=" " ) def test_invalid_source_language_format_raises_error(self, sample_text_content): """Test that invalid source language format raises ValueError.""" invalid_codes = ["e", "ENG", "en-us", "en-USA", "123", "en_US"] for code in invalid_codes: with pytest.raises(ValueError, match="Invalid source language code format"): TranslationRequest( source_text=sample_text_content, target_language="es", source_language=code ) def test_same_source_and_target_language_explicit_raises_error(self, sample_text_content): """Test that same explicit source and target language raises ValueError.""" with pytest.raises(ValueError, match="Source and target languages cannot be the same"): TranslationRequest( source_text=sample_text_content, target_language="en", source_language="en" ) def test_same_source_and_target_language_implicit_raises_error(self): """Test that same implicit source and target language raises ValueError.""" text_content = TextContent(text="Hello", language="en") with pytest.raises(ValueError, match="Source and target languages cannot be the same"): TranslationRequest( source_text=text_content, target_language="en" # Same as text_content.language ) def test_text_length_property(self, sample_text_content): """Test text_length property.""" request = TranslationRequest( source_text=sample_text_content, target_language="es" ) assert request.text_length == len(sample_text_content.text) def test_word_count_property(self, sample_text_content): """Test word_count property.""" request = TranslationRequest( source_text=sample_text_content, target_language="es" ) assert request.word_count == sample_text_content.word_count def test_with_target_language_method(self, sample_text_content): """Test with_target_language method creates new instance.""" original = TranslationRequest( source_text=sample_text_content, target_language="es", source_language="en" ) new_request = original.with_target_language("fr") assert new_request.target_language == "fr" assert new_request.source_text == original.source_text assert new_request.source_language == original.source_language assert new_request is not original # Different instances def test_with_source_language_method(self, sample_text_content): """Test with_source_language method creates new instance.""" original = TranslationRequest( source_text=sample_text_content, target_language="es", source_language="en" ) new_request = original.with_source_language("de") assert new_request.source_language == "de" assert new_request.target_language == original.target_language assert new_request.source_text == original.source_text assert new_request is not original # Different instances def test_with_source_language_none(self, sample_text_content): """Test with_source_language method with None value.""" original = TranslationRequest( source_text=sample_text_content, target_language="es", source_language="en" ) new_request = original.with_source_language(None) assert new_request.source_language is None assert new_request.is_auto_detect_source is True def test_translation_request_is_immutable(self, sample_text_content): """Test that TranslationRequest is immutable (frozen dataclass).""" request = TranslationRequest( source_text=sample_text_content, target_language="es" ) with pytest.raises(AttributeError): request.target_language = "fr" # type: ignore def test_effective_source_language_with_explicit_source(self, sample_text_content): """Test effective_source_language with explicit source language.""" request = TranslationRequest( source_text=sample_text_content, target_language="es", source_language="de" # Different from text_content.language ) assert request.effective_source_language == "de" def test_effective_source_language_with_implicit_source(self, sample_text_content): """Test effective_source_language with implicit source language.""" request = TranslationRequest( source_text=sample_text_content, target_language="es" ) assert request.effective_source_language == sample_text_content.language