feat: new settings, CLI skeleton and interface skeletons
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.
This commit is contained in:
1 parent
4ac9626eb5
commit
b82e2866cb
24 files changed
+1512
-605
No files matched your search
@@ -1,4 +1,4 @@
|
||||
"""Tests for structured logging helpers and get_issue instrumentation (#14)."""
|
||||
"""Tests for structured logging helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -7,26 +7,12 @@ import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from aegis_gitea_mcp.config import reset_settings
|
||||
from aegis_gitea_mcp.logging_utils import (
|
||||
JsonLogFormatter,
|
||||
log_event,
|
||||
log_nullable_field,
|
||||
sanitize_context,
|
||||
)
|
||||
from aegis_gitea_mcp.tools.read_tools import get_issue_tool
|
||||
|
||||
READ_TOOLS_LOGGER = "aegis_gitea_mcp.tools.read_tools"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def tool_env(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""Provide minimal settings environment for response limit helpers."""
|
||||
reset_settings()
|
||||
monkeypatch.setenv("GITEA_URL", "https://gitea.example.com")
|
||||
monkeypatch.setenv("GITEA_TOKEN", "test-token")
|
||||
monkeypatch.setenv("MCP_API_KEYS", "a" * 64)
|
||||
monkeypatch.setenv("ENVIRONMENT", "test")
|
||||
|
||||
|
||||
def test_sanitize_context_masks_sensitive_keys() -> None:
|
||||
@@ -82,39 +68,3 @@ def test_log_nullable_field_characterizes_value(caplog: pytest.LogCaptureFixture
|
||||
"is_none": False,
|
||||
"value_type": "list",
|
||||
}
|
||||
|
||||
|
||||
class _NullIssueGitea:
|
||||
"""Minimal stub returning an issue with null collection fields."""
|
||||
|
||||
async def get_issue(self, owner: str, repo: str, index: int) -> dict[str, object]:
|
||||
return {
|
||||
"number": index,
|
||||
"title": "Issue",
|
||||
"body": "Body",
|
||||
"state": "open",
|
||||
"labels": None,
|
||||
"assignees": None,
|
||||
"user": None,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_issue_tool_emits_debug_events(caplog: pytest.LogCaptureFixture) -> None:
|
||||
"""get_issue_tool emits start/shape/field-check debug events and still parses."""
|
||||
with caplog.at_level(logging.DEBUG, logger=READ_TOOLS_LOGGER):
|
||||
result = await get_issue_tool(
|
||||
_NullIssueGitea(), {"owner": "acme", "repo": "app", "issue_number": 7}
|
||||
)
|
||||
|
||||
events = [r.getMessage() for r in caplog.records]
|
||||
assert "get_issue.start" in events
|
||||
assert "get_issue.payload_shape" in events
|
||||
|
||||
field_checks = [r.context for r in caplog.records if r.getMessage() == "get_issue.field_check"]
|
||||
assert {"field": "labels", "is_none": True, "value_type": None} in field_checks
|
||||
assert {"field": "user", "is_none": True, "value_type": None} in field_checks
|
||||
|
||||
# Logging must not change behaviour: null collections still parse to empties.
|
||||
assert result["labels"] == []
|
||||
assert result["assignees"] == []
|
||||
Reference in new issue
Block a user