test(homeassistant): prevent unit tests from calling live instances

Two tests made real HTTP calls to homeassistant.local:8123 — on a LAN
with an actual Home Assistant instance they could turn on real lights,
and otherwise burned ~10s in network timeouts. Replace with AsyncMock at
_async_call_service and assert the exact production call signature
(domain, service, entity_id, data). 35 pass in ~0.2s.

Salvaged from PR #72634 by @jeeves-assistant.

Co-authored-by: Jeeves Assistant <jeevesassistant00@gmail.com>
This commit is contained in:
Jeeves Assistant 2026-07-29 20:19:28 -07:00 committed by Teknium
parent 9e9c220608
commit 080bb83746

View file

@ -5,7 +5,7 @@ handler validation, and availability gating.
"""
import json
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
import pytest
@ -141,16 +141,20 @@ class TestDomainBlocklist:
assert "error" in result
assert "blocked" in result["error"].lower()
def test_safe_domain_not_blocked(self):
"""Safe domains like 'light' should not be blocked (will fail on network, not blocklist)."""
# This will try to make a real HTTP call and fail, but the important thing
# is it does NOT return a "blocked" error
@patch("tools.homeassistant_tool._async_call_service", new_callable=AsyncMock)
def test_safe_domain_not_blocked(self, mock_call_service):
"""Safe domains like ``light`` reach the service-call layer."""
mock_call_service.return_value = {"success": True}
result = json.loads(_handle_call_service({
"domain": "light", "service": "turn_on", "entity_id": "light.test"
}))
# Should fail with a network/connection error, not a "blocked" error
if "error" in result:
assert "blocked" not in result["error"].lower()
assert result["result"]["success"] is True
mock_call_service.assert_awaited_once_with(
"light",
"turn_on",
"light.test",
None,
)
def test_blocked_domains_include_shell_command(self):
assert "shell_command" in _BLOCKED_DOMAINS
@ -179,14 +183,20 @@ class TestEntityIdValidation:
assert _ENTITY_ID_RE.match("../api/config") is None
def test_call_service_allows_no_entity_id(self):
@patch("tools.homeassistant_tool._async_call_service", new_callable=AsyncMock)
def test_call_service_allows_no_entity_id(self, mock_call_service):
"""Some services (like scene.turn_on) don't need entity_id."""
# Will fail on network, but should NOT fail on entity_id validation
mock_call_service.return_value = {"success": True}
result = json.loads(_handle_call_service({
"domain": "scene", "service": "turn_on"
}))
if "error" in result:
assert "Invalid entity_id" not in result["error"]
assert result["result"]["success"] is True
mock_call_service.assert_awaited_once_with(
"scene",
"turn_on",
None,
None,
)
# ---------------------------------------------------------------------------