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.
71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
"""Tests for structured logging helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import logging
|
|
|
|
import pytest
|
|
|
|
from aegis_gitea_mcp.logging_utils import (
|
|
JsonLogFormatter,
|
|
log_event,
|
|
log_nullable_field,
|
|
sanitize_context,
|
|
)
|
|
|
|
|
|
def test_sanitize_context_masks_sensitive_keys() -> None:
|
|
"""Sensitive keys are masked case-insensitively; others pass through."""
|
|
cleaned = sanitize_context(
|
|
{"owner": "acme", "Token": "abc", "password": "x", "issue_number": 7}
|
|
)
|
|
|
|
assert cleaned["owner"] == "acme"
|
|
assert cleaned["issue_number"] == 7
|
|
assert cleaned["Token"] == "***"
|
|
assert cleaned["password"] == "***"
|
|
|
|
|
|
def test_json_formatter_includes_context() -> None:
|
|
"""The formatter serializes a record's context mapping into the payload."""
|
|
record = logging.LogRecord(
|
|
"test", logging.DEBUG, __file__, 1, "get_issue.field_check", None, None
|
|
)
|
|
record.context = {"field": "labels", "is_none": True}
|
|
|
|
payload = json.loads(JsonLogFormatter().format(record))
|
|
|
|
assert payload["message"] == "get_issue.field_check"
|
|
assert payload["context"] == {"field": "labels", "is_none": True}
|
|
|
|
|
|
def test_log_event_emits_sanitized_context(caplog: pytest.LogCaptureFixture) -> None:
|
|
"""log_event records the event name and masks sensitive context values."""
|
|
logger = logging.getLogger("test.log_event")
|
|
with caplog.at_level(logging.DEBUG, logger="test.log_event"):
|
|
log_event(logger, logging.DEBUG, "evt", owner="acme", token="secret")
|
|
|
|
record = caplog.records[-1]
|
|
assert record.getMessage() == "evt"
|
|
assert record.context == {"owner": "acme", "token": "***"}
|
|
|
|
|
|
def test_log_nullable_field_characterizes_value(caplog: pytest.LogCaptureFixture) -> None:
|
|
"""log_nullable_field reports None-ness and runtime type without dumping data."""
|
|
logger = logging.getLogger("test.nullable")
|
|
with caplog.at_level(logging.DEBUG, logger="test.nullable"):
|
|
log_nullable_field(logger, "evt", "labels", None)
|
|
log_nullable_field(logger, "evt", "labels", [1, 2])
|
|
|
|
assert caplog.records[0].context == {
|
|
"field": "labels",
|
|
"is_none": True,
|
|
"value_type": None,
|
|
}
|
|
assert caplog.records[1].context == {
|
|
"field": "labels",
|
|
"is_none": False,
|
|
"value_type": "list",
|
|
}
|