Spaces:
Sleeping
Sleeping
#!/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 | |
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 | |
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"]) | |
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"]) | |
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"]) | |
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"]) | |
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"]) | |
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() | |
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"]) | |
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") | |
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") | |
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"]) | |
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() |