Adds the pydantic-settings Settings with validated GITEA_URL, OAuth scopes and toolsets, the argparse CLI skeleton, catalog.model, identity and GiteaAPIError. Test fixtures now isolate env, cwd and state paths in tmp.
74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
"""Tests for error types and message sanitization."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from aegis_gitea_mcp.errors import GiteaAPIError, ToolError, kind_for_status, sanitize_message
|
|
|
|
|
|
def test_tool_error_defaults() -> None:
|
|
error = ToolError("nope")
|
|
assert str(error) == "nope"
|
|
assert error.detail == "nope"
|
|
assert error.status_code == 400
|
|
assert ToolError("x", status_code=403).status_code == 403
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("status", "kind"),
|
|
[
|
|
(400, "bad_request"),
|
|
(401, "unauthorized"),
|
|
(403, "forbidden"),
|
|
(404, "not_found"),
|
|
(409, "conflict"),
|
|
(422, "validation_failed"),
|
|
(429, "rate_limited"),
|
|
(418, "client_error"),
|
|
(500, "server_error"),
|
|
(503, "server_error"),
|
|
(0, "error"),
|
|
],
|
|
)
|
|
def test_kind_for_status(status: int, kind: str) -> None:
|
|
assert kind_for_status(status) == kind
|
|
|
|
|
|
def test_gitea_api_error_fields() -> None:
|
|
error = GiteaAPIError(404, "repository does not exist")
|
|
|
|
assert isinstance(error, ToolError)
|
|
assert error.status == 404
|
|
assert error.status_code == 404
|
|
assert error.kind == "not_found"
|
|
assert error.message == "repository does not exist"
|
|
assert error.to_dict() == {
|
|
"status": 404,
|
|
"kind": "not_found",
|
|
"message": "repository does not exist",
|
|
}
|
|
|
|
|
|
def test_gitea_api_error_explicit_kind() -> None:
|
|
assert GiteaAPIError(0, "connection refused", kind="network_error").kind == "network_error"
|
|
|
|
|
|
def test_gitea_api_error_sanitizes_message() -> None:
|
|
error = GiteaAPIError(401, "bad header Authorization: Bearer abcdef1234567890abcdef\nretry")
|
|
|
|
assert "abcdef1234567890abcdef" not in error.message
|
|
assert "\n" not in error.message
|
|
assert error.detail == error.message
|
|
|
|
|
|
def test_sanitize_message_masks_secret_patterns() -> None:
|
|
message = sanitize_message("failed with key AKIA1234567890ABCDEF in body")
|
|
assert "AKIA1234567890ABCDEF" not in message
|
|
|
|
|
|
def test_sanitize_message_truncates() -> None:
|
|
message = sanitize_message("x" * 2000, max_chars=100)
|
|
assert len(message) == 100
|
|
assert message.endswith("...")
|