telegram.video.summary.bot/tests/test_integration.py

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