""" Tests for the GoogleTranslationProvider. """ import pytest from unittest.mock import patch, MagicMock from services.providers.google_provider import ( GoogleTranslationProvider, get_google_provider, ) from services.providers.schemas import TranslationRequest, TranslationResponse class TestGoogleTranslationProvider: """Tests for GoogleTranslationProvider.""" @pytest.fixture def provider(self): """Create a Google provider instance.""" return GoogleTranslationProvider(use_cache=False) @pytest.fixture def provider_with_cache(self): """Create a Google provider with caching enabled.""" return GoogleTranslationProvider(use_cache=True) def test_get_name(self, provider): """Test provider name.""" assert provider.get_name() == "google" def test_is_available(self, provider): """Test availability check.""" result = provider.is_available() assert isinstance(result, bool) def test_translate_text_empty(self, provider): """Test translating empty text.""" request = TranslationRequest(text="", target_language="fr") response = provider.translate_text(request) assert response.translated_text == "" assert response.provider_name == "google" assert response.from_cache is False def test_translate_text_whitespace(self, provider): """Test translating whitespace-only text.""" request = TranslationRequest(text=" ", target_language="fr") response = provider.translate_text(request) assert response.translated_text == " " @patch( "services.providers.google_provider.GoogleTranslationProvider._get_translator" ) def test_translate_text_success(self, mock_get_translator, provider): """Test successful translation.""" mock_translator = MagicMock() mock_translator.translate.return_value = "Bonjour" mock_get_translator.return_value = mock_translator request = TranslationRequest(text="Hello", target_language="fr") response = provider.translate_text(request) assert response.translated_text == "Bonjour" assert response.provider_name == "google" assert response.from_cache is False @patch( "services.providers.google_provider.GoogleTranslationProvider._get_translator" ) def test_translate_text_with_source_language(self, mock_get_translator, provider): """Test translation with explicit source language.""" mock_translator = MagicMock() mock_translator.translate.return_value = "Bonjour" mock_get_translator.return_value = mock_translator request = TranslationRequest( text="Hello", target_language="fr", source_language="en" ) response = provider.translate_text(request) mock_get_translator.assert_called_once_with("en", "fr") assert response.translated_text == "Bonjour" @patch( "services.providers.google_provider.GoogleTranslationProvider._get_translator" ) def test_translate_text_error_fallback(self, mock_get_translator, provider): """Test that translation errors return original text and structured error (Story 2.2).""" mock_get_translator.side_effect = Exception("API Error") request = TranslationRequest(text="Hello", target_language="fr") response = provider.translate_text(request) assert response.translated_text == "Hello" assert response.provider_name == "google" assert response.error is not None assert response.error_code is not None def test_translate_batch_empty(self, provider): """Test batch translation with empty list.""" responses = provider.translate_batch([]) assert responses == [] @patch.object(GoogleTranslationProvider, "translate_text") def test_translate_batch(self, mock_translate, provider): """Test batch translation.""" mock_translate.side_effect = [ TranslationResponse(translated_text="Bonjour", provider_name="google"), TranslationResponse(translated_text="Monde", provider_name="google"), ] requests = [ TranslationRequest(text="Hello", target_language="fr"), TranslationRequest(text="World", target_language="fr"), ] responses = provider.translate_batch(requests) assert len(responses) == 2 assert responses[0].translated_text == "Bonjour" assert responses[1].translated_text == "Monde" def test_health_check(self, provider): """Test health check.""" status = provider.health_check() assert status.name == "google" assert isinstance(status.available, bool) assert status.latency_ms is not None def test_get_google_provider_singleton(self): """Test that get_google_provider returns same instance.""" provider1 = get_google_provider() provider2 = get_google_provider() assert provider1 is provider2 class TestGoogleProviderCaching: """Tests for Google provider caching functionality.""" @pytest.fixture def mock_cache(self): """Create a mock cache.""" cache = MagicMock() cache.get.return_value = None return cache def test_cache_hit(self, mock_cache): """Test that cache hits return cached result.""" mock_cache.get.return_value = "Cached Translation" provider = GoogleTranslationProvider(use_cache=True) provider._cache = mock_cache request = TranslationRequest(text="Hello", target_language="fr") response = provider.translate_text(request) assert response.translated_text == "Cached Translation" assert response.from_cache is True @patch( "services.providers.google_provider.GoogleTranslationProvider._get_translator" ) def test_cache_set_on_miss(self, mock_get_translator, mock_cache): """Test that translations are cached on miss.""" mock_translator = MagicMock() mock_translator.translate.return_value = "Bonjour" mock_get_translator.return_value = mock_translator provider = GoogleTranslationProvider(use_cache=True) provider._cache = mock_cache request = TranslationRequest(text="Hello", target_language="fr") provider.translate_text(request) mock_cache.set.assert_called_once_with( "Hello", "fr", "auto", "google", "Bonjour" )