refactor: extract focused clients from GiteaClient (Slices 1-6)

- Create gitea/issues_client.py with IssuesClient class (9 methods)
- Create gitea/prs_client.py with PullRequestsClient class (17 methods)
- Create gitea/files_client.py with FilesClient class (4 methods)
- Create gitea/notifications_client.py with NotificationsClient class (2 methods)
- Create gitea/repos_client.py with ReposClient class (2 methods)
- Create gitea/__init__.py to export all client classes
- Remove delegation methods from GiteaClient (now ~70 lines)
- Update all callers to use sub-clients (client.issues, client.prs, etc.)
- Update test files to mock sub-client attributes

GiteaClient is now a facade that provides access to focused sub-clients:
- repos: Repository operations (ReposClient)
- issues: Issue operations (IssuesClient)
- prs: Pull request operations (PullRequestsClient)
- files: File and git ref operations (FilesClient)
- notifications: Notification operations (NotificationsClient)

Refs: #godclass-refactor
This commit is contained in:
meeks
2026-07-17 07:31:05 +02:00
parent 3c94c3cfac
commit 25473ed684
21 changed files with 1480 additions and 728 deletions
+44 -20
View File
@@ -11,7 +11,7 @@ def test_gitea_client_list_repo_issues() -> None:
mock_get.return_value = mock_response
# Test default parameter ("open")
client.list_repo_issues("owner", "repo")
client.issues.list_repo_issues("owner", "repo")
mock_get.assert_called_once()
args, _ = mock_get.call_args
assert "type=issues" in args[0]
@@ -20,7 +20,7 @@ def test_gitea_client_list_repo_issues() -> None:
mock_get.reset_mock()
# Test custom parameter ("closed")
client.list_repo_issues("owner", "repo", state="closed")
client.issues.list_repo_issues("owner", "repo", state="closed")
mock_get.assert_called_once()
args, _ = mock_get.call_args
assert "type=issues" in args[0]
@@ -36,7 +36,7 @@ def test_gitea_client_list_repo_pull_requests() -> None:
mock_get.return_value = mock_response
# Test default parameter ("open")
client.list_repo_pull_requests("owner", "repo")
client.prs.list_repo_pull_requests("owner", "repo")
mock_get.assert_called_once()
args, _ = mock_get.call_args
assert "state=open" in args[0]
@@ -44,7 +44,7 @@ def test_gitea_client_list_repo_pull_requests() -> None:
mock_get.reset_mock()
# Test custom parameter ("closed")
client.list_repo_pull_requests("owner", "repo", state="closed")
client.prs.list_repo_pull_requests("owner", "repo", state="closed")
mock_get.assert_called_once()
args, _ = mock_get.call_args
assert "state=closed" in args[0]
@@ -55,14 +55,17 @@ def test_gitea_client_list_assigned_issues() -> None:
user_mock: MagicMock = MagicMock()
user_mock.login = "testuser"
with patch.object(client, "get_authenticated_user", return_value=user_mock), \
patch("httpx.Client.get") as mock_get:
with (
patch.object(client.repos, "get_authenticated_user", return_value=user_mock),
patch.object(client.issues, "_get_user", return_value=user_mock),
patch("httpx.Client.get") as mock_get,
):
mock_response: MagicMock = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = []
mock_get.return_value = mock_response
client.list_assigned_issues("owner", "repo")
client.issues.list_assigned_issues("owner", "repo")
mock_get.assert_called_once()
args, _ = mock_get.call_args
assert "type=issues" in args[0]
@@ -74,18 +77,36 @@ def test_gitea_client_list_assigned_pull_requests() -> None:
user_mock: MagicMock = MagicMock()
user_mock.login = "testuser"
with patch.object(client, "get_authenticated_user", return_value=user_mock), \
patch("httpx.Client.get") as mock_get:
with (
patch.object(client.repos, "get_authenticated_user", return_value=user_mock),
patch.object(client.prs, "_get_user", return_value=user_mock),
patch("httpx.Client.get") as mock_get,
):
mock_response: MagicMock = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = [
{"number": 1, "title": "PR 1", "assignee": {"login": "testuser"}, "user": {"login": "otheruser"}},
{"number": 2, "title": "PR 2", "assignee": None, "user": {"login": "testuser"}},
{"number": 3, "title": "PR 3", "assignee": {"login": "otheruser"}, "user": {"login": "otheruser"}}
{
"number": 1,
"title": "PR 1",
"assignee": {"login": "testuser"},
"user": {"login": "otheruser"},
},
{
"number": 2,
"title": "PR 2",
"assignee": None,
"user": {"login": "testuser"},
},
{
"number": 3,
"title": "PR 3",
"assignee": {"login": "otheruser"},
"user": {"login": "otheruser"},
},
]
mock_get.return_value = mock_response
res = client.list_assigned_pull_requests("owner", "repo")
res = client.prs.list_assigned_pull_requests("owner", "repo")
mock_get.assert_called_once()
assert len(res) == 2
numbers = [pr.number for pr in res]
@@ -106,7 +127,7 @@ def test_gitea_client_list_unread_notifications() -> None:
mock_get.return_value = mock_response
# Test without since
res = client.list_unread_notifications()
res = client.notifications.list_unread_notifications()
mock_get.assert_called_once()
_, kwargs = mock_get.call_args
assert kwargs.get("params") == {"all": "false"}
@@ -116,20 +137,23 @@ def test_gitea_client_list_unread_notifications() -> None:
mock_get.reset_mock()
# Test with since
res = client.list_unread_notifications(since="2026-06-30T21:41:16+02:00")
res = client.notifications.list_unread_notifications(
since="2026-06-30T21:41:16+02:00"
)
mock_get.assert_called_once()
_, kwargs = mock_get.call_args
assert kwargs.get("params") == {"all": "false", "since": "2026-06-30T21:41:16+02:00"}
assert kwargs.get("params") == {
"all": "false",
"since": "2026-06-30T21:41:16+02:00",
}
import pytest
def test_gitea_client_get_authenticated_user_failure() -> None:
client: GiteaClient = GiteaClient()
with patch("httpx.Client.get") as mock_get:
mock_get.side_effect = Exception("Connection error")
with pytest.raises(RuntimeError, match="Could not get authenticated user"):
client.get_authenticated_user()
client.repos.get_authenticated_user()
+60 -31
View File
@@ -3,19 +3,28 @@ from gitea.client import GiteaClient
from gitea.tools.file_tools import FileTools
def test_get_file_content_string_success() -> None:
def _create_mock_client() -> MagicMock:
"""Create a mock GiteaClient with sub-client attributes."""
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_file_content.return_value = "file content here"
mock_client.files = MagicMock()
return mock_client
def test_get_file_content_string_success() -> None:
mock_client = _create_mock_client()
mock_client.files.get_file_content.return_value = "file content here"
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.get_file_content("owner", "repo", "path/to/file")
assert res == "1: file content here"
mock_client.get_file_content.assert_called_once_with("owner", "repo", "path/to/file")
mock_client.files.get_file_content.assert_called_once_with(
"owner", "repo", "path/to/file"
)
def test_get_file_content_list_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_file_content.return_value = ["line1", "line2"]
mock_client = _create_mock_client()
mock_client.files.get_file_content.return_value = ["line1", "line2"]
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.get_file_content("owner", "repo", "path/to/file")
@@ -23,8 +32,8 @@ def test_get_file_content_list_success() -> None:
def test_get_file_content_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_file_content.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.files.get_file_content.side_effect = Exception("API Error")
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.get_file_content("owner", "repo", "path/to/file")
@@ -32,66 +41,86 @@ def test_get_file_content_failure() -> None:
def test_get_file_content_with_ref_string_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_file_content.return_value = "file content here"
mock_client = _create_mock_client()
mock_client.files.get_file_content.return_value = "file content here"
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.get_file_content_with_ref("owner", "repo", "path/to/file", "main")
res: str = file_tools.get_file_content_with_ref(
"owner", "repo", "path/to/file", "main"
)
assert res == "1: file content here"
mock_client.get_file_content.assert_called_once_with("owner", "repo", "path/to/file", "main")
mock_client.files.get_file_content.assert_called_once_with(
"owner", "repo", "path/to/file", "main"
)
def test_get_file_content_with_ref_list_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_file_content.return_value = ["line1", "line2"]
mock_client = _create_mock_client()
mock_client.files.get_file_content.return_value = ["line1", "line2"]
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.get_file_content_with_ref("owner", "repo", "path/to/file", "main")
res: str = file_tools.get_file_content_with_ref(
"owner", "repo", "path/to/file", "main"
)
assert res == "1: line1\n2: line2"
def test_get_file_content_with_ref_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_file_content.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.files.get_file_content.side_effect = Exception("API Error")
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.get_file_content_with_ref("owner", "repo", "path/to/file", "main")
res: str = file_tools.get_file_content_with_ref(
"owner", "repo", "path/to/file", "main"
)
assert "Error getting file content: API Error" in res
def test_commit_file_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.update_file.return_value = {}
mock_client = _create_mock_client()
mock_client.files.update_file.return_value = {}
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.commit_file("owner", "repo", "path/to/file", "msg", "content", "branch")
res: str = file_tools.commit_file(
"owner", "repo", "path/to/file", "msg", "content", "branch"
)
assert "committed successfully" in res
mock_client.update_file.assert_called_once_with("owner", "repo", "path/to/file", "msg", "content", "branch")
mock_client.files.update_file.assert_called_once_with(
"owner", "repo", "path/to/file", "msg", "content", "branch"
)
def test_commit_file_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.update_file.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.files.update_file.side_effect = Exception("API Error")
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.commit_file("owner", "repo", "path/to/file", "msg", "content", "branch")
res: str = file_tools.commit_file(
"owner", "repo", "path/to/file", "msg", "content", "branch"
)
assert "Error committing file: API Error" in res
def test_update_file_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.update_file.return_value = {}
mock_client = _create_mock_client()
mock_client.files.update_file.return_value = {}
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.update_file("owner", "repo", "path/to/file", "msg", "content", "branch")
res: str = file_tools.update_file(
"owner", "repo", "path/to/file", "msg", "content", "branch"
)
assert "updated in" in res
mock_client.update_file.assert_called_once_with("owner", "repo", "path/to/file", "msg", "content", "branch")
mock_client.files.update_file.assert_called_once_with(
"owner", "repo", "path/to/file", "msg", "content", "branch"
)
def test_update_file_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.update_file.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.files.update_file.side_effect = Exception("API Error")
file_tools: FileTools = FileTools(mock_client)
res: str = file_tools.update_file("owner", "repo", "path/to/file", "msg", "content", "branch")
res: str = file_tools.update_file(
"owner", "repo", "path/to/file", "msg", "content", "branch"
)
assert "Error updating file: API Error" in res
+12 -5
View File
@@ -3,19 +3,26 @@ from gitea.client import GiteaClient
from gitea.tools.git_tools import GitTools
def test_create_branch_success() -> None:
def _create_mock_client() -> MagicMock:
"""Create a mock GiteaClient with sub-client attributes."""
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.create_ref.return_value = {}
mock_client.files = MagicMock()
return mock_client
def test_create_branch_success() -> None:
mock_client = _create_mock_client()
mock_client.files.create_ref.return_value = {}
git_tools: GitTools = GitTools(mock_client)
res: str = git_tools.create_branch("owner", "repo", "ref", "sha")
assert res == "Branch 'ref' created successfully in owner/repo."
mock_client.create_ref.assert_called_once_with("owner", "repo", "ref", "sha")
mock_client.files.create_ref.assert_called_once_with("owner", "repo", "ref", "sha")
def test_create_branch_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.create_ref.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.files.create_ref.side_effect = Exception("API Error")
git_tools: GitTools = GitTools(mock_client)
res: str = git_tools.create_branch("owner", "repo", "ref", "sha")
+48 -40
View File
@@ -6,10 +6,18 @@ from gitea.models import IssueModel, CommentModel, LabelModel, RepositoryModel
from gitea.tools.issue_tools import IssueTools
def test_get_issue_success() -> None:
def _create_mock_client() -> MagicMock:
"""Create a mock GiteaClient with sub-client attributes."""
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.issues = MagicMock()
mock_client.repos = MagicMock()
return mock_client
def test_get_issue_success() -> None:
mock_client = _create_mock_client()
issue: IssueModel = IssueModel(number=1, title="Test Issue", state="open")
mock_client.get_issue.return_value = issue
mock_client.issues.get_issue.return_value = issue
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.get_issue("owner", "repo", 1)
@@ -17,12 +25,12 @@ def test_get_issue_success() -> None:
data: dict[str, Any] = json.loads(res)
assert data["number"] == 1
assert data["title"] == "Test Issue"
mock_client.get_issue.assert_called_once_with("owner", "repo", 1)
mock_client.issues.get_issue.assert_called_once_with("owner", "repo", 1)
def test_get_issue_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_issue.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.get_issue.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.get_issue("owner", "repo", 1)
@@ -30,18 +38,18 @@ def test_get_issue_failure() -> None:
def test_close_issue_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.close_issue.return_value = IssueModel(number=1, state="closed")
mock_client = _create_mock_client()
mock_client.issues.close_issue.return_value = IssueModel(number=1, state="closed")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.close_issue("owner", "repo", 1)
assert res == "Issue #1 closed successfully."
mock_client.close_issue.assert_called_once_with("owner", "repo", 1)
mock_client.issues.close_issue.assert_called_once_with("owner", "repo", 1)
def test_close_issue_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.close_issue.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.close_issue.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.close_issue("owner", "repo", 1)
@@ -49,9 +57,9 @@ def test_close_issue_failure() -> None:
def test_get_issue_comments_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
comment: CommentModel = CommentModel(id=123, body="Comment body")
mock_client.get_issue_comments.return_value = [comment]
mock_client.issues.get_issue_comments.return_value = [comment]
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.get_issue_comments("owner", "repo", 1)
@@ -61,8 +69,8 @@ def test_get_issue_comments_success() -> None:
def test_get_issue_comments_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_issue_comments.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.get_issue_comments.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.get_issue_comments("owner", "repo", 1)
@@ -70,23 +78,23 @@ def test_get_issue_comments_failure() -> None:
def test_list_assigned_issues_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
repo: RepositoryModel = RepositoryModel(name="repo1", owner="owner1")
issue: IssueModel = IssueModel(number=1, title="Test Issue")
mock_client.list_all_user_repos.return_value = [repo]
mock_client.list_assigned_issues.return_value = [issue]
mock_client.repos.list_all_user_repos.return_value = [repo]
mock_client.issues.list_assigned_issues.return_value = [issue]
issue_tools: IssueTools = IssueTools(mock_client)
res: list[dict[str, Any]] = issue_tools.list_assigned_issues()
assert len(res) == 1
assert res[0]["number"] == 1
mock_client.list_all_user_repos.assert_called_once()
mock_client.list_assigned_issues.assert_called_once_with("owner1", "repo1")
mock_client.repos.list_all_user_repos.assert_called_once()
mock_client.issues.list_assigned_issues.assert_called_once_with("owner1", "repo1")
def test_list_assigned_issues_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.list_all_user_repos.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.repos.list_all_user_repos.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: list[dict[str, Any]] = issue_tools.list_assigned_issues()
@@ -94,9 +102,9 @@ def test_list_assigned_issues_failure() -> None:
def test_list_issues_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
issue: IssueModel = IssueModel(number=1, title="Test Issue")
mock_client.list_repo_issues.return_value = [issue]
mock_client.issues.list_repo_issues.return_value = [issue]
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.list_issues("owner", "repo")
@@ -104,8 +112,8 @@ def test_list_issues_success() -> None:
def test_list_issues_empty() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.list_repo_issues.return_value = []
mock_client = _create_mock_client()
mock_client.issues.list_repo_issues.return_value = []
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.list_issues("owner", "repo")
@@ -113,8 +121,8 @@ def test_list_issues_empty() -> None:
def test_list_issues_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.list_repo_issues.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.list_repo_issues.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.list_issues("owner", "repo")
@@ -122,23 +130,23 @@ def test_list_issues_failure() -> None:
def test_create_issue_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
issue: IssueModel = IssueModel(number=2)
mock_client.create_issue.return_value = issue
mock_client.issues.create_issue.return_value = issue
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.create_issue(
"owner", "repo", "Title", "Body", ["label1"], ["assignee1"]
)
assert res == "Issue #2 created successfully in owner/repo."
mock_client.create_issue.assert_called_once_with(
mock_client.issues.create_issue.assert_called_once_with(
"owner", "repo", "Title", "Body", ["label1"], ["assignee1"]
)
def test_create_issue_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.create_issue.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.create_issue.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.create_issue("owner", "repo", "Title", "Body")
@@ -146,8 +154,8 @@ def test_create_issue_failure() -> None:
def test_add_label_to_issue_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.add_label.return_value = LabelModel(name="bug")
mock_client = _create_mock_client()
mock_client.issues.add_label.return_value = LabelModel(name="bug")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.add_label_to_issue("owner", "repo", 1, "bug")
@@ -155,8 +163,8 @@ def test_add_label_to_issue_success() -> None:
def test_add_label_to_issue_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.add_label.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.add_label.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.add_label_to_issue("owner", "repo", 1, "bug")
@@ -164,8 +172,8 @@ def test_add_label_to_issue_failure() -> None:
def test_add_comment_to_issue_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.add_comment.return_value = CommentModel(id=1)
mock_client = _create_mock_client()
mock_client.issues.add_comment.return_value = CommentModel(id=1)
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.add_comment_to_issue("owner", "repo", 1, "body")
@@ -173,8 +181,8 @@ def test_add_comment_to_issue_success() -> None:
def test_add_comment_to_issue_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.add_comment.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.issues.add_comment.side_effect = Exception("API Error")
issue_tools: IssueTools = IssueTools(mock_client)
res: str = issue_tools.add_comment_to_issue("owner", "repo", 1, "body")
+69 -53
View File
@@ -6,10 +6,18 @@ from gitea.models import PullRequestModel, CommentModel, RepositoryModel
from gitea.tools.pr_tools import PRTools
def test_get_pull_request_success() -> None:
def _create_mock_client() -> MagicMock:
"""Create a mock GiteaClient with sub-client attributes."""
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.prs = MagicMock()
mock_client.repos = MagicMock()
return mock_client
def test_get_pull_request_success() -> None:
mock_client = _create_mock_client()
pr: PullRequestModel = PullRequestModel(number=1, title="Test PR", state="open")
mock_client.get_pull_request.return_value = pr
mock_client.prs.get_pull_request.return_value = pr
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request("owner", "repo", 1)
@@ -17,12 +25,12 @@ def test_get_pull_request_success() -> None:
data: dict[str, Any] = json.loads(res)
assert data["number"] == 1
assert data["title"] == "Test PR"
mock_client.get_pull_request.assert_called_once_with("owner", "repo", 1)
mock_client.prs.get_pull_request.assert_called_once_with("owner", "repo", 1)
def test_get_pull_request_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_pull_request.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.get_pull_request.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request("owner", "repo", 1)
@@ -30,18 +38,20 @@ def test_get_pull_request_failure() -> None:
def test_close_pull_request_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.close_pull_request.return_value = PullRequestModel(number=1, state="closed")
mock_client = _create_mock_client()
mock_client.prs.close_pull_request.return_value = PullRequestModel(
number=1, state="closed"
)
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.close_pull_request("owner", "repo", 1)
assert res == "Pull request #1 closed successfully."
mock_client.close_pull_request.assert_called_once_with("owner", "repo", 1)
mock_client.prs.close_pull_request.assert_called_once_with("owner", "repo", 1)
def test_close_pull_request_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.close_pull_request.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.close_pull_request.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.close_pull_request("owner", "repo", 1)
@@ -49,9 +59,9 @@ def test_close_pull_request_failure() -> None:
def test_get_pull_request_comments_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
comment: CommentModel = CommentModel(id=123, body="Comment body")
mock_client.get_pull_request_comments.return_value = [comment]
mock_client.prs.get_pull_request_comments.return_value = [comment]
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request_comments("owner", "repo", 1)
@@ -61,8 +71,8 @@ def test_get_pull_request_comments_success() -> None:
def test_get_pull_request_comments_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_pull_request_comments.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.get_pull_request_comments.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request_comments("owner", "repo", 1)
@@ -70,23 +80,25 @@ def test_get_pull_request_comments_failure() -> None:
def test_list_assigned_pull_requests_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
repo: RepositoryModel = RepositoryModel(name="repo1", owner="owner1")
pr: PullRequestModel = PullRequestModel(number=1, title="Test PR")
mock_client.list_all_user_repos.return_value = [repo]
mock_client.list_assigned_pull_requests.return_value = [pr]
mock_client.repos.list_all_user_repos.return_value = [repo]
mock_client.prs.list_assigned_pull_requests.return_value = [pr]
pr_tools: PRTools = PRTools(mock_client)
res: list[dict[str, Any]] = pr_tools.list_assigned_pull_requests()
assert len(res) == 1
assert res[0]["number"] == 1
mock_client.list_all_user_repos.assert_called_once()
mock_client.list_assigned_pull_requests.assert_called_once_with("owner1", "repo1")
mock_client.repos.list_all_user_repos.assert_called_once()
mock_client.prs.list_assigned_pull_requests.assert_called_once_with(
"owner1", "repo1"
)
def test_list_assigned_pull_requests_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.list_all_user_repos.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.repos.list_all_user_repos.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: list[dict[str, Any]] = pr_tools.list_assigned_pull_requests()
@@ -94,9 +106,9 @@ def test_list_assigned_pull_requests_failure() -> None:
def test_list_pull_requests_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
pr: PullRequestModel = PullRequestModel(number=1, title="Test PR")
mock_client.list_repo_pull_requests.return_value = [pr]
mock_client.prs.list_repo_pull_requests.return_value = [pr]
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.list_pull_requests("owner", "repo")
@@ -104,8 +116,8 @@ def test_list_pull_requests_success() -> None:
def test_list_pull_requests_empty() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.list_repo_pull_requests.return_value = []
mock_client = _create_mock_client()
mock_client.prs.list_repo_pull_requests.return_value = []
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.list_pull_requests("owner", "repo")
@@ -113,8 +125,8 @@ def test_list_pull_requests_empty() -> None:
def test_list_pull_requests_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.list_repo_pull_requests.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.list_repo_pull_requests.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.list_pull_requests("owner", "repo")
@@ -122,20 +134,24 @@ def test_list_pull_requests_failure() -> None:
def test_create_pull_request_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client = _create_mock_client()
pr: PullRequestModel = PullRequestModel(number=2, title="Title")
mock_client.create_pr_via_tea.return_value = pr
mock_client.prs.create_pr_via_tea.return_value = pr
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.create_pull_request("owner", "repo", "head", "base", "Title", "Desc")
res: str = pr_tools.create_pull_request(
"owner", "repo", "head", "base", "Title", "Desc"
)
data: dict[str, Any] = json.loads(res)
assert data["number"] == 2
mock_client.create_pr_via_tea.assert_called_once_with("owner", "repo", "Title", "Desc", "head", "base")
mock_client.prs.create_pr_via_tea.assert_called_once_with(
"owner", "repo", "Title", "Desc", "head", "base"
)
def test_create_pull_request_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.create_pr_via_tea.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.create_pr_via_tea.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.create_pull_request("owner", "repo", "head", "base", "Title")
@@ -143,8 +159,8 @@ def test_create_pull_request_failure() -> None:
def test_add_label_to_pr_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.add_label_pr.return_value = {}
mock_client = _create_mock_client()
mock_client.prs.add_label_pr.return_value = {}
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.add_label_to_pr("owner", "repo", 1, "bug")
@@ -152,8 +168,8 @@ def test_add_label_to_pr_success() -> None:
def test_add_label_to_pr_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.add_label_pr.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.add_label_pr.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.add_label_to_pr("owner", "repo", 1, "bug")
@@ -161,8 +177,8 @@ def test_add_label_to_pr_failure() -> None:
def test_get_pull_request_diff_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_pull_request_diff.return_value = "diff content"
mock_client = _create_mock_client()
mock_client.prs.get_pull_request_diff.return_value = "diff content"
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request_diff("owner", "repo", 1)
@@ -170,8 +186,8 @@ def test_get_pull_request_diff_success() -> None:
def test_get_pull_request_diff_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_pull_request_diff.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.get_pull_request_diff.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request_diff("owner", "repo", 1)
@@ -179,8 +195,8 @@ def test_get_pull_request_diff_failure() -> None:
def test_get_pull_request_patch_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_pull_request_patch.return_value = "patch content"
mock_client = _create_mock_client()
mock_client.prs.get_pull_request_patch.return_value = "patch content"
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request_patch("owner", "repo", 1)
@@ -188,8 +204,8 @@ def test_get_pull_request_patch_success() -> None:
def test_get_pull_request_patch_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.get_pull_request_patch.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.get_pull_request_patch.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.get_pull_request_patch("owner", "repo", 1)
@@ -197,8 +213,8 @@ def test_get_pull_request_patch_failure() -> None:
def test_approve_pull_request_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.approve_pr.return_value = {}
mock_client = _create_mock_client()
mock_client.prs.approve_pr.return_value = {}
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.approve_pull_request("owner", "repo", 1, "good")
@@ -206,8 +222,8 @@ def test_approve_pull_request_success() -> None:
def test_approve_pull_request_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.approve_pr.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.approve_pr.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.approve_pull_request("owner", "repo", 1, "good")
@@ -215,8 +231,8 @@ def test_approve_pull_request_failure() -> None:
def test_request_changes_success() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.request_changes_pr.return_value = {}
mock_client = _create_mock_client()
mock_client.prs.request_changes_pr.return_value = {}
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.request_changes("owner", "repo", 1, "bad")
@@ -224,8 +240,8 @@ def test_request_changes_success() -> None:
def test_request_changes_failure() -> None:
mock_client: MagicMock = MagicMock(spec=GiteaClient)
mock_client.request_changes_pr.side_effect = Exception("API Error")
mock_client = _create_mock_client()
mock_client.prs.request_changes_pr.side_effect = Exception("API Error")
pr_tools: PRTools = PRTools(mock_client)
res: str = pr_tools.request_changes("owner", "repo", 1, "bad")
+30 -25
View File
@@ -9,25 +9,25 @@ from gitea.workspace import WorkspaceManager
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_configure_repo_user(
mock_client_class: MagicMock,
mock_run: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.repos = MagicMock()
mock_user = MagicMock()
mock_user.full_name = "Agent Tester"
mock_user.login = "agent-test"
mock_user.email = "agent-test@example.com"
mock_client.get_authenticated_user.return_value = mock_user
mock_client.repos.get_authenticated_user.return_value = mock_user
workspace = WorkspaceManager()
repo_path = Path("/tmp/mock-repo")
workspace._configure_repo_user(repo_path)
assert mock_run.call_count >= 3
calls = [c[0][0] for c in mock_run.call_args_list]
assert any("http.extraHeader" in call for call in calls)
assert any("user.name" in call for call in calls)
assert any("user.email" in call for call in calls)
@@ -36,27 +36,27 @@ def test_workspace_manager_configure_repo_user(
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_clone_repo(
mock_client_class: MagicMock,
mock_run: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.repos = MagicMock()
mock_user = MagicMock()
mock_user.full_name = "Agent Tester"
mock_user.login = "agent-test"
mock_user.email = "agent-test@example.com"
mock_client.get_authenticated_user.return_value = mock_user
mock_client.repos.get_authenticated_user.return_value = mock_user
workspace = WorkspaceManager()
with patch.object(workspace, "_configure_repo_user") as mock_configure:
with patch.object(workspace, "get_repo_path") as mock_get_path:
mock_repo_path = MagicMock(spec=Path)
mock_repo_path.exists.return_value = False
mock_get_path.return_value = mock_repo_path
workspace.clone_repo("meeks/repo1")
mock_run.assert_called_once()
args = mock_run.call_args[0][0]
assert "clone" in args
@@ -64,13 +64,15 @@ def test_workspace_manager_clone_repo(
mock_configure.assert_called_once_with(mock_repo_path)
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_fails_if_no_authenticated_user(
mock_client_class: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.get_authenticated_user.return_value = None
mock_client.repos = MagicMock()
mock_client.repos.get_authenticated_user.return_value = None
workspace = WorkspaceManager()
with pytest.raises(RuntimeError, match="No authenticated user found."):
@@ -80,15 +82,17 @@ def test_workspace_manager_fails_if_no_authenticated_user(
workspace._configure_repo_user(Path("/tmp/mock-repo"))
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_fails_if_authenticated_user_has_no_login(
mock_client_class: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.repos = MagicMock()
mock_user = MagicMock()
mock_user.login = ""
mock_client.get_authenticated_user.return_value = mock_user
mock_client.repos.get_authenticated_user.return_value = mock_user
workspace = WorkspaceManager()
with pytest.raises(RuntimeError, match="No authenticated user found."):
@@ -101,17 +105,17 @@ def test_workspace_manager_fails_if_authenticated_user_has_no_login(
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_sanitize_repo_no_changes(
mock_client_class: MagicMock,
mock_run: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
# Setup Gitea client mock
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.repos = MagicMock()
mock_user = MagicMock()
mock_user.full_name = "Agent Tester"
mock_user.login = "agent-test"
mock_user.email = "agent-test@example.com"
mock_client.get_authenticated_user.return_value = mock_user
mock_client.repos.get_authenticated_user.return_value = mock_user
# Mock subprocess.run for status check and others
def mock_run_side_effect(args: list[str], **kwargs: Any) -> MagicMock:
@@ -144,17 +148,17 @@ def test_workspace_manager_sanitize_repo_no_changes(
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_sanitize_repo_with_changes(
mock_client_class: MagicMock,
mock_run: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
# Setup Gitea client mock
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.repos = MagicMock()
mock_user = MagicMock()
mock_user.full_name = "Agent Tester"
mock_user.login = "agent-test"
mock_user.email = "agent-test@example.com"
mock_client.get_authenticated_user.return_value = mock_user
mock_client.repos.get_authenticated_user.return_value = mock_user
# Mock subprocess.run to show modified files
def mock_run_side_effect(args: list[str], **kwargs: Any) -> MagicMock:
@@ -183,20 +187,21 @@ def test_workspace_manager_sanitize_repo_with_changes(
@patch("gitea.workspace.subprocess.run")
@patch("gitea.workspace.GiteaClient")
def test_workspace_manager_sanitize_repo_fails(
mock_client_class: MagicMock,
mock_run: MagicMock
mock_client_class: MagicMock, mock_run: MagicMock
) -> None:
# Setup Gitea client mock
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.repos = MagicMock()
mock_user = MagicMock()
mock_user.full_name = "Agent Tester"
mock_user.login = "agent-test"
mock_user.email = "agent-test@example.com"
mock_client.get_authenticated_user.return_value = mock_user
mock_client.repos.get_authenticated_user.return_value = mock_user
# Mock remote set-url to fail
import subprocess
mock_run.side_effect = subprocess.CalledProcessError(1, "git remote set-url")
workspace = WorkspaceManager()