"""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", }