test: write failure paths, expired OAuth token, non-admin admin-tool refusals and webhook credential leak checks
This commit is contained in:
1 parent
84fa29e380
commit
d1b9a4845e
3 files changed
+139
-7
No files matched your search
@@ -0,0 +1,79 @@
|
||||
"""Write tools that Gitea refuses: the status and error kind reach the client intact."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
|
||||
from tests.integration.conftest import McpSession, RepoRef, b64
|
||||
from tests.integration.harness import GiteaInstance
|
||||
|
||||
|
||||
async def test_creating_in_a_missing_repository_is_not_found(
|
||||
mcp: McpSession, gitea: GiteaInstance
|
||||
) -> None:
|
||||
missing = {"owner": gitea.admin_login, "repo": "missing-" + secrets.token_hex(4)}
|
||||
issue = await mcp.fail("gitea_issue_create_issue", 404, body={"title": "x"}, **missing)
|
||||
assert issue.error_kind == "not_found"
|
||||
label = await mcp.fail(
|
||||
"gitea_issue_create_label", 404, body={"name": "x", "color": "#ffffff"}, **missing
|
||||
)
|
||||
assert label.error_kind == "not_found"
|
||||
# The audit log records the failure with the same kind.
|
||||
failed = [e for e in mcp.audit_entries() if e["tool_name"] == "gitea_issue_create_issue"]
|
||||
assert failed and failed[-1]["outcome"] == "not_found"
|
||||
assert failed[-1]["result_status"] == "error"
|
||||
|
||||
|
||||
async def test_invalid_values_are_validation_errors(mcp: McpSession, fresh_repo: RepoRef) -> None:
|
||||
repo = fresh_repo.args
|
||||
bad_color = await mcp.call(
|
||||
"gitea_issue_create_label", body={"name": "bad", "color": "not-a-color"}, **repo
|
||||
)
|
||||
assert bad_color.is_error
|
||||
assert bad_color.error_kind in ("validation_failed", "bad_request")
|
||||
assert bad_color.status in (400, 422)
|
||||
|
||||
# Gitea itself refuses a missing body.
|
||||
missing_body = await mcp.call("gitea_issue_create_issue", **repo)
|
||||
assert missing_body.is_error and missing_body.status == 422
|
||||
assert missing_body.error_kind == "validation_failed"
|
||||
|
||||
# A field of the wrong type never reaches Gitea: the schema rejects it first.
|
||||
wrong_type = await mcp.call(
|
||||
"gitea_issue_create_issue", body={"title": ["not", "a", "string"]}, **repo
|
||||
)
|
||||
assert wrong_type.is_error and wrong_type.status is None
|
||||
assert wrong_type.error_kind == "invalid_argument"
|
||||
|
||||
|
||||
async def test_conflicting_writes_are_conflicts(
|
||||
mcp: McpSession, gitea: GiteaInstance, fresh_repo: RepoRef
|
||||
) -> None:
|
||||
repo = fresh_repo.args
|
||||
duplicate = await mcp.fail(
|
||||
"gitea_user_current_create_repo", 409, body={"name": fresh_repo.name}
|
||||
)
|
||||
assert duplicate.error_kind == "conflict"
|
||||
|
||||
await mcp.ok(
|
||||
"gitea_repo_create_file",
|
||||
status=201,
|
||||
filepath="a.txt",
|
||||
body={"content": b64("one"), "message": "one"},
|
||||
**repo,
|
||||
)
|
||||
again = await mcp.call(
|
||||
"gitea_repo_create_file",
|
||||
filepath="a.txt",
|
||||
body={"content": b64("two"), "message": "two"},
|
||||
**repo,
|
||||
)
|
||||
assert again.is_error and again.status in (409, 422)
|
||||
|
||||
stale = await mcp.call(
|
||||
"gitea_repo_update_file",
|
||||
filepath="a.txt",
|
||||
body={"content": b64("three"), "message": "three", "sha": "0" * 40},
|
||||
**repo,
|
||||
)
|
||||
assert stale.is_error and stale.status in (409, 422)
|
||||
Reference in new issue
Block a user