Skip to main content
Glama
test_prd_ui.pyโ€ข16.9 kB
#!/usr/bin/env python3 """ Comprehensive tests for PRD UI components and integration This module contains unit tests for PRD-related UI components, interface integration, and user workflow functionality. """ import unittest import tempfile import os import sys from unittest.mock import Mock, patch, MagicMock # Add the parent directory to the path so we can import our modules sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from ui.components import ComponentFactory from ui.gradio_interface import GradioInterface from config.settings import settings class TestPRDUIComponents(unittest.TestCase): """Test cases for PRD UI components""" def setUp(self): """Set up test fixtures""" self.component_factory = ComponentFactory() def test_create_prd_output_component(self): """Test PRD output component creation""" component = ComponentFactory.create_prd_output() # Verify component is created self.assertIsNotNone(component) # Test with custom parameters custom_component = ComponentFactory.create_prd_output( label="Custom PRD Output", lines=25, max_lines=50 ) self.assertIsNotNone(custom_component) def test_create_prd_output_with_default_params(self): """Test PRD output component creation with default parameters""" component = ComponentFactory.create_prd_output() # Component should be created successfully with defaults self.assertIsNotNone(component) def test_create_prd_output_with_custom_params(self): """Test PRD output component creation with custom parameters""" custom_params = { 'label': 'Test PRD Output', 'lines': 30, 'max_lines': 60, 'show_copy_button': True } component = ComponentFactory.create_prd_output(**custom_params) self.assertIsNotNone(component) def test_prd_component_factory_methods(self): """Test that ComponentFactory has all required PRD methods""" required_methods = [ 'create_prd_output' ] for method_name in required_methods: self.assertTrue(hasattr(ComponentFactory, method_name)) self.assertTrue(callable(getattr(ComponentFactory, method_name))) def test_prd_ui_labels_exist(self): """Test that PRD UI labels are properly defined""" from config.constants import PRD_UI_LABELS required_labels = [ 'generate_prd_button', 'prd_output_label', 'prd_download_label', 'prd_generating', 'prd_error' ] for label_key in required_labels: self.assertIn(label_key, PRD_UI_LABELS) self.assertIsInstance(PRD_UI_LABELS[label_key], str) self.assertGreater(len(PRD_UI_LABELS[label_key]), 0) class TestPRDInterfaceIntegration(unittest.TestCase): """Test cases for PRD interface integration""" def setUp(self): """Set up test fixtures""" # Mock gradio to avoid actual UI creation during tests self.gradio_mock = MagicMock() @patch('ui.gradio_interface.gr') def test_gradio_interface_prd_attributes(self, mock_gr): """Test that GradioInterface has PRD-related attributes""" mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() interface = GradioInterface() # Test PRD component attributes exist required_attributes = [ 'prd_btn', 'prd_output', 'prd_download_file' ] for attr_name in required_attributes: self.assertTrue(hasattr(interface, attr_name)) @patch('ui.gradio_interface.gr') def test_gradio_interface_prd_methods(self, mock_gr): """Test that GradioInterface has PRD-related methods""" mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() interface = GradioInterface() # Test PRD processing methods exist required_methods = [ '_process_prd_generation' ] for method_name in required_methods: self.assertTrue(hasattr(interface, method_name)) self.assertTrue(callable(getattr(interface, method_name))) @patch('ui.gradio_interface.gr') @patch('services.openai_service.OpenAIService.generate_prd_from_key_points') @patch('services.file_service.FileService.create_prd_download_file') def test_prd_generation_workflow(self, mock_create_file, mock_generate_prd, mock_gr): """Test PRD generation workflow through interface""" # Setup mocks mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() sample_prd_content = """# Product Requirements Document ## Executive Summary Test PRD content for workflow testing. ## Problem Statement Testing PRD generation workflow. """ mock_generate_prd.return_value = sample_prd_content mock_create_file.return_value = "/tmp/test_prd.md" interface = GradioInterface() # Test PRD generation process sample_key_points = "Test key points for PRD generation" try: result = interface._process_prd_generation(sample_key_points) # Verify the workflow was executed mock_generate_prd.assert_called_once_with(sample_key_points) mock_create_file.assert_called_once_with(sample_prd_content) # Result should be a tuple (prd_content, file_path) self.assertIsInstance(result, tuple) self.assertEqual(len(result), 2) except Exception as e: # If method doesn't exist yet, that's expected for testing if "has no attribute '_process_prd_generation'" in str(e): self.skipTest("PRD generation method not yet implemented") else: raise @patch('ui.gradio_interface.gr') def test_prd_button_visibility_when_enabled(self, mock_gr): """Test PRD button visibility when feature is enabled""" mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() with patch.object(settings, 'enable_prd_generation', True): interface = GradioInterface() # PRD components should be created when enabled self.assertIsNotNone(interface.prd_btn) @patch('ui.gradio_interface.gr') def test_prd_button_visibility_when_disabled(self, mock_gr): """Test PRD button visibility when feature is disabled""" mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() with patch.object(settings, 'enable_prd_generation', False): interface = GradioInterface() # PRD components might still exist but should be hidden/disabled # This depends on implementation - test accordingly self.assertTrue(hasattr(interface, 'prd_btn')) @patch('ui.gradio_interface.gr') @patch('services.openai_service.OpenAIService.generate_prd_from_key_points') def test_prd_generation_error_handling(self, mock_generate_prd, mock_gr): """Test PRD generation error handling""" # Setup mocks mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() # Mock an error during PRD generation mock_generate_prd.side_effect = Exception("OpenAI API Error") interface = GradioInterface() sample_key_points = "Test key points" try: result = interface._process_prd_generation(sample_key_points) # Should handle error gracefully if isinstance(result, tuple): error_message, file_path = result self.assertIn("error", error_message.lower()) self.assertIsNone(file_path) except Exception as e: # If method doesn't exist yet, that's expected for testing if "has no attribute '_process_prd_generation'" in str(e): self.skipTest("PRD generation method not yet implemented") else: # Error should be handled within the method, not propagated self.fail(f"Unhandled error in PRD generation: {e}") class TestPRDSettings(unittest.TestCase): """Test cases for PRD configuration and settings""" def test_prd_settings_exist(self): """Test that PRD settings are properly configured""" # Test that PRD settings are available self.assertTrue(hasattr(settings, 'enable_prd_generation')) self.assertTrue(hasattr(settings, 'prd_openai_model')) self.assertTrue(hasattr(settings, 'prd_max_tokens')) self.assertTrue(hasattr(settings, 'prd_temperature')) self.assertTrue(hasattr(settings, 'prd_file_prefix')) def test_prd_config_method(self): """Test PRD configuration method""" self.assertTrue(hasattr(settings, 'get_prd_config')) self.assertTrue(callable(getattr(settings, 'get_prd_config'))) prd_config = settings.get_prd_config() self.assertIsInstance(prd_config, dict) # Test required config keys required_keys = ['model', 'max_tokens', 'temperature'] for key in required_keys: self.assertIn(key, prd_config) def test_prd_settings_types(self): """Test PRD settings data types""" self.assertIsInstance(settings.enable_prd_generation, bool) self.assertIsInstance(settings.prd_openai_model, str) self.assertIsInstance(settings.prd_max_tokens, int) self.assertIsInstance(settings.prd_temperature, float) self.assertIsInstance(settings.prd_file_prefix, str) def test_prd_settings_values(self): """Test PRD settings have reasonable values""" # PRD max tokens should be reasonable self.assertGreater(settings.prd_max_tokens, 0) self.assertLessEqual(settings.prd_max_tokens, 4096) # PRD temperature should be between 0 and 1 self.assertGreaterEqual(settings.prd_temperature, 0.0) self.assertLessEqual(settings.prd_temperature, 1.0) # PRD file prefix should not be empty self.assertGreater(len(settings.prd_file_prefix), 0) class TestPRDWorkflow(unittest.TestCase): """Integration tests for complete PRD workflow""" @patch('ui.gradio_interface.gr') def test_prd_feature_toggle(self, mock_gr): """Test PRD feature can be toggled on/off""" mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() # Test with PRD enabled with patch.object(settings, 'enable_prd_generation', True): interface_enabled = GradioInterface() self.assertTrue(hasattr(interface_enabled, 'prd_btn')) # Test with PRD disabled with patch.object(settings, 'enable_prd_generation', False): interface_disabled = GradioInterface() self.assertTrue(hasattr(interface_disabled, 'prd_btn')) def test_prd_constants_exist(self): """Test that PRD-related constants are properly defined""" from config.constants import PRD_TEMPLATE_SECTIONS, PRD_UI_LABELS # Test PRD template sections self.assertIsInstance(PRD_TEMPLATE_SECTIONS, list) self.assertGreater(len(PRD_TEMPLATE_SECTIONS), 0) expected_sections = [ "Executive Summary", "Problem Statement", "Goals & Objectives", "User Stories/Requirements", "Success Metrics", "Timeline/Milestones", "Technical Requirements", "Risk Assessment" ] for section in expected_sections: self.assertIn(section, PRD_TEMPLATE_SECTIONS) # Test PRD UI labels self.assertIsInstance(PRD_UI_LABELS, dict) self.assertGreater(len(PRD_UI_LABELS), 0) class TestPRDIntegrationScript(unittest.TestCase): """Integration tests from the original test_prd script""" def test_prd_components_creation(self): """Test PRD UI components creation (from original test_prd script)""" try: from ui.components import ComponentFactory from config.settings import settings # Test PRD output component creation prd_output = ComponentFactory.create_prd_output() self.assertIsNotNone(prd_output) # Test PRD settings self.assertIsNotNone(settings.enable_prd_generation) self.assertIsNotNone(settings.prd_openai_model) self.assertIsNotNone(settings.prd_max_tokens) self.assertIsNotNone(settings.prd_temperature) self.assertIsNotNone(settings.prd_file_prefix) # Test PRD config method prd_config = settings.get_prd_config() self.assertIsInstance(prd_config, dict) except Exception as e: self.fail(f"PRD components creation failed: {e}") def test_prd_services_integration(self): """Test PRD services integration (from original test_prd script)""" try: from services.openai_service import OpenAIService from services.file_service import FileService # Test OpenAI service PRD method openai_service = OpenAIService() self.assertTrue(hasattr(openai_service, 'generate_prd_from_key_points')) # Test File service PRD methods file_service = FileService() self.assertTrue(hasattr(file_service, 'create_prd_download_file')) self.assertTrue(hasattr(file_service, 'validate_prd_content')) except Exception as e: self.fail(f"PRD services integration failed: {e}") def test_prd_interface_integration(self): """Test PRD interface integration (from original test_prd script)""" with patch('ui.gradio_interface.gr') as mock_gr: mock_gr.Textbox = MagicMock() mock_gr.Button = MagicMock() mock_gr.File = MagicMock() mock_gr.Column = MagicMock() mock_gr.Row = MagicMock() try: from ui.gradio_interface import GradioInterface # Test interface creation with PRD enabled interface = GradioInterface() # Check if PRD components are initialized self.assertTrue(hasattr(interface, 'prd_btn')) self.assertTrue(hasattr(interface, 'prd_output')) self.assertTrue(hasattr(interface, 'prd_download_file')) self.assertTrue(hasattr(interface, '_process_prd_generation')) except Exception as e: self.fail(f"PRD interface integration failed: {e}") def run_prd_ui_tests(): """Run all PRD UI tests""" # Create test suite suite = unittest.TestSuite() # Add test cases suite.addTest(unittest.makeSuite(TestPRDUIComponents)) suite.addTest(unittest.makeSuite(TestPRDInterfaceIntegration)) suite.addTest(unittest.makeSuite(TestPRDSettings)) suite.addTest(unittest.makeSuite(TestPRDWorkflow)) suite.addTest(unittest.makeSuite(TestPRDIntegrationScript)) # Run tests runner = unittest.TextTestRunner(verbosity=2) result = runner.run(suite) return result.wasSuccessful() if __name__ == '__main__': print("๐Ÿงช Running PRD UI Tests") print("=" * 60) success = run_prd_ui_tests() if success: print("\n๐ŸŽ‰ All PRD UI tests passed!") else: print("\nโŒ Some PRD UI tests failed!") sys.exit(0 if success else 1)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tomdwipo/agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server