mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-02 11:50:37 +08:00
127 lines
5.5 KiB
Python
127 lines
5.5 KiB
Python
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from pr_agent.algo.types import EDIT_TYPE
|
|
from pr_agent.git_providers.gitea_provider import GiteaProvider
|
|
|
|
|
|
class TestGiteaProvider:
|
|
"""Unit-tests for GiteaProvider following project style (explicit object construction, minimal patching)."""
|
|
|
|
def _provider(self):
|
|
"""Create provider instance with patched settings and avoid real HTTP calls."""
|
|
with patch('pr_agent.git_providers.gitea_provider.get_settings') as mock_get_settings, \
|
|
patch('requests.get') as mock_get:
|
|
settings = MagicMock()
|
|
settings.get.side_effect = lambda k, d=None: {
|
|
'GITEA.URL': 'https://gitea.example.com',
|
|
'GITEA.TOKEN': 'test-token'
|
|
}.get(k, d)
|
|
mock_get_settings.return_value = settings
|
|
# Stub the PR fetch triggered during provider initialization
|
|
pr_resp = MagicMock()
|
|
pr_resp.json.return_value = {
|
|
'title': 'stub',
|
|
'body': 'stub',
|
|
'head': {'ref': 'main'},
|
|
'user': {'id': 1}
|
|
}
|
|
pr_resp.raise_for_status = MagicMock()
|
|
mock_get.return_value = pr_resp
|
|
return GiteaProvider('https://gitea.example.com/owner/repo/pulls/123')
|
|
|
|
# ---------------- URL parsing ----------------
|
|
def test_parse_pr_url_valid(self):
|
|
owner, repo, pr_num = GiteaProvider._parse_pr_url('https://gitea.example.com/owner/repo/pulls/123')
|
|
assert (owner, repo, pr_num) == ('owner', 'repo', '123')
|
|
|
|
def test_parse_pr_url_invalid(self):
|
|
with pytest.raises(ValueError):
|
|
GiteaProvider._parse_pr_url('https://gitea.example.com/owner/repo')
|
|
|
|
# ---------------- simple getters ----------------
|
|
def test_get_files(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock()
|
|
mock_resp.json.return_value = [{'filename': 'a.txt'}, {'filename': 'b.txt'}]
|
|
mock_resp.raise_for_status = MagicMock()
|
|
with patch('requests.get', return_value=mock_resp) as mock_get:
|
|
assert provider.get_files() == ['a.txt', 'b.txt']
|
|
mock_get.assert_called_once()
|
|
|
|
def test_get_diff_files(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock()
|
|
mock_resp.json.return_value = [
|
|
{'filename': 'f1', 'previous_filename': 'old_f1', 'status': 'renamed', 'patch': ''},
|
|
{'filename': 'f2', 'status': 'added', 'patch': ''},
|
|
{'filename': 'f3', 'status': 'deleted', 'patch': ''},
|
|
{'filename': 'f4', 'status': 'modified', 'patch': ''}
|
|
]
|
|
mock_resp.raise_for_status = MagicMock()
|
|
with patch('requests.get', return_value=mock_resp):
|
|
res = provider.get_diff_files()
|
|
assert [f.edit_type for f in res] == [EDIT_TYPE.RENAMED, EDIT_TYPE.ADDED, EDIT_TYPE.DELETED,
|
|
EDIT_TYPE.MODIFIED]
|
|
|
|
# ---------------- publishing methods ----------------
|
|
def test_publish_description(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock();
|
|
mock_resp.raise_for_status = MagicMock()
|
|
with patch('requests.patch', return_value=mock_resp) as mock_patch:
|
|
provider.publish_description('t', 'b');
|
|
mock_patch.assert_called_once()
|
|
|
|
def test_publish_comment(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock();
|
|
mock_resp.raise_for_status = MagicMock()
|
|
with patch('requests.post', return_value=mock_resp) as mock_post:
|
|
provider.publish_comment('c');
|
|
mock_post.assert_called_once()
|
|
|
|
def test_publish_inline_comment(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock();
|
|
mock_resp.raise_for_status = MagicMock()
|
|
with patch('requests.post', return_value=mock_resp) as mock_post:
|
|
provider.publish_inline_comment('body', 'file', '10');
|
|
mock_post.assert_called_once()
|
|
|
|
# ---------------- labels & reactions ----------------
|
|
def test_get_pr_labels(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock();
|
|
mock_resp.raise_for_status = MagicMock();
|
|
mock_resp.json.return_value = [{'name': 'l1'}]
|
|
with patch('requests.get', return_value=mock_resp):
|
|
assert provider.get_pr_labels() == ['l1']
|
|
|
|
def test_add_eyes_reaction(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock();
|
|
mock_resp.raise_for_status = MagicMock();
|
|
mock_resp.json.return_value = {'id': 7}
|
|
with patch('requests.post', return_value=mock_resp):
|
|
assert provider.add_eyes_reaction(1) == 7
|
|
|
|
# ---------------- commit messages & url helpers ----------------
|
|
def test_get_commit_messages(self):
|
|
provider = self._provider()
|
|
mock_resp = MagicMock();
|
|
mock_resp.raise_for_status = MagicMock()
|
|
mock_resp.json.return_value = [
|
|
{'commit': {'message': 'm1'}}, {'commit': {'message': 'm2'}}]
|
|
with patch('requests.get', return_value=mock_resp):
|
|
assert provider.get_commit_messages() == ['m1', 'm2']
|
|
|
|
def test_git_url_helpers(self):
|
|
provider = self._provider()
|
|
issues_url = 'https://gitea.example.com/owner/repo/pulls/3'
|
|
assert provider.get_git_repo_url(issues_url) == 'https://gitea.example.com/owner/repo.git'
|
|
prefix, suffix = provider.get_canonical_url_parts('https://gitea.example.com/owner/repo.git', 'dev')
|
|
assert prefix == 'https://gitea.example.com/owner/repo/src/branch/dev'
|
|
assert suffix == ''
|