|
|
|
|
|
|
|
""" |
|
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() |