fix: move Gitea integration tests to issue-facade capability
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled

Corrected the location of Gitea integration tests. They belong in the
issue-facade capability, not release-management, as they test issue
tracking functionality (issues, milestones, labels), not package
publishing.

Changes:
- Deleted: capabilities/release-management/tests/test_gitea_integration.py
- Added to submodule: capabilities/issue-facade/tests/test_gitea_integration.py
- Updated submodule reference for issue-facade

Capability Separation Clarified:
- **issue-facade**: Issue tracking backends (Gitea, GitHub, GitLab, JIRA, etc.)
  - Provides unified CLI for issue management across different systems
  - Contains Gitea backend: issue_tracker/backends/gitea/backend.py

- **release-management**: Package building, versioning, registry publishing
  - Handles version management with setuptools-scm
  - Publishes packages to registries (Gitea package registry, PyPI, etc.)

Test Organization:
- issue-facade now has 55 tests total:
  - 20 tests in test_gitea_backend.py (passing - current backend)
  - 35 tests in test_gitea_integration.py (skipped - needs architecture update)

Main markitect test suite: 1,158 passed, 3 skipped (unchanged)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-17 15:40:30 +01:00
parent 9fe2960842
commit 01e5c811ab
2 changed files with 1 additions and 530 deletions

View File

