159 lines
6.4 KiB
Python
159 lines
6.4 KiB
Python
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 |