"""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.""" def test_valid_translation_request_creation(self): """Test creating valid TranslationRequest instance.""" source_text = TextContent(text="Hello, world!", language="en") request = TranslationRequest( source_text=source_text, target_language="fr", source_language="en" ) assert request.source_text == source_text assert request.target_language == "fr" 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): """Test creating TranslationRequest without explicit source language.""" source_text = TextContent(text="Hello, world!", language="en") request = TranslationRequest( source_text=source_text, target_language="fr" ) 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_text raises TypeError.""" with pytest.raises(TypeError, match="Source text must be a TextContent instance"): TranslationRequest( source_text="Hello, world!", # type: ignore target_language="fr" ) def test_non_string_target_language_raises_error(self): """Test that non-string target_language raises TypeError.""" source_text = TextContent(text="Hello, world!", language="en") with pytest.raises(TypeError, match="Target language must be a string"): TranslationRequest( source_text=source_text, target_language=123 # type: ignore ) def test_empty_target_language_raises_error(self): """Test that empty target_language raises ValueError.""" source_text = TextContent(text="Hello, world!", language="en") with pytest.raises(ValueError, match="Target language cannot be empty"): TranslationRequest( source_text=source_text, target_language="" ) def test_whitespace_target_language_raises_error(self): """Test that whitespace-only target_language raises ValueError.""" source_text = TextContent(text="Hello, world!", language="en") with pytest.raises(ValueError, match="Target language cannot be empty"): TranslationRequest( source_text=source_text, target_language=" " ) def test_invalid_target_language_format_raises_error(self): """Test that invalid target language format raises ValueError.""" source_text = TextContent(text="Hello, world!", language="en") invalid_codes = ["f", "FRA", "fr-us", "fr-USA", "123", "fr_FR"] for code in invalid_codes: with pytest.raises(ValueError, match="Invalid target language code format"): TranslationRequest( source_text=source_text, target_language=code ) def test_valid_target_language_codes(self): """Test valid target language code formats.""" source_text = TextContent(text="Hello, world!", language="en") valid_codes = ["fr", "de", "es", "zh", "ja", "fr-FR", "de-DE", "zh-CN"] for code in valid_codes: request = TranslationRequest( source_text=source_text, target_language=code ) assert request.target_language == code def test_non_string_source_language_raises_error(self): """Test that non-string source_language raises TypeError.""" source_text = TextContent(text="Hello, world!", language="en") with pytest.raises(TypeError, match="Source language must be a string"): TranslationRequest( source_text=source_text, target_language="fr", source_language=123 # type: ignore ) def test_empty_source_language_raises_error(self): """Test that empty source_language raises ValueError.""" source_text = TextContent(text="Hello, world!", language="en") with pytest.raises(ValueError, match="Source language cannot be empty string"): TranslationRequest( source_text=source_text, target_language="fr", source_language="" ) def test_whitespace_source_language_raises_error(self): """Test that whitespace-only source_language raises ValueError.""" source_text = TextContent(text="Hello, world!", language="en") with pytest.raises(ValueError, match="Source language cannot be empty string"): TranslationRequest( source_text=source_text, target_language="fr", source_language=" " ) def test_invalid_source_language_format_raises_error(self): """Test that invalid source language format raises ValueError.""" source_text = TextContent(text="Hello, world!", language="en") 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=source_text, target_language="fr", source_language=code ) def test_same_source_and_target_language_raises_error(self): """Test that same source and target languages raise ValueError.""" source_text = TextContent(text="Hello, world!", language="en") # Explicit source language same as target with pytest.raises(ValueError, match="Source and target languages cannot be the same"): TranslationRequest( source_text=source_text, target_language="en", source_language="en" ) # Implicit source language (from TextContent) same as target with pytest.raises(ValueError, match="Source and target languages cannot be the same"): TranslationRequest( source_text=source_text, target_language="en" ) def test_effective_source_language_property(self): """Test effective_source_language property.""" source_text = TextContent(text="Hello, world!", language="en") # With explicit source language request_explicit = TranslationRequest( source_text=source_text, target_language="fr", source_language="de" ) assert request_explicit.effective_source_language == "de" # Without explicit source language (uses TextContent language) request_implicit = TranslationRequest( source_text=source_text, target_language="fr" ) assert request_implicit.effective_source_language == "en" def test_text_length_property(self): """Test text_length property.""" source_text = TextContent(text="Hello, world!", language="en") request = TranslationRequest( source_text=source_text, target_language="fr" ) assert request.text_length == len("Hello, world!") def test_word_count_property(self): """Test word_count property.""" source_text = TextContent(text="Hello, world!", language="en") request = TranslationRequest( source_text=source_text, target_language="fr" ) assert request.word_count == source_text.word_count def test_with_target_language_method(self): """Test with_target_language method creates new instance.""" source_text = TextContent(text="Hello, world!", language="en") original = TranslationRequest( source_text=source_text, target_language="fr", source_language="en" ) new_request = original.with_target_language("de") assert new_request.target_language == "de" 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): """Test with_source_language method creates new instance.""" source_text = TextContent(text="Hello, world!", language="en") original = TranslationRequest( source_text=source_text, target_language="fr", 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): """Test with_source_language method with None value.""" source_text = TextContent(text="Hello, world!", language="en") original = TranslationRequest( source_text=source_text, target_language="fr", 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): """Test that TranslationRequest is immutable (frozen dataclass).""" source_text = TextContent(text="Hello, world!", language="en") request = TranslationRequest( source_text=source_text, target_language="fr" ) with pytest.raises(AttributeError): request.target_language = "de" # type: ignore def test_valid_language_combinations(self): """Test various valid language combinations.""" test_cases = [ ("en", "fr", "en"), # English to French with explicit source ("en", "de", None), # English to German with auto-detect ("fr-FR", "en-US", "fr"), # Regional codes ("zh", "ja", "zh-CN"), # Asian languages ] for text_lang, target_lang, source_lang in test_cases: source_text = TextContent(text="Test text", language=text_lang) request = TranslationRequest( source_text=source_text, target_language=target_lang, source_language=source_lang ) assert request.target_language == target_lang assert request.source_language == source_lang