homelab-codex-ws/services/agent-system/telegram-bot/tests/test_format.py

117 lines
4 KiB
Python
Raw Permalink Normal View History

"""Tests for _format_pending_action — no Telegram connection required.
telegram stubs are set up in conftest.py before this module is imported.
"""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).parent.parent))
from bot import _format_pending_action
# ---------------------------------------------------------------------------
# Bug 1 — risk_level field
# ---------------------------------------------------------------------------
def test_risk_level_shown_when_present():
data = {
"type": "container_restart", "service": "homeassistant",
"node": "chelsty-ha", "risk_level": "low",
}
msg = _format_pending_action("container-restart-chelsty-ha-homeassistant", data)
assert "Risk: *low*" in msg
assert "unknown" not in msg
def test_risk_falls_back_to_legacy_risk_key():
data = {
"type": "redeploy", "service": "mosquitto",
"node": "chelsty-infra", "risk": "guarded",
}
msg = _format_pending_action("redeploy-chelsty-infra-mosquitto", data)
assert "Risk: *guarded*" in msg
def test_risk_unknown_when_both_absent():
data = {"type": "redeploy", "service": "foo", "node": "bar"}
msg = _format_pending_action("redeploy-bar-foo", data)
assert "Risk: *unknown*" in msg
# ---------------------------------------------------------------------------
# Bug 2 — description field
# ---------------------------------------------------------------------------
def test_description_shown_for_alert_only():
data = {
"type": "alert_only", "service": "homeassistant",
"node": "chelsty-ha", "risk_level": "info",
"description": "3 entities unavailable for >1h",
}
msg = _format_pending_action("alert-ha-entity-unavailable-chelsty-ha", data)
assert "3 entities unavailable for >1h" in msg
assert "Description:" in msg
def test_description_shown_for_container_restart():
data = {
"type": "container_restart", "service": "homeassistant",
"node": "chelsty-ha", "risk_level": "low",
"description": "Restart 'homeassistant' on chelsty-ha: HA WebSocket unresponsive",
}
msg = _format_pending_action("container-restart-chelsty-ha-homeassistant", data)
assert "HA WebSocket unresponsive" in msg
def test_description_absent_no_crash():
data = {"type": "redeploy", "service": "foo", "node": "bar", "risk_level": "guarded"}
msg = _format_pending_action("redeploy-bar-foo", data)
assert "Description:" not in msg
assert "Risk: *guarded*" in msg
def test_description_truncated_at_300_chars():
long_desc = "x" * 400
data = {
"type": "alert_only", "service": "homeassistant",
"node": "chelsty-ha", "risk_level": "info",
"description": long_desc,
}
msg = _format_pending_action("alert-ha-foo-chelsty-ha", data)
assert "x" * 300 in msg
assert "..." in msg
assert "x" * 301 not in msg
# ---------------------------------------------------------------------------
# Combined — real HA alert_only action shape
# ---------------------------------------------------------------------------
def test_ha_alert_only_full_action():
"""Mirrors an actual alert_only action written by supervisor._generate_ha_alert_only."""
data = {
"action_id": "alert-ha-entity-unavailable-chelsty-ha",
"type": "alert_only",
"node": "chelsty-ha",
"service": "homeassistant",
"risk_level": "info",
"confidence": 1.0,
"description": "3 entities unavailable for >1h: sensor.power, binary_sensor.window",
"status": "pending",
"payload": {
"location_tag": "chelsty",
"reason": "ha_entity_unavailable_long",
"count": 3,
},
}
msg = _format_pending_action(data["action_id"], data)
assert "alert_only" in msg
assert "chelsty-ha" in msg
assert "Risk: *info*" in msg
assert "3 entities unavailable" in msg
assert "unknown" not in msg