galaxis-agent/tests/test_gitea_client.py
머니페니 b2ad726fc4 feat: implement GiteaClient with Gitea REST API v1
Implemented full async Gitea REST API v1 client using httpx with the following methods:
- create_pull_request: Create PRs with title, head, base, and body
- merge_pull_request: Merge PRs with configurable merge type
- create_issue_comment: Post comments on issues/PRs
- get_issue: Fetch issue/PR details
- get_issue_comments: Retrieve all comments for an issue/PR
- create_branch: Create new branches from existing ones

Added lazy singleton pattern with get_gitea_client() factory function that reads GITEA_URL and GITEA_TOKEN from environment.

All methods properly call raise_for_status() and return JSON responses. Comprehensive test suite with 8 tests covering all methods plus error handling.
2026-03-20 16:11:52 +09:00

88 lines
3.7 KiB
Python

import pytest
import httpx
from unittest.mock import AsyncMock, MagicMock
from agent.utils.gitea_client import GiteaClient
@pytest.fixture
def gitea_client():
return GiteaClient(base_url="http://gitea:3000", token="test-token")
@pytest.fixture
def mock_response():
def _make(status_code=200, json_data=None):
resp = MagicMock(spec=httpx.Response)
resp.status_code = status_code
resp.json.return_value = json_data or {}
resp.raise_for_status = MagicMock()
if status_code >= 400:
resp.raise_for_status.side_effect = httpx.HTTPStatusError(
"error", request=MagicMock(), response=resp
)
return resp
return _make
@pytest.mark.asyncio
async def test_create_pull_request(gitea_client, mock_response):
pr_data = {"number": 1, "html_url": "http://gitea:3000/quant/galaxis-po/pulls/1"}
gitea_client._client.post = AsyncMock(return_value=mock_response(201, pr_data))
result = await gitea_client.create_pull_request(
owner="quant", repo="galaxis-po", title="feat: add feature",
head="galaxis-agent/abc123", base="main", body="PR body",
)
assert result["number"] == 1
call_url = gitea_client._client.post.call_args[0][0]
assert "/repos/quant/galaxis-po/pulls" in call_url
@pytest.mark.asyncio
async def test_create_issue_comment(gitea_client, mock_response):
comment_data = {"id": 42, "body": "작업을 시작합니다."}
gitea_client._client.post = AsyncMock(return_value=mock_response(201, comment_data))
result = await gitea_client.create_issue_comment(
owner="quant", repo="galaxis-po", issue_number=1, body="작업을 시작합니다."
)
assert result["id"] == 42
@pytest.mark.asyncio
async def test_get_issue(gitea_client, mock_response):
issue_data = {"number": 1, "title": "Fix bug", "body": "Bug description"}
gitea_client._client.get = AsyncMock(return_value=mock_response(200, issue_data))
result = await gitea_client.get_issue(owner="quant", repo="galaxis-po", issue_number=1)
assert result["title"] == "Fix bug"
@pytest.mark.asyncio
async def test_get_issue_comments(gitea_client, mock_response):
comments = [{"id": 1, "body": "comment1"}, {"id": 2, "body": "comment2"}]
gitea_client._client.get = AsyncMock(return_value=mock_response(200, comments))
result = await gitea_client.get_issue_comments(owner="quant", repo="galaxis-po", issue_number=1)
assert len(result) == 2
@pytest.mark.asyncio
async def test_merge_pull_request(gitea_client, mock_response):
gitea_client._client.post = AsyncMock(return_value=mock_response(200, {}))
await gitea_client.merge_pull_request(owner="quant", repo="galaxis-po", pr_number=1, merge_type="merge")
call_url = gitea_client._client.post.call_args[0][0]
assert "/pulls/1/merge" in call_url
@pytest.mark.asyncio
async def test_create_branch(gitea_client, mock_response):
branch_data = {"name": "galaxis-agent/abc123"}
gitea_client._client.post = AsyncMock(return_value=mock_response(201, branch_data))
result = await gitea_client.create_branch(
owner="quant", repo="galaxis-po", branch_name="galaxis-agent/abc123", old_branch="main",
)
assert result["name"] == "galaxis-agent/abc123"
@pytest.mark.asyncio
async def test_api_error_raises_exception(gitea_client, mock_response):
gitea_client._client.post = AsyncMock(return_value=mock_response(404))
with pytest.raises(httpx.HTTPStatusError):
await gitea_client.create_pull_request(
owner="quant", repo="galaxis-po", title="t", head="h", base="b", body=""
)
@pytest.mark.asyncio
async def test_client_close(gitea_client):
gitea_client._client.aclose = AsyncMock()
await gitea_client.close()
gitea_client._client.aclose.assert_called_once()