#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Unit tests for the Agent Manager """ import unittest from unittest.mock import patch, MagicMock import os import sys from pathlib import Path # Add the project root directory to the Python path project_root = Path(__file__).resolve().parent.parent sys.path.insert(0, str(project_root)) from src.core.agent_manager import AgentManager class TestAgentManager(unittest.TestCase): """Test cases for the AgentManager class""" def setUp(self): """Set up test fixtures""" # Create mock components self.mock_progress_tracker = MagicMock() self.mock_results_dashboard = MagicMock() # Create the agent manager with mocked components with patch('src.core.agent_manager.LanguageDetector'), \ patch('src.services.repository_service'), \ patch('src.services.code_analyzer.CodeAnalyzer'), \ patch('src.services.security_scanner.SecurityScanner'), \ patch('src.services.performance_analyzer.PerformanceAnalyzer'), \ patch('src.mcp.ai_review.AIReviewService'), \ patch('src.services.report_generator.ReportGenerator'): self.agent_manager = AgentManager() # Replace the UI components with mocks self.agent_manager._progress_tracker = self.mock_progress_tracker self.agent_manager._results_dashboard = self.mock_results_dashboard @patch('src.services.repository_service.validate_github_url') @patch('src.services.repository_service.clone_repository') @patch('src.services.repository_service.get_repository_info') @patch('src.core.language_detector.LanguageDetector.detect_languages') @patch('src.core.language_detector.LanguageDetector.get_language_breakdown') def test_start_review(self, mock_get_breakdown, mock_detect_languages, mock_get_repo_info, mock_clone_repo, mock_validate_url): """Test start_review method""" # Set up the mocks mock_validate_url.return_value = True mock_clone_repo.return_value = "/test/repo" mock_get_repo_info.return_value = {"branch": "main", "commit": "abc123"} mock_detect_languages.return_value = ["Python", "JavaScript"] mock_get_breakdown.return_value = { "Python": {"files": 5, "lines": 500, "percentage": 70}, "JavaScript": {"files": 3, "lines": 200, "percentage": 30} } # Mock the analysis methods self.agent_manager._analyze_code = MagicMock() self.agent_manager._scan_security = MagicMock() self.agent_manager._analyze_performance = MagicMock() self.agent_manager._perform_ai_review = MagicMock() self.agent_manager._generate_report = MagicMock() # Call the method result = self.agent_manager.start_review( repo_url="https://github.com/user/repo", languages=["Python", "JavaScript"], features=["code_analysis", "security_scan", "performance_analysis", "ai_review"] ) # Verify the result self.assertTrue(result["success"]) self.assertEqual(result["repo_path"], "/test/repo") # Verify the method calls mock_validate_url.assert_called_once_with("https://github.com/user/repo") mock_clone_repo.assert_called_once() mock_get_repo_info.assert_called_once_with("/test/repo") mock_detect_languages.assert_called_once_with("/test/repo") mock_get_breakdown.assert_called_once_with("/test/repo") # Verify the analysis method calls self.agent_manager._analyze_code.assert_called_once() self.agent_manager._scan_security.assert_called_once() self.agent_manager._analyze_performance.assert_called_once() self.agent_manager._perform_ai_review.assert_called_once() self.agent_manager._generate_report.assert_called_once() # Verify the progress updates self.assertEqual(self.mock_progress_tracker.update.call_count, 8) # Initial + 7 steps @patch('src.services.repository_service.validate_github_url') def test_start_review_invalid_url(self, mock_validate_url): """Test start_review method with invalid URL""" # Set up the mock mock_validate_url.return_value = False # Call the method result = self.agent_manager.start_review( repo_url="invalid_url", languages=["Python"], features=["code_analysis"] ) # Verify the result self.assertFalse(result["success"]) self.assertIn("Invalid GitHub URL", result["error"]) @patch('src.services.repository_service.validate_github_url') @patch('src.services.repository_service.clone_repository') def test_start_review_clone_error(self, mock_clone_repo, mock_validate_url): """Test start_review method with clone error""" # Set up the mocks mock_validate_url.return_value = True mock_clone_repo.side_effect = Exception("Clone error") # Call the method result = self.agent_manager.start_review( repo_url="https://github.com/user/repo", languages=["Python"], features=["code_analysis"] ) # Verify the result self.assertFalse(result["success"]) self.assertIn("Failed to clone repository", result["error"]) @patch('src.services.code_analyzer.CodeAnalyzer.analyze_code') def test_analyze_code(self, mock_analyze_code): """Test _analyze_code method""" # Set up the mock mock_analyze_code.return_value = {"Python": {"issues": [], "issue_count": 0}} # Call the method self.agent_manager._repo_path = "/test/repo" self.agent_manager._languages = ["Python"] self.agent_manager._results = {} self.agent_manager._analyze_code() # Verify the result self.assertIn("code_analysis", self.agent_manager._results) mock_analyze_code.assert_called_once_with("/test/repo", ["Python"]) @patch('src.services.security_scanner.SecurityScanner.scan_repository') def test_scan_security(self, mock_scan_repo): """Test _scan_security method""" # Set up the mock mock_scan_repo.return_value = {"Python": {"vulnerabilities": [], "vulnerability_count": 0}} # Call the method self.agent_manager._repo_path = "/test/repo" self.agent_manager._languages = ["Python"] self.agent_manager._results = {} self.agent_manager._scan_security() # Verify the result self.assertIn("security_scan", self.agent_manager._results) mock_scan_repo.assert_called_once_with("/test/repo", ["Python"]) @patch('src.services.performance_analyzer.PerformanceAnalyzer.analyze_repository') def test_analyze_performance(self, mock_analyze_repo): """Test _analyze_performance method""" # Set up the mock mock_analyze_repo.return_value = { "language_results": {"Python": {"issues": [], "issue_count": 0}}, "hotspots": [] } # Call the method self.agent_manager._repo_path = "/test/repo" self.agent_manager._languages = ["Python"] self.agent_manager._results = {} self.agent_manager._analyze_performance() # Verify the result self.assertIn("performance_analysis", self.agent_manager._results) mock_analyze_repo.assert_called_once_with("/test/repo", ["Python"]) @patch('src.mcp.ai_review.AIReviewService.is_available') @patch('src.mcp.ai_review.AIReviewService.review_repository') def test_perform_ai_review(self, mock_review_repo, mock_is_available): """Test _perform_ai_review method""" # Set up the mocks mock_is_available.return_value = True mock_review_repo.return_value = { "status": "success", "reviews": {}, "summary": "AI review summary" } # Call the method self.agent_manager._repo_path = "/test/repo" self.agent_manager._languages = ["Python"] self.agent_manager._results = {} self.agent_manager._perform_ai_review() # Verify the result self.assertIn("ai_review", self.agent_manager._results) mock_review_repo.assert_called_once() @patch('src.mcp.ai_review.AIReviewService.is_available') def test_perform_ai_review_unavailable(self, mock_is_available): """Test _perform_ai_review method when AI review is unavailable""" # Set up the mock mock_is_available.return_value = False # Call the method self.agent_manager._repo_path = "/test/repo" self.agent_manager._languages = ["Python"] self.agent_manager._results = {} self.agent_manager._perform_ai_review() # Verify the result self.assertIn("ai_review", self.agent_manager._results) self.assertEqual(self.agent_manager._results["ai_review"]["status"], "error") self.assertIn("AI review service is not available", self.agent_manager._results["ai_review"]["error"]) @patch('src.services.report_generator.ReportGenerator.generate_report') def test_generate_report(self, mock_generate_report): """Test _generate_report method""" # Set up the mock mock_generate_report.return_value = { "json": "/test/reports/report.json", "html": "/test/reports/report.html" } # Call the method self.agent_manager._repo_name = "repo" self.agent_manager._results = {"test": "data"} self.agent_manager._generate_report() # Verify the result self.assertIn("report_paths", self.agent_manager._results) mock_generate_report.assert_called_once_with("repo", {"test": "data"}, "all") @patch('src.services.report_generator.ReportGenerator.generate_report') def test_export_report(self, mock_generate_report): """Test export_report method""" # Set up the mock mock_generate_report.return_value = { "json": "/test/reports/report.json" } # Call the method self.agent_manager._repo_name = "repo" self.agent_manager._results = {"test": "data"} result = self.agent_manager.export_report("json") # Verify the result self.assertTrue(result["success"]) self.assertEqual(result["report_path"], "/test/reports/report.json") mock_generate_report.assert_called_once_with("repo", {"test": "data"}, "json") @patch('src.services.report_generator.ReportGenerator.generate_report') def test_export_report_error(self, mock_generate_report): """Test export_report method with error""" # Set up the mock mock_generate_report.side_effect = Exception("Export error") # Call the method self.agent_manager._repo_name = "repo" self.agent_manager._results = {"test": "data"} result = self.agent_manager.export_report("json") # Verify the result self.assertFalse(result["success"]) self.assertIn("Failed to export report", result["error"]) @patch('src.services.repository_service.clone_repository') def test_clone_repository(self, mock_clone_repo): """Test _clone_repository method""" # Set up the mock mock_clone_repo.return_value = "/test/repo" # Call the method repo_path = self.agent_manager._clone_repository("https://github.com/user/repo") # Verify the result self.assertEqual(repo_path, "/test/repo") mock_clone_repo.assert_called_once() def test_update_progress(self): """Test _update_progress method""" # Call the method self.agent_manager._update_progress("Test step", 50, "Test message") # Verify the result self.mock_progress_tracker.update.assert_called_once_with( "Test step", 50, "Test message" ) def test_create_progress_tracker(self): """Test _create_progress_tracker method""" # Mock the gradio components with patch('gradio.Markdown'), patch('gradio.Slider'), patch('gradio.Accordion'), patch('gradio.Group'): # Call the method progress_tracker = self.agent_manager._create_progress_tracker() # Verify the result self.assertIsNotNone(progress_tracker) def test_create_results_dashboard(self): """Test _create_results_dashboard method""" # Mock the gradio components with patch('gradio.Markdown'), patch('gradio.Dataframe'), patch('gradio.HighlightedText'), \ patch('gradio.Code'), patch('gradio.Accordion'), patch('gradio.Tab'), patch('gradio.Tabs'), \ patch('gradio.Group'): # Call the method results_dashboard = self.agent_manager._create_results_dashboard() # Verify the result self.assertIsNotNone(results_dashboard) def test_create_error_progress_tracker(self): """Test _create_error_progress_tracker method""" # Mock the gradio components with patch('gradio.Markdown'), patch('gradio.Group'): # Call the method error_tracker = self.agent_manager._create_error_progress_tracker("Test error") # Verify the result self.assertIsNotNone(error_tracker) if __name__ == "__main__": unittest.main()