Files
issue-core/tests/test_gitea_backend.py
tegwick b605d970e3 feat: rename to issue-core and add task ingestion endpoint
Renames the package, distribution, CLI alias, Makefile targets, and
working directory from issue-facade to issue-core, signalling its
role as the authoritative task lifecycle manager for the Coulomb org
(peer to activity-core, rules-core, project-core).

Adds POST /issues/ ingestion endpoint for activity-core's IssueSink,
under a new optional [api] extra. The endpoint is served by `issue
serve`, authenticates via the ISSUE_CORE_API_KEY env var (Bearer or
X-API-Key header), and routes the TaskSpec payload to the configured
default backend with full traceability metadata embedded in
sync_metadata.

- T01: Python package issue_tracker -> issue_core, dir rename
- T02: registered in state hub under custodian domain
- T03: INTENT.md (what it is, what it isn't, how it fits)
- T04: SCOPE.md (in/out-of-scope, integration boundaries)
- T05: POST /issues/ via FastAPI + Uvicorn, 9 unit tests
- T06: docs/nats-task-ingestion.md design stub

Closes ISSC-WP-0001.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 05:16:27 +02:00

195 lines
7.0 KiB
Python

"""
Test suite for Gitea backend functionality.
These tests ensure the Gitea backend works correctly with the API.
"""
import pytest
import json
from unittest.mock import Mock, patch, MagicMock
from issue_core.backends.gitea.backend import GiteaBackend, GiteaAPIError
class TestGiteaBackend:
"""Test Gitea backend implementation."""
def setup_method(self):
"""Set up test environment."""
self.backend = GiteaBackend()
self.test_config = {
'type': 'gitea',
'base_url': 'https://git.example.com',
'owner': 'testorg',
'repo': 'testrepo',
'token': 'test-token'
}
def test_backend_initialization(self):
"""Test backend initializes correctly."""
assert self.backend.base_url is None
assert self.backend.token is None
assert self.backend.owner is None
assert self.backend.repo is None
assert self.backend.session is not None
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_connect_success(self, mock_session_class):
"""Test successful connection to Gitea API."""
mock_session = MagicMock()
mock_session_class.return_value = mock_session
# Mock successful API response
mock_response = Mock()
mock_response.status_code = 200
mock_session.request.return_value = mock_response
backend = GiteaBackend()
backend.session = mock_session
backend.connect(self.test_config)
# Verify configuration is set
assert backend.base_url == 'https://git.example.com'
assert backend.token == 'test-token'
assert backend.owner == 'testorg'
assert backend.repo == 'testrepo'
# Verify headers are set
mock_session.headers.update.assert_called_once_with({
'Authorization': 'token test-token',
'Content-Type': 'application/json',
'Accept': 'application/json'
})
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_connect_failure(self, mock_session_class):
"""Test failed connection raises appropriate error."""
mock_session = MagicMock()
mock_session_class.return_value = mock_session
# Mock failed API response
mock_response = Mock()
mock_response.status_code = 404
mock_session.request.return_value = mock_response
backend = GiteaBackend()
backend.session = mock_session
with pytest.raises(GiteaAPIError, match="Failed to connect to Gitea API"):
backend.connect(self.test_config)
def test_url_construction_fix(self):
"""Test that URL construction properly handles urljoin edge cases."""
backend = GiteaBackend()
backend.base_url = 'https://git.example.com'
# Test the fixed _api_request URL construction
with patch.object(backend.session, 'request') as mock_request:
mock_response = Mock()
mock_response.status_code = 200
mock_request.return_value = mock_response
backend._api_request('GET', '/repos/owner/repo')
# Verify the correct URL was called
mock_request.assert_called_once()
called_url = mock_request.call_args[1]['url'] if 'url' in mock_request.call_args[1] else mock_request.call_args[0][1]
assert called_url == 'https://git.example.com/api/v1/repos/owner/repo'
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_test_connection_success(self, mock_session_class):
"""Test test_connection method works correctly."""
mock_session = MagicMock()
mock_session_class.return_value = mock_session
# Mock successful API response
mock_response = Mock()
mock_response.status_code = 200
mock_session.request.return_value = mock_response
backend = GiteaBackend()
backend.session = mock_session
backend.base_url = 'https://git.example.com'
backend.owner = 'testorg'
backend.repo = 'testrepo'
backend.token = 'test-token'
result = backend.test_connection()
assert result is True
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_test_connection_failure(self, mock_session_class):
"""Test test_connection handles failures gracefully."""
mock_session = MagicMock()
mock_session_class.return_value = mock_session
# Mock failed API response
mock_response = Mock()
mock_response.status_code = 404
mock_response.raise_for_status.side_effect = Exception("404 Not Found")
mock_session.request.return_value = mock_response
backend = GiteaBackend()
backend.session = mock_session
backend.base_url = 'https://git.example.com'
backend.owner = 'testorg'
backend.repo = 'testrepo'
backend.token = 'test-token'
result = backend.test_connection()
assert result is False
@patch('issue_core.backends.gitea.backend.requests.Session')
def test_get_issue_success(self, mock_session_class):
"""Test successful issue retrieval."""
mock_session = MagicMock()
mock_session_class.return_value = mock_session
# Mock Gitea issue response
gitea_issue = {
"id": 123,
"number": 42,
"title": "Test Issue",
"body": "Test description",
"state": "open",
"user": {"login": "testuser", "email": "test@example.com"},
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z",
"labels": [],
"assignees": [],
"milestone": None,
"comments": 0
}
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = gitea_issue
mock_session.request.return_value = mock_response
backend = GiteaBackend()
backend.session = mock_session
backend.base_url = 'https://git.example.com'
backend.owner = 'testorg'
backend.repo = 'testrepo'
backend.token = 'test-token'
issue = backend.get_issue(42)
assert issue.number == 42
assert issue.title == "Test Issue"
assert issue.description == "Test description"
assert issue.state.value == "open"
def test_disconnect(self):
"""Test disconnect method cleans up properly."""
self.backend.base_url = 'https://git.example.com'
self.backend.token = 'test-token'
self.backend.owner = 'testorg'
self.backend.repo = 'testrepo'
self.backend.disconnect()
assert self.backend.base_url is None
assert self.backend.token is None
assert self.backend.owner is None
assert self.backend.repo is None