""" Unit Tests for DreamWeaver AI - API-Based Version ================================================== These tests verify the functionality of the dream analysis components. Note: Some tests mock API calls to avoid rate limits during CI/CD. Run with: pytest test_app.py -v """ import pytest import sys import os from unittest.mock import Mock, patch, MagicMock # Add parent directory to path for imports sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) class TestDreamSymbols: """Test suite for dream symbol detection (no API calls needed).""" def test_import_app(self): """Test that app module can be imported.""" import app assert app is not None def test_dream_symbols_exist(self): """Test that dream symbols dictionary exists.""" import app assert hasattr(app, 'DREAM_SYMBOLS') assert len(app.DREAM_SYMBOLS) > 0 def test_find_dream_symbols_basic(self): """Test basic symbol detection.""" import app dream = "I was flying over the ocean and saw a beautiful house." result = app.find_dream_symbols(dream) assert "flying" in result.lower() or "ocean" in result.lower() or "house" in result.lower() def test_find_dream_symbols_no_match(self): """Test when no symbols are found.""" import app dream = "I had a conversation with someone." result = app.find_dream_symbols(dream) assert "No common symbols" in result or "unique personal symbolism" in result def test_find_dream_symbols_multiple(self): """Test detection of multiple symbols.""" import app dream = "I saw water, fire, and a snake near a door in the moonlight." result = app.find_dream_symbols(dream) # At least some symbols should be detected assert "🔮" in result # The header emoji class TestMoodColors: """Test suite for mood color mappings.""" def test_mood_colors_exist(self): """Test that mood colors dictionary exists.""" import app assert hasattr(app, 'MOOD_COLORS') assert len(app.MOOD_COLORS) > 0 def test_mood_colors_have_hex(self): """Test that mood colors have hex values.""" import app for mood, color in app.MOOD_COLORS.items(): assert color.startswith('#') class TestImagePromptGeneration: """Test suite for image prompt generation (no API calls).""" def test_generate_image_prompt_basic(self): """Test image prompt generation.""" import app dream = "I was flying through a forest with the moon above." result = app.generate_dream_image_prompt(dream) assert "Image Generation Prompt" in result assert "```" in result # Code block for the prompt def test_generate_image_prompt_empty(self): """Test image prompt with minimal input.""" import app dream = "A simple dream." result = app.generate_dream_image_prompt(dream) assert "dreamscape" in result.lower() or "scene" in result.lower() class TestJournalSaving: """Test suite for journal entry formatting.""" def test_save_to_journal_format(self): """Test journal entry formatting.""" import app dream = "I had a wonderful dream about flying." interpretation = "This dream represents freedom." result = app.save_to_journal(dream, interpretation) assert "Dream Journal Entry" in result assert dream in result assert interpretation in result assert "DreamWeaver AI" in result class TestSentimentAnalysisMocked: """Test suite for sentiment analysis with mocked API.""" @patch('app.client') def test_analyze_sentiment_success(self, mock_client): """Test sentiment analysis with mocked successful response.""" import app # Mock the API response mock_result = [ Mock(label="joy", score=0.8), Mock(label="surprise", score=0.1), Mock(label="neutral", score=0.1) ] mock_client.text_classification.return_value = mock_result result, time, mood = app.analyze_dream_sentiment("I was so happy in my dream!") assert "Emotional Landscape" in result assert mood == "joy" assert "s" in time # time should contain seconds @patch('app.client') def test_analyze_sentiment_empty_input(self, mock_client): """Test sentiment analysis with empty input.""" import app result, time, mood = app.analyze_dream_sentiment("") assert "Please enter some text" in result or "Please describe your dream" in result mock_client.text_classification.assert_not_called() class TestTextGenerationMocked: """Test suite for text generation with mocked API.""" @patch('app.client') def test_generate_text_success(self, mock_client): """Test text generation with mocked response.""" import app mock_client.text_generation.return_value = "Once upon a time, in a magical land..." result, time = app.generate_text("Once upon a time", 50, 0.7) assert isinstance(result, str) assert "s" in time @patch('app.client') def test_generate_text_empty_input(self, mock_client): """Test text generation with empty input.""" import app result, time = app.generate_text("", 50, 0.7) assert "Please enter" in result mock_client.text_generation.assert_not_called() class TestDreamInterpretationMocked: """Test suite for dream interpretation with mocked API.""" @patch('app.client') def test_generate_interpretation_success(self, mock_client): """Test interpretation generation with mocked response.""" import app mock_client.text_generation.return_value = "This dream symbolizes your desire for freedom..." result, time = app.generate_dream_interpretation( "I was flying over mountains", "joy" ) assert "Dream Interpretation" in result assert "s" in time class TestDreamStoryMocked: """Test suite for story generation with mocked API.""" @patch('app.client') def test_generate_story_fantasy(self, mock_client): """Test fantasy story generation.""" import app mock_client.text_generation.return_value = "The hero discovered a magical realm..." result, time = app.generate_dream_story( "I found a magical sword", "Fantasy", 250 ) assert "Fantasy" in result assert "Story" in result @patch('app.client') def test_generate_story_scifi(self, mock_client): """Test sci-fi story generation.""" import app mock_client.text_generation.return_value = "In the year 3000..." result, time = app.generate_dream_story( "I was on a spaceship", "Sci-Fi", 250 ) assert "Sci-Fi" in result class TestErrorHandling: """Test suite for error handling.""" @patch('app.client') def test_api_error_handling(self, mock_client): """Test that API errors are handled gracefully.""" import app mock_client.text_classification.side_effect = Exception("API rate limit exceeded") result, time, mood = app.analyze_dream_sentiment("Test dream") assert "Error" in result assert "rate limit" in result.lower() or "error" in result.lower() class TestGradioInterface: """Test suite for Gradio interface components.""" def test_demo_exists(self): """Test that the Gradio demo object exists.""" import app assert hasattr(app, 'demo') def test_demo_is_blocks(self): """Test that demo is a Gradio Blocks instance.""" import app import gradio as gr assert isinstance(app.demo, gr.Blocks) # Integration test (only runs if HF_TOKEN is available) class TestIntegrationWithAPI: """Integration tests that actually call the API (skipped in CI without token).""" @pytest.mark.skipif( os.getenv('SKIP_API_TESTS', 'true').lower() == 'true', reason="Skipping API tests to avoid rate limits" ) def test_real_sentiment_analysis(self): """Test real API call for sentiment analysis.""" import app result, time, mood = app.analyze_dream_sentiment( "I was extremely happy flying through beautiful clouds." ) assert "Emotional Landscape" in result assert mood != "" if __name__ == "__main__": pytest.main([__file__, "-v", "--tb=short"])