1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-22 16:30:27 +01:00
Files
core/tests/components/risco/test_init.py
T
2026-05-12 19:39:08 +02:00

140 lines
4.4 KiB
Python

"""Tests for the Risco integration."""
import logging
from typing import Any, cast
from unittest.mock import AsyncMock, MagicMock, patch
from pyrisco import OperationError
import pytest
from homeassistant.components.risco.const import (
CONF_COMMUNICATION_DELAY,
DEFAULT_CONCURRENCY,
DOMAIN,
TYPE_LOCAL,
)
from homeassistant.const import CONF_HOST, CONF_PIN, CONF_PORT, CONF_TYPE
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
@pytest.fixture
def mock_error_handler() -> MagicMock:
"""Create a mock for add_error_handler."""
with patch("homeassistant.components.risco.RiscoLocal.add_error_handler") as mock:
yield mock
async def test_connection_reset(
hass: HomeAssistant,
two_zone_local: dict[int, Any],
mock_error_handler: MagicMock,
setup_risco_local: MockConfigEntry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test that ConnectionResetError triggers a reload but generic errors do not."""
callback = mock_error_handler.call_args.args[0]
assert callback is not None
local_data = setup_risco_local.runtime_data.local_data
disconnect_mock = cast(AsyncMock, local_data.system.disconnect)
connect_mock = cast(AsyncMock, local_data.system.connect)
caplog.set_level(logging.DEBUG, logger="homeassistant.components.risco")
# Generic error should not trigger reload — unload/setup not invoked again
await callback(Exception())
await hass.async_block_till_done()
disconnect_mock.assert_not_called()
assert connect_mock.call_count == 1
# ConnectionResetError should trigger a reload
await callback(ConnectionResetError())
await hass.async_block_till_done()
disconnect_mock.assert_awaited_once()
assert connect_mock.call_count == 2
assert "Disconnected from panel. Reloading integration" in caplog.text
async def test_unload_handles_disconnect_error(
hass: HomeAssistant,
two_zone_local: dict[int, Any],
setup_risco_local: MockConfigEntry,
) -> None:
"""Test unload succeeds when local disconnect errors out."""
with patch(
"homeassistant.components.risco.RiscoLocal.disconnect",
side_effect=RuntimeError("disconnect failed"),
) as disconnect_mock:
assert await hass.config_entries.async_unload(setup_risco_local.entry_id)
disconnect_mock.assert_awaited_once()
async def test_local_setup_uses_stored_communication_delay(
hass: HomeAssistant,
) -> None:
"""Test local setup passes stored communication delay to the client."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_TYPE: TYPE_LOCAL,
CONF_HOST: "test-host",
CONF_PORT: 5004,
CONF_PIN: "1234",
CONF_COMMUNICATION_DELAY: 2,
},
)
config_entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.risco.RiscoLocal", autospec=True
) as risco_local,
patch.object(
hass.config_entries,
"async_forward_entry_setups",
AsyncMock(return_value=True),
),
):
risco_local.return_value.connect = AsyncMock()
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
risco_local.assert_called_once_with(
"test-host",
5004,
"1234",
communication_delay=2,
concurrency=DEFAULT_CONCURRENCY,
)
async def test_clock_operation_error_is_downgraded(
hass: HomeAssistant,
two_zone_local: dict[int, Any],
mock_error_handler: MagicMock,
setup_risco_local: MockConfigEntry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test CLOCK keep-alive operation errors warn without triggering reload."""
callback = mock_error_handler.call_args.args[0]
assert callback is not None
local_data = setup_risco_local.runtime_data.local_data
disconnect_mock = cast(AsyncMock, local_data.system.disconnect)
caplog.set_level(logging.WARNING, logger="homeassistant.components.risco")
await callback(OperationError("Timeout in command: CLOCK"))
disconnect_mock.assert_not_awaited()
assert "Error in Risco library" not in caplog.text
expected_warning = (
"Risco keep-alive timeout for entry "
f"{setup_risco_local.title} (host: "
f"{setup_risco_local.data.get(CONF_HOST, 'unknown')})"
)
assert expected_warning in caplog.text