generated from personal-projects/leo-claude-mktplace
- Copied source from leo-claude-mktplace/mcp-servers/gitea/ v1.0.0 - Renamed module: mcp_server → gitea_mcp (all imports updated) - Created pyproject.toml for standalone package identity - Preserved all existing tools and test suite - MCP SDK imports unchanged Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
164 lines
5.8 KiB
Python
164 lines
5.8 KiB
Python
"""
|
|
Unit tests for issue tools with branch detection.
|
|
"""
|
|
import pytest
|
|
from unittest.mock import Mock, patch, AsyncMock
|
|
from gitea_mcp.tools.issues import IssueTools
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_gitea_client():
|
|
"""Fixture providing mocked Gitea client"""
|
|
client = Mock()
|
|
client.mode = 'project'
|
|
return client
|
|
|
|
|
|
@pytest.fixture
|
|
def issue_tools(mock_gitea_client):
|
|
"""Fixture providing IssueTools instance"""
|
|
return IssueTools(mock_gitea_client)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_issues_development_branch(issue_tools):
|
|
"""Test listing issues on development branch (allowed)"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='feat/test-feature'):
|
|
issue_tools.gitea.list_issues = Mock(return_value=[{'number': 1}])
|
|
|
|
issues = await issue_tools.list_issues(state='open')
|
|
|
|
assert len(issues) == 1
|
|
issue_tools.gitea.list_issues.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_issue_development_branch(issue_tools):
|
|
"""Test creating issue on development branch (allowed)"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='development'):
|
|
issue_tools.gitea.create_issue = Mock(return_value={'number': 1})
|
|
|
|
issue = await issue_tools.create_issue('Test', 'Body')
|
|
|
|
assert issue['number'] == 1
|
|
issue_tools.gitea.create_issue.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_issue_main_branch_blocked(issue_tools):
|
|
"""Test creating issue on main branch (blocked)"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='main'):
|
|
with pytest.raises(PermissionError) as exc_info:
|
|
await issue_tools.create_issue('Test', 'Body')
|
|
|
|
assert "Cannot create issues on branch 'main'" in str(exc_info.value)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_issue_staging_branch_allowed(issue_tools):
|
|
"""Test creating issue on staging branch (allowed for documentation)"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='staging'):
|
|
issue_tools.gitea.create_issue = Mock(return_value={'number': 1})
|
|
|
|
issue = await issue_tools.create_issue('Test', 'Body')
|
|
|
|
assert issue['number'] == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_issue_main_branch_blocked(issue_tools):
|
|
"""Test updating issue on main branch (blocked)"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='main'):
|
|
with pytest.raises(PermissionError) as exc_info:
|
|
await issue_tools.update_issue(1, title='Updated')
|
|
|
|
assert "Cannot update issues on branch 'main'" in str(exc_info.value)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_issues_main_branch_allowed(issue_tools):
|
|
"""Test listing issues on main branch (allowed - read-only)"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='main'):
|
|
issue_tools.gitea.list_issues = Mock(return_value=[{'number': 1}])
|
|
|
|
issues = await issue_tools.list_issues(state='open')
|
|
|
|
assert len(issues) == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_issue(issue_tools):
|
|
"""Test getting specific issue"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='development'):
|
|
issue_tools.gitea.get_issue = Mock(return_value={'number': 1, 'title': 'Test'})
|
|
|
|
issue = await issue_tools.get_issue(1)
|
|
|
|
assert issue['number'] == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_add_comment(issue_tools):
|
|
"""Test adding comment to issue"""
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='development'):
|
|
issue_tools.gitea.add_comment = Mock(return_value={'body': 'Test comment'})
|
|
|
|
comment = await issue_tools.add_comment(1, 'Test comment')
|
|
|
|
assert comment['body'] == 'Test comment'
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_aggregate_issues_company_mode(issue_tools):
|
|
"""Test aggregating issues in company mode"""
|
|
issue_tools.gitea.mode = 'company'
|
|
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='development'):
|
|
issue_tools.gitea.aggregate_issues = Mock(return_value={
|
|
'repo1': [{'number': 1}],
|
|
'repo2': [{'number': 2}]
|
|
})
|
|
|
|
aggregated = await issue_tools.aggregate_issues(org='test_owner')
|
|
|
|
assert 'repo1' in aggregated
|
|
assert 'repo2' in aggregated
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_aggregate_issues_project_mode(issue_tools):
|
|
"""Test that aggregate_issues works in project mode with org argument"""
|
|
issue_tools.gitea.mode = 'project'
|
|
|
|
with patch.object(issue_tools, '_get_current_branch', return_value='development'):
|
|
issue_tools.gitea.aggregate_issues = Mock(return_value={
|
|
'repo1': [{'number': 1}]
|
|
})
|
|
|
|
# aggregate_issues now works in any mode when org is provided
|
|
aggregated = await issue_tools.aggregate_issues(org='test_owner')
|
|
|
|
assert 'repo1' in aggregated
|
|
|
|
|
|
def test_branch_detection():
|
|
"""Test branch detection logic"""
|
|
tools = IssueTools(Mock())
|
|
|
|
# Test development branches
|
|
with patch.object(tools, '_get_current_branch', return_value='development'):
|
|
assert tools._check_branch_permissions('create_issue') is True
|
|
|
|
with patch.object(tools, '_get_current_branch', return_value='feat/new-feature'):
|
|
assert tools._check_branch_permissions('create_issue') is True
|
|
|
|
# Test production branches
|
|
with patch.object(tools, '_get_current_branch', return_value='main'):
|
|
assert tools._check_branch_permissions('create_issue') is False
|
|
assert tools._check_branch_permissions('list_issues') is True
|
|
|
|
# Test staging branches
|
|
with patch.object(tools, '_get_current_branch', return_value='staging'):
|
|
assert tools._check_branch_permissions('create_issue') is True
|
|
assert tools._check_branch_permissions('update_issue') is False
|