"""Regression checks for the 3 hermes reviewer findings. No broker, no TV. Run: python3 tests/test_bridge.py""" import subprocess from pathlib import Path from types import SimpleNamespace import paho.mqtt.client as mqtt SRC = Path(__file__).resolve().parents[1] / "lgtv_mqtt.py" def load(run): ns = {"__name__": "test"} exec(compile(SRC.read_text(), str(SRC), "exec"), ns) ns["run"] = run ns["time"] = SimpleNamespace(sleep=lambda _: None) return ns def command(ns, payload): sent = [] client = SimpleNamespace(publish=lambda topic, p, retain=False: sent.append(p)) ns["handle_command"](client, SimpleNamespace(payload=payload)) return sent # failed-power-commands-publish-success-state: on/off fail, TV really still ON ns = load(lambda cmd, **k: ("TV: ON", 0) if cmd.endswith("status") else ("", 1)) assert command(ns, b"OFF") == ["ON"], "failed OFF must not report OFF" ns = load(lambda cmd, **k: ("TV: OFF", 0) if cmd.endswith("status") else ("", 1)) assert command(ns, b"ON") == ["OFF"], "failed ON must not report ON" ns = load(lambda cmd, **k: ("", 0)) assert command(ns, b"ON") == ["ON"] and command(ns, b"OFF") == ["OFF"] # uncaught-helper-timeout-stops-bridge: real run(), helper that outlives timeout ns = {"__name__": "test"} exec(compile(SRC.read_text(), str(SRC), "exec"), ns) assert ns["run"]("sleep 5", timeout=0.2) == ("timeout", 124) ns["LGTV_SCRIPT"] = "sleep 5;" ns["run"].__defaults__ = (0.2,) assert ns["get_tv_state"]() == "OFF" # malformed-mqtt-payload-kills-network-loop: real paho dispatch survives ns = load(lambda cmd, **k: ("", 0)) client = mqtt.Client(client_id="test-no-network") client.on_message = ns["on_message"] msg = mqtt.MQTTMessage() msg.topic = b"lgtv/switch/command" msg.payload = b"\xff" client._handle_on_message(msg) ns["worker"].shutdown(wait=True) assert command(ns, b"\xff") == [] # decoded, logged as unknown, ignored print("ok")