"""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)