CodeReviewAgent / tests /test_agent_manager.py
c1r3x's picture
Review Agent: first commit
88d205f
#!/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()