"""
Unit Tests for Enhanced MCP Tools
Tests the enhanced MCP tools for repository analysis.
"""
import pytest
from unittest.mock import Mock, patch
# Import functions inside test methods to avoid import issues
# This matches the pattern used in other tests
@pytest.mark.unit
class TestAnalyzeRepositoryHealth:
"""Test cases for analyze_repository_health tool."""
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_analyze_repository_health_success(self, mock_service_class):
"""Test successful repository health analysis."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import analyze_repository_health
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service.git_implementation = "GitPython"
mock_service_class.return_value = mock_service
# Mock repository status
mock_service.get_repository_status.return_value = {
"repository_stats": {
"total_commits": 100,
"total_branches": 3,
"total_tags": 2,
},
"current_branch": "main",
"staged_files_count": 0,
"unstaged_files_count": 2,
"untracked_files_count": 1,
"staging_clean": True,
}
# Mock commit data
mock_service.git_service.get_commits.return_value = [
{
"committed_date": "2025-07-01T12:00:00",
"author_name": "Test User",
"stats": {"insertions": 10, "deletions": 5},
},
{
"committed_date": "2025-07-02T12:00:00",
"author_name": "Another User",
"stats": {"insertions": 20, "deletions": 10},
},
]
# Call the function
result = analyze_repository_health(repo_path="/test/repo")
# Verify result
assert result["success"] is True
assert result["repository_path"] == "/test/repo"
assert result["implementation"] == "GitPython"
assert "health_analysis" in result
assert "overall_score" in result["health_analysis"]
assert "commit_frequency" in result["health_analysis"]
assert "author_analysis" in result["health_analysis"]
assert "repository_structure" in result["health_analysis"]
assert "working_directory" in result["health_analysis"]
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_analyze_repository_health_git_disabled(self, mock_service_class):
"""Test repository health analysis with git disabled."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import analyze_repository_health
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = False
mock_service_class.return_value = mock_service
# Call the function
result = analyze_repository_health(repo_path="/test/repo")
# Verify result
assert result["success"] is False
assert "error" in result
assert "Enhanced features not available" in result["error"]
assert result["repository_path"] == "/test/repo"
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_analyze_repository_health_error(self, mock_service_class):
"""Test repository health analysis with error."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import analyze_repository_health
# Setup mock service to raise exception
mock_service_class.side_effect = Exception("Test error")
# Call the function
result = analyze_repository_health(repo_path="/test/repo")
# Verify result
assert result["success"] is False
assert "error" in result
assert "Test error" in result["error"]
assert result["repository_path"] == "/test/repo"
@pytest.mark.unit
class TestGetDetailedDiffAnalysis:
"""Test cases for get_detailed_diff_analysis tool."""
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_get_detailed_diff_analysis_success(self, mock_service_class):
"""Test successful detailed diff analysis."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import get_detailed_diff_analysis
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service.git_implementation = "GitPython"
mock_service_class.return_value = mock_service
# Mock repository and diff objects
mock_repo = Mock()
mock_service.git_service.repo = mock_repo
# Mock diff items
mock_diff_item = Mock()
mock_diff_item.a_path = "test.py"
mock_diff_item.b_path = "test.py"
mock_diff_item.change_type = "M"
mock_diff_item.diff = (
b"@@ -1,5 +1,7 @@\n+new line\n existing line\n-removed line"
)
# Mock index diff methods
mock_repo.index.diff.return_value = [mock_diff_item]
# Call the function
result = get_detailed_diff_analysis(
repo_path="/test/repo", compare_with="HEAD", include_content=True
)
# Verify result
assert result["success"] is True
assert result["repository_path"] == "/test/repo"
assert result["implementation"] == "GitPython"
assert "diff_analysis" in result
assert "staged_changes" in result["diff_analysis"]
assert "unstaged_changes" in result["diff_analysis"]
assert "summary" in result["diff_analysis"]
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_get_detailed_diff_analysis_git_disabled(self, mock_service_class):
"""Test detailed diff analysis with git disabled."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import get_detailed_diff_analysis
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = False
mock_service_class.return_value = mock_service
# Call the function
result = get_detailed_diff_analysis(repo_path="/test/repo")
# Verify result
assert result["success"] is False
assert "error" in result
assert "Enhanced diff analysis requires GitPython" in result["error"]
assert result["repository_path"] == "/test/repo"
@pytest.mark.unit
class TestGetBranchAnalysis:
"""Test cases for get_branch_analysis tool."""
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_get_branch_analysis_success(self, mock_service_class):
"""Test successful branch analysis."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import get_branch_analysis
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service.git_implementation = "GitPython"
mock_service_class.return_value = mock_service
# Mock repository
mock_repo = Mock()
mock_service.git_service.repo = mock_repo
# Mock branch
mock_branch = Mock()
mock_branch.name = "main"
mock_branch.commit.hexsha = "abcdef1234567890"
mock_branch.commit.summary = "Test commit"
mock_branch.commit.author.name = "Test User"
mock_branch.commit.committed_datetime.isoformat.return_value = (
"2025-07-01T12:00:00"
)
# Mock active branch
mock_repo.active_branch = mock_branch
# Mock branches
mock_repo.branches = [mock_branch]
# Mock remote
mock_remote = Mock()
mock_remote.name = "origin"
# Mock remote ref
mock_ref = Mock()
mock_ref.name = "origin/main"
mock_ref.commit = mock_branch.commit
# Mock remotes
mock_remote.refs = [mock_ref]
mock_repo.remotes = [mock_remote]
# Mock iter_commits
mock_repo.iter_commits.return_value = [mock_branch.commit]
# Call the function
result = get_branch_analysis(repo_path="/test/repo")
# Verify result
assert result["success"] is True
assert result["repository_path"] == "/test/repo"
assert result["implementation"] == "GitPython"
assert "branch_analysis" in result
assert "current_branch" in result["branch_analysis"]
assert "local_branches" in result["branch_analysis"]
assert "remote_branches" in result["branch_analysis"]
assert "summary" in result["branch_analysis"]
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_get_branch_analysis_git_disabled(self, mock_service_class):
"""Test branch analysis with git disabled."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import get_branch_analysis
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = False
mock_service_class.return_value = mock_service
# Call the function
result = get_branch_analysis(repo_path="/test/repo")
# Verify result
assert result["success"] is False
assert "error" in result
assert "Branch analysis requires GitPython" in result["error"]
assert result["repository_path"] == "/test/repo"
@pytest.mark.unit
class TestSmartCommitSuggestion:
"""Test cases for smart_commit_suggestion tool."""
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_smart_commit_suggestion_success(self, mock_service_class):
"""Test successful smart commit suggestion."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import smart_commit_suggestion
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service.git_implementation = "GitPython"
mock_service_class.return_value = mock_service
# Mock repository status
mock_service.get_repository_status.return_value = {
"staging_clean": False,
"staged_files": ["src/test.py", "docs/README.md"],
}
# Call the function
result = smart_commit_suggestion(
repo_path="/test/repo",
analyze_changes=True,
suggest_type=True,
suggest_scope=True,
)
# Verify result
assert result["success"] is True
assert result["repository_path"] == "/test/repo"
assert result["implementation"] == "GitPython"
assert "suggestions" in result
assert "types" in result["suggestions"]
assert "scopes" in result["suggestions"]
assert "subjects" in result["suggestions"]
assert "analysis" in result["suggestions"]
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_smart_commit_suggestion_no_staged_files(self, mock_service_class):
"""Test smart commit suggestion with no staged files."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import smart_commit_suggestion
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service_class.return_value = mock_service
# Mock repository status with clean staging
mock_service.get_repository_status.return_value = {
"staging_clean": True,
"staged_files": [],
}
# Call the function
result = smart_commit_suggestion(repo_path="/test/repo")
# Verify result
assert result["success"] is False
assert "error" in result
assert "No staged changes to analyze" in result["error"]
assert result["repository_path"] == "/test/repo"
@pytest.mark.unit
class TestBatchCommitAnalysis:
"""Test cases for batch_commit_analysis tool."""
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_batch_commit_analysis_success(self, mock_service_class):
"""Test successful batch commit analysis."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import batch_commit_analysis
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service.git_implementation = "GitPython"
mock_service_class.return_value = mock_service
# Prepare file groups
file_groups = [
{
"description": "Feature implementation",
"files": ["src/feature.py", "tests/test_feature.py"],
},
{
"description": "Documentation update",
"files": ["docs/README.md", "docs/USAGE.md"],
},
]
# Call the function
result = batch_commit_analysis(
repo_path="/test/repo", file_groups=file_groups, generate_messages=True
)
# Verify result
assert result["success"] is True
assert result["repository_path"] == "/test/repo"
assert result["implementation"] == "GitPython"
assert "batch_analysis" in result
assert len(result["batch_analysis"]) == 2
assert "total_groups" in result
assert result["total_groups"] == 2
assert "total_files" in result
assert result["total_files"] == 4
@patch("commit_helper_mcp.server.enhanced_tools.CommitzenService")
def test_batch_commit_analysis_empty_groups(self, mock_service_class):
"""Test batch commit analysis with empty groups."""
# Import function to test
from commit_helper_mcp.server.enhanced_tools import batch_commit_analysis
# Setup mock service
mock_service = Mock()
mock_service.git_enabled = True
mock_service.git_implementation = "GitPython"
mock_service_class.return_value = mock_service
# Prepare empty file groups
file_groups = [{"description": "Empty group", "files": []}]
# Call the function
result = batch_commit_analysis(repo_path="/test/repo", file_groups=file_groups)
# Verify result
assert result["success"] is True
assert result["repository_path"] == "/test/repo"
assert "batch_analysis" in result
assert len(result["batch_analysis"]) == 0
assert "total_groups" in result
assert result["total_groups"] == 0