245 lines
9.4 KiB
Python
245 lines
9.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.openai_utils import (
|
|
summarize_text,
|
|
check_openai_api_status,
|
|
EmptyTextError,
|
|
APIKeyMissingError,
|
|
SummarizationError,
|
|
QuotaExceededError
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_text_success():
|
|
# Przygotowanie mocka dla odpowiedzi OpenAI
|
|
mock_choice = MagicMock()
|
|
mock_message = MagicMock()
|
|
|
|
mock_message.content = "To jest przykładowe streszczenie filmu."
|
|
mock_choice.message = mock_message
|
|
|
|
mock_response = MagicMock()
|
|
mock_response.choices = [mock_choice]
|
|
|
|
# Testowy tekst transkrypcji
|
|
test_transcript = "To jest przykładowa transkrypcja filmu YouTube, " \
|
|
"która zostanie wysłana do API OpenAI w celu streszczenia. " \
|
|
"Zawiera kilka zdań o różnej tematyce."
|
|
|
|
# Test funkcji z mockiem
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(return_value=mock_response)
|
|
result = await summarize_text(test_transcript)
|
|
|
|
# Sprawdzenie wyników
|
|
assert result == "To jest przykładowe streszczenie filmu."
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
# Sprawdzenie czy parametry zostały przekazane poprawnie
|
|
call_args = mock_client.chat.completions.create.call_args[1]
|
|
assert call_args['model'] == "gpt-4o-mini" # Zaktualizowano model
|
|
assert call_args['temperature'] == 0.5
|
|
assert call_args['max_tokens'] == 150
|
|
|
|
# Sprawdzenie wiadomości
|
|
messages = call_args['messages']
|
|
assert len(messages) == 2
|
|
assert messages[0]['role'] == "system"
|
|
assert messages[1]['role'] == "user"
|
|
assert test_transcript in messages[1]['content'] # Sprawdzenie czy transkrypcja jest w prompcie
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_text_with_transcript_from_youtube():
|
|
# Przygotowanie mocka dla odpowiedzi OpenAI
|
|
mock_choice = MagicMock()
|
|
mock_message = MagicMock()
|
|
|
|
mock_message.content = "Film przedstawia dyskusję na temat sztucznej inteligencji i jej zastosowań w życiu codziennym."
|
|
mock_choice.message = mock_message
|
|
|
|
mock_response = MagicMock()
|
|
mock_response.choices = [mock_choice]
|
|
|
|
# Przykładowa transkrypcja z YouTube
|
|
youtube_transcript = "To jest przykładowa transkrypcja z YouTube. " \
|
|
"Zawiera dyskusję o sztucznej inteligencji. " \
|
|
"Przedstawia różne zastosowania AI w codziennym życiu."
|
|
|
|
# Test funkcji
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(return_value=mock_response)
|
|
result = await summarize_text(youtube_transcript)
|
|
|
|
# Sprawdzenie wyników
|
|
assert result == "Film przedstawia dyskusję na temat sztucznej inteligencji i jej zastosowań w życiu codziennym."
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_empty_text():
|
|
# Test funkcji z pustym tekstem
|
|
with patch('src.openai_utils.client.chat.completions.create') as mock_create:
|
|
# Powinien rzucić EmptyTextError dla pustego tekstu
|
|
with pytest.raises(EmptyTextError):
|
|
await summarize_text("")
|
|
|
|
# Sprawdzenie czy mock nie został wywołany
|
|
assert not mock_create.called
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_text_api_error():
|
|
# Symulacja błędu API
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(side_effect=Exception("API Error"))
|
|
|
|
# Test funkcji - powinien rzucić SummarizationError
|
|
with pytest.raises(SummarizationError) as excinfo:
|
|
await summarize_text("Jakiś tekst transkrypcji")
|
|
|
|
# Sprawdzenie czy wiadomość błędu zawiera oryginalne informacje
|
|
assert "API Error" in str(excinfo.value)
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_text_quota_exceeded_error():
|
|
# Symulacja błędu przekroczenia limitu
|
|
error_response = Exception("Error code: 429 - {'error': {'message': 'You exceeded your current quota', 'type': 'insufficient_quota'}}")
|
|
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(side_effect=error_response)
|
|
|
|
# Test funkcji - powinien rzucić QuotaExceededError
|
|
with pytest.raises(QuotaExceededError) as excinfo:
|
|
await summarize_text("Jakiś tekst transkrypcji")
|
|
|
|
# Sprawdzenie czy wiadomość błędu zawiera informację o limicie
|
|
assert "Przekroczono limit zapytań API OpenAI" in str(excinfo.value)
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_text_no_client():
|
|
# Symulacja braku klienta OpenAI
|
|
with patch('src.openai_utils.client', None):
|
|
# Test funkcji - powinien rzucić APIKeyMissingError
|
|
with pytest.raises(APIKeyMissingError):
|
|
await summarize_text("Jakiś tekst transkrypcji")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_summarize_text_prompt_format():
|
|
# Przygotowanie mocka
|
|
mock_choice = MagicMock()
|
|
mock_message = MagicMock()
|
|
|
|
mock_message.content = "Streszczenie"
|
|
mock_choice.message = mock_message
|
|
|
|
mock_response = MagicMock()
|
|
mock_response.choices = [mock_choice]
|
|
|
|
# Testowy tekst
|
|
test_transcript = "Testowa transkrypcja"
|
|
|
|
# Przygotowanie spy do przechwycenia argumentów
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(return_value=mock_response)
|
|
|
|
# Test funkcji
|
|
await summarize_text(test_transcript)
|
|
|
|
# Sprawdzenie czy został wywołany
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
# Pobranie argumentów wywołania
|
|
call_args = mock_client.chat.completions.create.call_args[1]
|
|
messages = call_args['messages']
|
|
|
|
# Sprawdzenie czy prompt zawiera odpowiedni format
|
|
user_prompt = messages[1]['content']
|
|
assert "Streść poniższy transkrypt filmu z YouTube" in user_prompt
|
|
assert "Transkrypt:" in user_prompt
|
|
assert test_transcript in user_prompt
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_openai_api_status_success():
|
|
# Przygotowanie mocka dla udanej odpowiedzi
|
|
mock_choice = MagicMock()
|
|
mock_message = MagicMock()
|
|
|
|
mock_message.content = "Hello"
|
|
mock_choice.message = mock_message
|
|
|
|
mock_response = MagicMock()
|
|
mock_response.choices = [mock_choice]
|
|
mock_response.usage = MagicMock(_asdict=lambda: {"prompt_tokens": 20, "completion_tokens": 5, "total_tokens": 25})
|
|
mock_response.organization_id = "org-123"
|
|
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(return_value=mock_response)
|
|
|
|
# Test funkcji
|
|
available, status_info = await check_openai_api_status()
|
|
|
|
# Sprawdzenie wyników
|
|
assert available == True
|
|
assert status_info["available"] == True
|
|
assert status_info["model"] == "gpt-4o-mini"
|
|
assert status_info["organization_id"] == "org-123"
|
|
assert "usage" in status_info
|
|
assert status_info["usage"]["total_tokens"] == 25
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_openai_api_status_quota_exceeded():
|
|
# Symulacja błędu przekroczenia limitu
|
|
error_response = Exception("Error code: 429 - {'error': {'message': 'You exceeded your current quota', 'type': 'insufficient_quota'}}")
|
|
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(side_effect=error_response)
|
|
|
|
# Test funkcji - powinien rzucić QuotaExceededError
|
|
with pytest.raises(QuotaExceededError) as excinfo:
|
|
await check_openai_api_status()
|
|
|
|
# Sprawdzenie czy wiadomość błędu zawiera informację o limicie
|
|
assert "Przekroczono limit zapytań API OpenAI" in str(excinfo.value)
|
|
assert mock_client.chat.completions.create.called
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_openai_api_status_no_client():
|
|
# Symulacja braku klienta OpenAI
|
|
with patch('src.openai_utils.client', None):
|
|
# Test funkcji - powinien rzucić APIKeyMissingError
|
|
with pytest.raises(APIKeyMissingError):
|
|
await check_openai_api_status()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_openai_api_status_api_error():
|
|
# Symulacja ogólnego błędu API
|
|
with patch('src.openai_utils.client') as mock_client:
|
|
mock_client.chat.completions.create = AsyncMock(side_effect=Exception("General API Error"))
|
|
|
|
# Test funkcji - nie powinien rzucać wyjątku
|
|
available, status_info = await check_openai_api_status()
|
|
|
|
# Sprawdzenie wyników
|
|
assert available == False
|
|
assert status_info["available"] == False
|
|
assert "error" in status_info
|
|
assert "General API Error" in status_info["error"]
|
|
assert mock_client.chat.completions.create.called |