@@ -1,529 +0,0 @@
"""
Tests for Gitea Issue/Milestone/Label Management (Future Functionality)
IMPORTANT: These tests are for Gitea issue tracker integration functionality
that is NOT YET IMPLEMENTED in the release-management capability.
The current release-management capability focuses on:
- Package registry operations (GiteaRegistry)
- Version management and tagging
- Package building and publishing
This test suite covers future Gitea API operations for:
- Issue management (create, update, close issues)
- Milestone tracking
- Label operations
These tests serve as:
1. Specification for future issue management features
2. Documentation of expected API behavior
3. Placeholder for when issue tracking integration is added
Current Status: SKIPPED - Functionality not implemented
Related: capabilities/release-management/src/release_management/registries/gitea/
"""
import pytest
from unittest.mock import Mock, MagicMock, patch
from datetime import datetime
# Skip all tests - this functionality doesn't exist in the capability yet
# Remove this skip marker when implementing Gitea issue management features
pytestmark = pytest.mark.skip(
reason="Gitea issue/milestone/label management not yet implemented in release-management capability. "
"Current capability only supports package registry operations."
)
class TestGiteaConfig:
"""Test GiteaConfig functionality."""
def test_config_creation(self):
"""Test basic config creation."""
config = GiteaConfig(
gitea_url="https://gitea.example.com",
repo_owner="test_owner",
repo_name="test_repo",
auth_token="test_token"
)
assert config.gitea_url == "https://gitea.example.com"
assert config.repo_owner == "test_owner"
assert config.repo_name == "test_repo"
assert config.auth_token == "test_token"
def test_api_url_properties(self):
"""Test API URL property generation."""
config = GiteaConfig(
gitea_url="https://gitea.example.com",
repo_owner="test_owner",
repo_name="test_repo"
)
assert config.base_api_url == "https://gitea.example.com/api/v1"
assert config.repo_api_url == "https://gitea.example.com/api/v1/repos/test_owner/test_repo"
assert config.issues_api_url == "https://gitea.example.com/api/v1/repos/test_owner/test_repo/issues"
@patch('gitea.config.subprocess.run')
def test_from_git_repository(self, mock_run):
"""Test config creation from git repository."""
mock_run.return_value = Mock(
stdout="https://gitea.example.com/owner/repo.git",
returncode=0
)
config = GiteaConfig.from_git_repository()
assert config.gitea_url == "https://gitea.example.com"
assert config.repo_owner == "owner"
assert config.repo_name == "repo"
def test_config_validation(self):
"""Test config validation."""
# Valid config should not raise
config = GiteaConfig(
gitea_url="https://gitea.example.com",
repo_owner="owner",
repo_name="repo"
)
config.validate() # Should not raise
# Invalid URL should raise
invalid_config = GiteaConfig(
gitea_url="invalid-url",
repo_owner="owner",
repo_name="repo"
)
with pytest.raises(Exception):
invalid_config.validate()
class TestIssuesClient:
"""Test IssuesClient functionality."""
def setup_method(self):
"""Set up test fixtures."""
self.mock_api = Mock()
self.client = IssuesClient(self.mock_api)
# Mock issue for responses
self.mock_issue = Mock(spec=Issue)
self.mock_issue.number = 1
self.mock_issue.title = "Test Issue"
self.mock_issue.body = "Test body"
self.mock_issue.state = "open"
self.mock_issue.html_url = "https://gitea.example.com/owner/repo/issues/1"
self.mock_issue.created_at = datetime(2023, 1, 1, 12, 0, 0)
self.mock_issue.updated_at = datetime(2023, 1, 1, 12, 0, 0)
self.mock_issue.assignee = None
self.mock_issue.labels = []
self.mock_issue.milestone = None
def test_get_issue(self):
"""Test getting a single issue."""
self.mock_api.get_issue.return_value = self.mock_issue
result = self.client.get(1)
assert result == self.mock_issue
self.mock_api.get_issue.assert_called_once_with(1)
def test_list_issues(self):
"""Test listing issues."""
self.mock_api.list_issues.return_value = [self.mock_issue]
result = self.client.list()
assert result == [self.mock_issue]
self.mock_api.list_issues.assert_called_once_with("all", 1, 50)
def test_list_issues_with_filters(self):
"""Test listing issues with filters."""
self.mock_api.list_issues.return_value = [self.mock_issue]
result = self.client.list(state="open", page=2, per_page=25)
assert result == [self.mock_issue]
self.mock_api.list_issues.assert_called_once_with("open", 2, 25)
def test_create_issue(self):
"""Test creating an issue."""
self.mock_api.create_issue.return_value = self.mock_issue
result = self.client.create("Test Title", "Test Body")
assert result == self.mock_issue
self.mock_api.create_issue.assert_called_once()
def test_create_issue_with_options(self):
"""Test creating an issue with optional fields."""
self.mock_api.create_issue.return_value = self.mock_issue
result = self.client.create(
"Test Title",
"Test Body",
assignees=["user1"],
milestone=1,
labels=["bug", "priority:high"]
)
assert result == self.mock_issue
self.mock_api.create_issue.assert_called_once()
def test_update_issue(self):
"""Test updating an issue."""
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.update(1, title="New Title")
assert result == self.mock_issue
self.mock_api.update_issue.assert_called_once()
def test_close_issue(self):
"""Test closing an issue."""
closed_issue = Mock(spec=Issue)
closed_issue.state = "closed"
self.mock_api.update_issue.return_value = closed_issue
result = self.client.close(1)
assert result.state == "closed"
self.mock_api.update_issue.assert_called_once()
def test_reopen_issue(self):
"""Test reopening an issue."""
opened_issue = Mock(spec=Issue)
opened_issue.state = "open"
self.mock_api.update_issue.return_value = opened_issue
result = self.client.reopen(1)
assert result.state == "open"
self.mock_api.update_issue.assert_called_once()
def test_add_labels(self):
"""Test adding labels to an issue."""
# Mock getting current issue
self.mock_issue.labels = [Mock(name="existing")]
self.mock_api.get_issue.return_value = self.mock_issue
# Mock update result
updated_issue = Mock(spec=Issue)
updated_issue.labels = [Mock(name="existing"), Mock(name="new")]
self.mock_api.update_issue.return_value = updated_issue
result = self.client.add_labels(1, ["new"])
assert len(result.labels) == 2
self.mock_api.get_issue.assert_called_once_with(1)
self.mock_api.update_issue.assert_called_once()
def test_remove_labels(self):
"""Test removing labels from an issue."""
# Mock getting current issue
label1 = Mock(name="keep")
label2 = Mock(name="remove")
self.mock_issue.labels = [label1, label2]
self.mock_api.get_issue.return_value = self.mock_issue
# Mock update result
updated_issue = Mock(spec=Issue)
updated_issue.labels = [label1]
self.mock_api.update_issue.return_value = updated_issue
result = self.client.remove_labels(1, ["remove"])
assert len(result.labels) == 1
self.mock_api.get_issue.assert_called_once_with(1)
self.mock_api.update_issue.assert_called_once()
def test_assign_to_milestone(self):
"""Test assigning issue to milestone."""
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.assign_to_milestone(1, 5)
assert result == self.mock_issue
self.mock_api.update_issue.assert_called_once()
def test_remove_from_milestone(self):
"""Test removing issue from milestone."""
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.remove_from_milestone(1)
assert result == self.mock_issue
self.mock_api.update_issue.assert_called_once()
def test_set_labels(self):
"""Test replacing all labels on an issue."""
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.set_labels(1, ["bug", "priority:high"])
assert result == self.mock_issue
self.mock_api.update_issue.assert_called_once()
def test_update_title(self):
"""Test updating only issue title."""
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.update_title(1, "New Title")
assert result == self.mock_issue
self.mock_api.update_issue.assert_called_once()
def test_update_body(self):
"""Test updating only issue body."""
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.update_body(1, "New Body")
assert result == self.mock_issue
self.mock_api.update_issue.assert_called_once()
def test_set_priority(self):
"""Test setting issue priority."""
# Mock getting current issue
self.mock_issue.labels = [Mock(name="bug")]
self.mock_api.get_issue.return_value = self.mock_issue
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.set_priority(1, Priority.HIGH)
assert result == self.mock_issue
self.mock_api.get_issue.assert_called_once_with(1)
self.mock_api.update_issue.assert_called_once()
def test_set_status(self):
"""Test setting issue status."""
# Mock getting current issue
self.mock_issue.labels = [Mock(name="bug")]
self.mock_api.get_issue.return_value = self.mock_issue
self.mock_api.update_issue.return_value = self.mock_issue
result = self.client.set_status(1, ProjectState.ACTIVE)
assert result == self.mock_issue
self.mock_api.get_issue.assert_called_once_with(1)
self.mock_api.update_issue.assert_called_once()
def test_to_dict(self):
"""Test converting issue to dictionary."""
result = self.client.to_dict(self.mock_issue)
expected_keys = ['number', 'title', 'body', 'state', 'html_url',
'created_at', 'updated_at', 'assignee', 'labels', 'milestone']
assert all(key in result for key in expected_keys)
assert result['number'] == 1
assert result['title'] == "Test Issue"
assert result['state'] == "open"
class TestMilestonesClient:
"""Test MilestonesClient functionality."""
def setup_method(self):
"""Set up test fixtures."""
self.mock_api = Mock()
self.client = MilestonesClient(self.mock_api)
self.mock_milestone = Mock(spec=Milestone)
self.mock_milestone.id = 1
self.mock_milestone.title = "Test Milestone"
def test_list_milestones(self):
"""Test listing milestones."""
self.mock_api.list_milestones.return_value = [self.mock_milestone]
result = self.client.list()
assert result == [self.mock_milestone]
self.mock_api.list_milestones.assert_called_once_with("all")
def test_list_open_milestones(self):
"""Test listing open milestones."""
self.mock_api.list_milestones.return_value = [self.mock_milestone]
result = self.client.list_open()
assert result == [self.mock_milestone]
self.mock_api.list_milestones.assert_called_once_with("open")
def test_create_milestone(self):
"""Test creating a milestone."""
self.mock_api.create_milestone.return_value = self.mock_milestone
result = self.client.create("Test Milestone", "Description")
assert result == self.mock_milestone
self.mock_api.create_milestone.assert_called_once()
class TestLabelsClient:
"""Test LabelsClient functionality."""
def setup_method(self):
"""Set up test fixtures."""
self.mock_api = Mock()
self.client = LabelsClient(self.mock_api)
self.mock_label = Mock(spec=Label)
self.mock_label.id = 1
self.mock_label.name = "bug"
def test_list_labels(self):
"""Test listing labels."""
self.mock_api.list_labels.return_value = [self.mock_label]
result = self.client.list()
assert result == [self.mock_label]
self.mock_api.list_labels.assert_called_once()
def test_create_label(self):
"""Test creating a label."""
self.mock_api.create_label.return_value = self.mock_label
result = self.client.create("bug", "red", "Bug reports")
assert result == self.mock_label
self.mock_api.create_label.assert_called_once()
class TestGiteaClient:
"""Test the main GiteaClient facade."""
@patch('gitea.client.GiteaApiClient')
def test_client_initialization(self, mock_api_client):
"""Test GiteaClient initialization."""
config = GiteaConfig(
gitea_url="https://gitea.example.com",
repo_owner="test_owner",
repo_name="test_repo"
)
client = GiteaClient(config)
assert isinstance(client.issues, IssuesClient)
assert isinstance(client.milestones, MilestonesClient)
assert isinstance(client.labels, LabelsClient)
mock_api_client.assert_called_once_with(config)
@patch('gitea.client.GiteaConfig.from_git_repository')
@patch('gitea.client.GiteaApiClient')
def test_client_auto_config(self, mock_api_client, mock_from_git):
"""Test GiteaClient with auto-detected config."""
mock_config = Mock()
mock_from_git.return_value = mock_config
client = GiteaClient()
mock_from_git.assert_called_once()
mock_api_client.assert_called_once_with(mock_config)
class TestErrorHandling:
"""Test error handling throughout the facade."""
def setup_method(self):
"""Set up test fixtures."""
self.mock_api = Mock()
self.client = IssuesClient(self.mock_api)
def test_gitea_error_propagation(self):
"""Test that GiteaError is properly propagated."""
self.mock_api.get_issue.side_effect = GiteaError("API Error")
with pytest.raises(GiteaError):
self.client.get(1)
def test_not_found_error_propagation(self):
"""Test that GiteaNotFoundError is properly propagated."""
self.mock_api.get_issue.side_effect = GiteaNotFoundError("Issue not found")
with pytest.raises(GiteaNotFoundError):
self.client.get(999)
def test_auth_error_propagation(self):
"""Test that GiteaAuthError is properly propagated."""
self.mock_api.create_issue.side_effect = GiteaAuthError("Unauthorized")
with pytest.raises(GiteaAuthError):
self.client.create("Title", "Body")
class TestIntegrationPatterns:
"""Test integration patterns and best practices."""
@patch('gitea.client.GiteaApiClient')
def test_consistent_interface(self, mock_api_client):
"""Test that the facade provides consistent interfaces."""
config = GiteaConfig(gitea_url="https://gitea.example.com",
repo_owner="owner", repo_name="repo")
client = GiteaClient(config)
# All sub-clients should be available
assert hasattr(client, 'issues')
assert hasattr(client, 'milestones')
assert hasattr(client, 'labels')
# All should have consistent method patterns
assert hasattr(client.issues, 'list')
assert hasattr(client.issues, 'get')
assert hasattr(client.issues, 'create')
assert hasattr(client.issues, 'update')
assert hasattr(client.milestones, 'list')
assert hasattr(client.milestones, 'create')
assert hasattr(client.labels, 'list')
assert hasattr(client.labels, 'create')
def test_backward_compatibility_dict_conversion(self):
"""Test that to_dict provides backward compatibility."""
mock_api = Mock()
client = IssuesClient(mock_api)
# Create a mock issue with all expected attributes
mock_issue = Mock(spec=Issue)
mock_issue.number = 1
mock_issue.title = "Test"
mock_issue.body = "Body"
mock_issue.state = "open"
mock_issue.html_url = "https://example.com"
mock_issue.created_at = datetime(2023, 1, 1)
mock_issue.updated_at = datetime(2023, 1, 1)
mock_issue.assignee = None
mock_issue.labels = []
mock_issue.milestone = None
result = client.to_dict(mock_issue)
# Should contain all expected fields for backward compatibility
required_fields = ['number', 'title', 'body', 'state', 'html_url',
'created_at', 'updated_at', 'assignee', 'labels', 'milestone']
for field in required_fields:
assert field in result, f"Missing required field: {field}"
def test_label_operations_consistency(self):
"""Test that label operations work consistently."""
mock_api = Mock()
client = IssuesClient(mock_api)
# Mock issue with labels
mock_issue = Mock()
mock_issue.labels = [Mock(name="bug"), Mock(name="priority:high")]
mock_api.get_issue.return_value = mock_issue
mock_api.update_issue.return_value = mock_issue
# Test all label operations
client.add_labels(1, ["new-label"])
client.remove_labels(1, ["old-label"])
client.set_labels(1, ["label1", "label2"])
# Should have made appropriate API calls
assert mock_api.get_issue.call_count == 2 # add_labels and remove_labels
assert mock_api.update_issue.call_count == 3 # all three operations