| | |
| | |
| |
|
| | """ |
| | Unit tests for the Agent Manager |
| | """ |
| |
|
| | import unittest |
| | from unittest.mock import patch, MagicMock |
| | import os |
| | import sys |
| | from pathlib import 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""" |
| | |
| | self.mock_progress_tracker = MagicMock() |
| | self.mock_results_dashboard = MagicMock() |
| | |
| | |
| | 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() |
| | |
| | |
| | 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""" |
| | |
| | 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} |
| | } |
| | |
| | |
| | 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() |
| | |
| | |
| | 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"] |
| | ) |
| | |
| | |
| | self.assertTrue(result["success"]) |
| | self.assertEqual(result["repo_path"], "/test/repo") |
| | |
| | |
| | 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") |
| | |
| | |
| | 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() |
| | |
| | |
| | self.assertEqual(self.mock_progress_tracker.update.call_count, 8) |
| | |
| | @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""" |
| | |
| | mock_validate_url.return_value = False |
| | |
| | |
| | result = self.agent_manager.start_review( |
| | repo_url="invalid_url", |
| | languages=["Python"], |
| | features=["code_analysis"] |
| | ) |
| | |
| | |
| | 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""" |
| | |
| | mock_validate_url.return_value = True |
| | mock_clone_repo.side_effect = Exception("Clone error") |
| | |
| | |
| | result = self.agent_manager.start_review( |
| | repo_url="https://github.com/user/repo", |
| | languages=["Python"], |
| | features=["code_analysis"] |
| | ) |
| | |
| | |
| | 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""" |
| | |
| | mock_analyze_code.return_value = {"Python": {"issues": [], "issue_count": 0}} |
| | |
| | |
| | self.agent_manager._repo_path = "/test/repo" |
| | self.agent_manager._languages = ["Python"] |
| | self.agent_manager._results = {} |
| | |
| | self.agent_manager._analyze_code() |
| | |
| | |
| | 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""" |
| | |
| | mock_scan_repo.return_value = {"Python": {"vulnerabilities": [], "vulnerability_count": 0}} |
| | |
| | |
| | self.agent_manager._repo_path = "/test/repo" |
| | self.agent_manager._languages = ["Python"] |
| | self.agent_manager._results = {} |
| | |
| | self.agent_manager._scan_security() |
| | |
| | |
| | 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""" |
| | |
| | mock_analyze_repo.return_value = { |
| | "language_results": {"Python": {"issues": [], "issue_count": 0}}, |
| | "hotspots": [] |
| | } |
| | |
| | |
| | self.agent_manager._repo_path = "/test/repo" |
| | self.agent_manager._languages = ["Python"] |
| | self.agent_manager._results = {} |
| | |
| | self.agent_manager._analyze_performance() |
| | |
| | |
| | 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""" |
| | |
| | mock_is_available.return_value = True |
| | mock_review_repo.return_value = { |
| | "status": "success", |
| | "reviews": {}, |
| | "summary": "AI review summary" |
| | } |
| | |
| | |
| | self.agent_manager._repo_path = "/test/repo" |
| | self.agent_manager._languages = ["Python"] |
| | self.agent_manager._results = {} |
| | |
| | self.agent_manager._perform_ai_review() |
| | |
| | |
| | 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""" |
| | |
| | mock_is_available.return_value = False |
| | |
| | |
| | self.agent_manager._repo_path = "/test/repo" |
| | self.agent_manager._languages = ["Python"] |
| | self.agent_manager._results = {} |
| | |
| | self.agent_manager._perform_ai_review() |
| | |
| | |
| | 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""" |
| | |
| | mock_generate_report.return_value = { |
| | "json": "/test/reports/report.json", |
| | "html": "/test/reports/report.html" |
| | } |
| | |
| | |
| | self.agent_manager._repo_name = "repo" |
| | self.agent_manager._results = {"test": "data"} |
| | |
| | self.agent_manager._generate_report() |
| | |
| | |
| | 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""" |
| | |
| | mock_generate_report.return_value = { |
| | "json": "/test/reports/report.json" |
| | } |
| | |
| | |
| | self.agent_manager._repo_name = "repo" |
| | self.agent_manager._results = {"test": "data"} |
| | |
| | result = self.agent_manager.export_report("json") |
| | |
| | |
| | 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""" |
| | |
| | mock_generate_report.side_effect = Exception("Export error") |
| | |
| | |
| | self.agent_manager._repo_name = "repo" |
| | self.agent_manager._results = {"test": "data"} |
| | |
| | result = self.agent_manager.export_report("json") |
| | |
| | |
| | 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""" |
| | |
| | mock_clone_repo.return_value = "/test/repo" |
| | |
| | |
| | repo_path = self.agent_manager._clone_repository("https://github.com/user/repo") |
| | |
| | |
| | self.assertEqual(repo_path, "/test/repo") |
| | mock_clone_repo.assert_called_once() |
| | |
| | def test_update_progress(self): |
| | """Test _update_progress method""" |
| | |
| | self.agent_manager._update_progress("Test step", 50, "Test message") |
| | |
| | |
| | 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""" |
| | |
| | with patch('gradio.Markdown'), patch('gradio.Slider'), patch('gradio.Accordion'), patch('gradio.Group'): |
| | |
| | progress_tracker = self.agent_manager._create_progress_tracker() |
| | |
| | |
| | self.assertIsNotNone(progress_tracker) |
| | |
| | def test_create_results_dashboard(self): |
| | """Test _create_results_dashboard method""" |
| | |
| | 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'): |
| | |
| | |
| | results_dashboard = self.agent_manager._create_results_dashboard() |
| | |
| | |
| | self.assertIsNotNone(results_dashboard) |
| | |
| | def test_create_error_progress_tracker(self): |
| | """Test _create_error_progress_tracker method""" |
| | |
| | with patch('gradio.Markdown'), patch('gradio.Group'): |
| | |
| | error_tracker = self.agent_manager._create_error_progress_tracker("Test error") |
| | |
| | |
| | self.assertIsNotNone(error_tracker) |
| |
|
| |
|
| | if __name__ == "__main__": |
| | unittest.main() |