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