test: cover write-tool auth and backend error branches
lint / lint (push) Successful in 36s
docker / test (pull_request) Successful in 32s
test / test (push) Successful in 38s
docker / lint (pull_request) Successful in 38s
docker / docker-test (pull_request) Successful in 12s
docker / docker-publish (pull_request) Has been skipped
test / test (pull_request) Successful in 25s
lint / lint (pull_request) Successful in 27s

Every write tool's `except (Auth...)` re-raise and `except GiteaError ->
RuntimeError` wrapping was previously untested, leaving write_tools at 60%
coverage and the repo below the 80% gate. Adds parametrized error-path tests
for all 15 write tools (backend error wrapping + auth propagation), raising
write_tools coverage to 99% and total coverage above the gate.
This commit is contained in:
2026-06-22 15:58:59 +02:00
parent f53e1a3a5a
commit 538d6d964a
+60 -1
View File
@@ -3,7 +3,7 @@
import pytest
from aegis_gitea_mcp.config import reset_settings
from aegis_gitea_mcp.gitea_client import GiteaError
from aegis_gitea_mcp.gitea_client import GiteaAuthenticationError, GiteaError
from aegis_gitea_mcp.tools.read_tools import (
compare_refs_tool,
get_branch_tool,
@@ -402,3 +402,62 @@ def test_create_label_args_reject_invalid_color() -> None:
with pytest.raises(pydantic.ValidationError):
CreateLabelArgs(owner="o", repo="r", name="bug", color="red")
# (tool, valid_args) for every write tool, used to exercise error branches.
WRITE_TOOL_ERROR_CASES = [
(create_issue_tool, {"owner": "acme", "repo": "app", "title": "Issue"}),
(update_issue_tool, {"owner": "acme", "repo": "app", "issue_number": 1, "title": "x"}),
(create_issue_comment_tool, {"owner": "acme", "repo": "app", "issue_number": 1, "body": "c"}),
(create_pr_comment_tool, {"owner": "acme", "repo": "app", "pull_number": 1, "body": "c"}),
(add_labels_tool, {"owner": "acme", "repo": "app", "issue_number": 1, "labels": ["bug"]}),
(assign_issue_tool, {"owner": "acme", "repo": "app", "issue_number": 1, "assignees": ["al"]}),
(create_label_tool, {"owner": "acme", "repo": "app", "name": "bug", "color": "#ff0000"}),
(update_label_tool, {"owner": "acme", "repo": "app", "name": "bug", "new_name": "defect"}),
(remove_labels_tool, {"owner": "acme", "repo": "app", "issue_number": 1, "labels": ["bug"]}),
(
create_pull_request_tool,
{"owner": "acme", "repo": "app", "title": "PR", "head": "feature", "base": "main"},
),
(create_release_tool, {"owner": "acme", "repo": "app", "tag_name": "v1.0.0"}),
(edit_release_tool, {"owner": "acme", "repo": "app", "release_id": 3, "name": "x"}),
(create_branch_tool, {"owner": "acme", "repo": "app", "new_branch_name": "feature/x"}),
(create_milestone_tool, {"owner": "acme", "repo": "app", "title": "M1"}),
(edit_issue_comment_tool, {"owner": "acme", "repo": "app", "comment_id": 5, "body": "e"}),
]
class _WriteBackendErrorGitea:
"""Stub whose every method raises a generic Gitea backend error."""
def __getattr__(self, name: str):
async def _raise(*args: object, **kwargs: object) -> object:
raise GiteaError("backend failure")
return _raise
class _WriteAuthErrorGitea:
"""Stub whose every method raises an authentication error."""
def __getattr__(self, name: str):
async def _raise(*args: object, **kwargs: object) -> object:
raise GiteaAuthenticationError("token expired")
return _raise
@pytest.mark.asyncio
@pytest.mark.parametrize("tool,args", WRITE_TOOL_ERROR_CASES)
async def test_write_tools_wrap_backend_errors(tool, args) -> None:
"""Every write tool wraps a backend GiteaError as a RuntimeError."""
with pytest.raises(RuntimeError):
await tool(_WriteBackendErrorGitea(), args)
@pytest.mark.asyncio
@pytest.mark.parametrize("tool,args", WRITE_TOOL_ERROR_CASES)
async def test_write_tools_propagate_auth_errors(tool, args) -> None:
"""Every write tool lets auth failures surface for re-authorization."""
with pytest.raises(GiteaAuthenticationError):
await tool(_WriteAuthErrorGitea(), args)