import pytest from unittest.mock import patch, MagicMock, AsyncMock import sys import os # Dodanie katalogu nadrzędnego do ścieżki dla importów sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from src.youtube_utils import extract_youtube_urls, extract_video_id, get_transcript, NoTranscriptFound, TranscriptsDisabled from src.openai_utils import summarize_text @pytest.mark.asyncio async def test_youtube_to_openai_integration(): # 1. Przygotowanie danych testowych text_with_youtube_url = "Sprawdź to wideo https://www.youtube.com/watch?v=abc123" # 2. Przygotowanie mocka dla API youtube-transcript.io mock_response = MagicMock() mock_response.status = 200 # Przykładowa odpowiedź z API zawierająca transkrypcję w języku polskim i tytuł mock_json_data = { "abc123": { "title": "Tytuł przykładowego wideo", "pl": [ {"text": "To jest", "start": 0.0, "duration": 1.0}, {"text": "przykładowa transkrypcja", "start": 1.0, "duration": 2.0}, {"text": "z YouTube", "start": 3.0, "duration": 1.0} ] } } # Konfiguracja asynchronicznego mocka mock_response.json = AsyncMock(return_value=mock_json_data) # Mock dla kontekstowego managera aiohttp.ClientSession().post() mock_session = MagicMock() mock_session.__aenter__.return_value = mock_response mock_client_session = MagicMock() mock_client_session.post.return_value = mock_session mock_client_session.__aenter__.return_value = mock_client_session # 3. Przygotowanie mocka dla odpowiedzi OpenAI mock_choice = MagicMock() mock_message = MagicMock() mock_message.content = "Film zawiera przykładową transkrypcję z YouTube." mock_choice.message = mock_message mock_openai_response = MagicMock() mock_openai_response.choices = [mock_choice] # 4. Proces integracji z wykorzystaniem kontekstowych managerów dla mocków # Najpierw sprawdzamy podstawowe funkcje bez mocków urls = extract_youtube_urls(text_with_youtube_url) assert len(urls) == 1 video_id = extract_video_id(urls[0]) assert video_id == "abc123" # Teraz testujemy z mockami dla operacji asynchronicznych with patch('src.youtube_utils.YOUTUBE_TRANSCRIPT_API_TOKEN', "fake_token"): with patch('aiohttp.ClientSession', return_value=mock_client_session): result = await get_transcript(video_id, ["pl", "en"]) assert result is not None transcript, title = result assert transcript == "To jest przykładowa transkrypcja z YouTube" assert title == "Tytuł przykładowego wideo" with patch('src.openai_utils.client.chat.completions.create', new=AsyncMock(return_value=mock_openai_response)): summary = await summarize_text(transcript) assert summary == "Film zawiera przykładową transkrypcję z YouTube." @pytest.mark.asyncio async def test_integration_with_english_fallback(): # 1. Symulacja braku polskiej transkrypcji, ale z dostępną angielską mock_response = MagicMock() mock_response.status = 200 # Przykładowa odpowiedź z API zawierająca tylko transkrypcję angielską i tytuł mock_json_data = { "xyz789": { "title": "English Sample Video", "en": [ {"text": "This is", "start": 0.0, "duration": 1.0}, {"text": "a sample", "start": 1.0, "duration": 2.0}, {"text": "transcript", "start": 3.0, "duration": 1.0} ] } } # Konfiguracja asynchronicznego mocka mock_response.json = AsyncMock(return_value=mock_json_data) # Mock dla kontekstowego managera aiohttp.ClientSession().post() mock_session = MagicMock() mock_session.__aenter__.return_value = mock_response mock_client_session = MagicMock() mock_client_session.post.return_value = mock_session mock_client_session.__aenter__.return_value = mock_client_session # 2. Przygotowanie mocka dla odpowiedzi OpenAI mock_choice = MagicMock() mock_message = MagicMock() mock_message.content = "Film zawiera angielską transkrypcję." mock_choice.message = mock_message mock_openai_response = MagicMock() mock_openai_response.choices = [mock_choice] # 3. Proces integracji z transkrypcją angielską jako fallback video_id = "xyz789" with patch('src.youtube_utils.YOUTUBE_TRANSCRIPT_API_TOKEN', "fake_token"): with patch('aiohttp.ClientSession', return_value=mock_client_session): # Pobieranie transkrypcji - preferujemy polski, ale dostępny jest tylko angielski result = await get_transcript(video_id, ["pl", "en"]) assert result is not None transcript, title = result assert transcript == "This is a sample transcript" assert title == "English Sample Video" # Generowanie streszczenia with patch('src.openai_utils.client.chat.completions.create', new=AsyncMock(return_value=mock_openai_response)): summary = await summarize_text(transcript) assert summary == "Film zawiera angielską transkrypcję." @pytest.mark.asyncio async def test_integration_no_transcript_available(): # 1. Symulacja braku jakiejkolwiek transkrypcji mock_response = MagicMock() mock_response.status = 404 # Brak transkrypcji # Mock dla kontekstowego managera aiohttp.ClientSession().post() mock_session = MagicMock() mock_session.__aenter__.return_value = mock_response mock_client_session = MagicMock() mock_client_session.post.return_value = mock_session mock_client_session.__aenter__.return_value = mock_client_session # 2. Proces integracji - powinien zakończyć się na etapie transkrypcji video_id = "no_transcript_123" with patch('src.youtube_utils.YOUTUBE_TRANSCRIPT_API_TOKEN', "fake_token"): with patch('aiohttp.ClientSession', return_value=mock_client_session): # Próba pobrania transkrypcji powinna rzucić NoTranscriptFound with pytest.raises(NoTranscriptFound): transcript = await get_transcript(video_id, ["pl", "en"]) # 3. Ponieważ nie udało się pobrać transkrypcji, nie testujemy dalej