""" End-to-End tests for the Vibeon Translator service Tests complete translation flows including TTS, STT, and language learning features """ import pytest import asyncio import json import tempfile import os from fastapi.testclient import TestClient from main import app client = TestClient(app) class TestTranslationFlow: """Test complete translation flows""" @pytest.mark.asyncio async def test_end_to_end_text_translation_flow(self): """Test complete text translation flow""" # Test English to Kinyarwanda translation response = client.post("/api/translate", json={ "text": "Hello, how are you?", "target_language": "rw", "source_language": "en" }) assert response.status_code == 200 data = response.json() assert "translated_text" in data assert data["target_language"] == "rw" assert data["source_language"] == "en" assert len(data["translated_text"]) > 0 # Test Kinyarwanda to English translation response = client.post("/api/translate", json={ "text": "Muraho, amakuru?", "target_language": "en", "source_language": "rw" }) assert response.status_code == 200 data = response.json() assert "translated_text" in data assert data["target_language"] == "en" assert data["source_language"] == "rw" @pytest.mark.asyncio async def test_language_detection_flow(self): """Test automatic language detection""" response = client.post("/api/detect-language", json={ "text": "Bonjour, comment allez-vous?" }) assert response.status_code == 200 data = response.json() assert "detected_language" in data assert data["detected_language"] == "fr" @pytest.mark.asyncio async def test_batch_translation_flow(self): """Test batch translation functionality""" texts = [ "Hello", "Good morning", "How are you?", "Thank you" ] response = client.post("/api/translate/batch", json={ "texts": texts, "target_language": "rw", "source_language": "en" }) assert response.status_code == 200 data = response.json() assert len(data) == len(texts) for result in data: assert "translated_text" in result assert result["target_language"] == "rw" @pytest.mark.asyncio async def test_tts_generation_flow(self): """Test Text-to-Speech generation""" response = client.post("/api/tts/generate", json={ "text": "Muraho", "language": "rw", "voice": "default" }) assert response.status_code == 200 assert response.headers["content-type"] == "audio/mpeg" assert len(response.content) > 0 @pytest.mark.asyncio async def test_stt_transcription_flow(self): """Test Speech-to-Text transcription""" # Create a temporary audio file for testing with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_file: # Write minimal WAV header (44 bytes) tmp_file.write(b'RIFF\x24\x08\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\x00\x08\x00\x00') tmp_file.write(b'\x00' * 2048) # Add some silence tmp_file_path = tmp_file.name try: with open(tmp_file_path, "rb") as audio_file: response = client.post("/api/stt/transcribe", files={"audio": audio_file}, data={"language": "en"} ) assert response.status_code == 200 data = response.json() assert "text" in data assert "confidence" in data finally: os.unlink(tmp_file_path) @pytest.mark.asyncio async def test_audio_translation_flow(self): """Test audio translation (STT + Translation + TTS)""" # Create a temporary audio file with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_file: tmp_file.write(b'RIFF\x24\x08\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\x00\x08\x00\x00') tmp_file.write(b'\x00' * 2048) tmp_file_path = tmp_file.name try: with open(tmp_file_path, "rb") as audio_file: response = client.post("/api/translate/audio", files={"audio": audio_file}, data={"target_language": "rw", "output_format": "text"} ) assert response.status_code == 200 data = response.json() assert "translated_text" in data assert data["target_language"] == "rw" finally: os.unlink(tmp_file_path) @pytest.mark.asyncio async def test_languages_api_flow(self): """Test languages API endpoints""" # Test get all languages response = client.get("/api/languages") assert response.status_code == 200 data = response.json() assert "languages" in data assert len(data["languages"]) > 0 # Verify Kinyarwanda is included kinyarwanda = next((lang for lang in data["languages"] if lang["code"] == "rw"), None) assert kinyarwanda is not None assert kinyarwanda["name"] == "Kinyarwanda" assert kinyarwanda["native_name"] == "Ikinyarwanda" assert kinyarwanda["features"]["translation"] is True assert kinyarwanda["features"]["tts"] is True assert kinyarwanda["features"]["stt"] is True # Test get specific language response = client.get("/api/languages/rw") assert response.status_code == 200 data = response.json() assert data["code"] == "rw" assert data["name"] == "Kinyarwanda" # Test language features summary response = client.get("/api/languages/features/summary") assert response.status_code == 200 data = response.json() assert "total_languages" in data assert "features_summary" in data @pytest.mark.asyncio async def test_health_check_flow(self): """Test health check endpoints""" response = client.get("/health") assert response.status_code == 200 data = response.json() assert "status" in data assert data["status"] == "healthy" response = client.get("/api/health") assert response.status_code == 200 data = response.json() assert "healthy" in data assert data["healthy"] is True @pytest.mark.asyncio async def test_error_handling_flow(self): """Test error handling in various scenarios""" # Test invalid language code response = client.post("/api/translate", json={ "text": "Hello", "target_language": "invalid", "source_language": "en" }) assert response.status_code == 400 # Test empty text response = client.post("/api/translate", json={ "text": "", "target_language": "rw" }) assert response.status_code == 400 # Test missing required fields response = client.post("/api/translate", json={ "text": "Hello" }) assert response.status_code == 422 @pytest.mark.asyncio async def test_performance_flow(self): """Test performance under load""" import time # Test multiple concurrent requests start_time = time.time() tasks = [] for i in range(10): task = asyncio.create_task( self._make_translation_request(f"Test message {i}") ) tasks.append(task) results = await asyncio.gather(*tasks) end_time = time.time() total_time = end_time - start_time # All requests should succeed for result in results: assert result.status_code == 200 # Should complete within reasonable time assert total_time < 30 # 30 seconds for 10 requests async def _make_translation_request(self, text): """Helper method to make translation request""" response = client.post("/api/translate", json={ "text": text, "target_language": "rw", "source_language": "en" }) return response @pytest.mark.asyncio async def test_caching_flow(self): """Test caching functionality""" text = "Hello, this is a test message for caching" # First request response1 = client.post("/api/translate", json={ "text": text, "target_language": "rw", "source_language": "en" }) assert response1.status_code == 200 data1 = response1.json() # Second request (should be cached) response2 = client.post("/api/translate", json={ "text": text, "target_language": "rw", "source_language": "en" }) assert response2.status_code == 200 data2 = response2.json() # Results should be identical assert data1["translated_text"] == data2["translated_text"] @pytest.mark.asyncio async def test_multilingual_support_flow(self): """Test support for multiple languages""" test_cases = [ ("Hello", "en", "rw"), ("Bonjour", "fr", "en"), ("Hola", "es", "rw"), ("Guten Tag", "de", "en"), ] for text, source_lang, target_lang in test_cases: response = client.post("/api/translate", json={ "text": text, "target_language": target_lang, "source_language": source_lang }) assert response.status_code == 200 data = response.json() assert "translated_text" in data assert data["source_language"] == source_lang assert data["target_language"] == target_lang @pytest.mark.asyncio async def test_quality_assessment_flow(self): """Test translation quality assessment""" response = client.post("/api/translate", json={ "text": "Hello, how are you today?", "target_language": "rw", "source_language": "en", "include_quality": True }) assert response.status_code == 200 data = response.json() assert "translated_text" in data assert "quality_score" in data assert 0 <= data["quality_score"] <= 1 @pytest.mark.asyncio async def test_context_aware_translation_flow(self): """Test context-aware translation""" response = client.post("/api/translate", json={ "text": "The bank is closed", "target_language": "rw", "source_language": "en", "context": "financial_institution" }) assert response.status_code == 200 data = response.json() assert "translated_text" in data # Context should influence translation choice @pytest.mark.asyncio async def test_real_time_translation_flow(self): """Test real-time translation capabilities""" # Simulate real-time translation with streaming response = client.post("/api/translate/stream", json={ "text": "Hello, this is a real-time translation test", "target_language": "rw", "source_language": "en" }) assert response.status_code == 200 # In a real implementation, this would be a streaming response if __name__ == "__main__": pytest.main([__file__, "-v"])