117 lines
4 KiB
Python
117 lines
4 KiB
Python
|
|
"""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
|