mirror of
https://github.com/home-assistant/core.git
synced 2026-08-28 18:24:50 -05:00
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Paulus Schoutsen <balloob@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
213 lines
6.5 KiB
Python
213 lines
6.5 KiB
Python
"""Tests for the Flexit integration."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from modbus_connection import (
|
|
ModbusError,
|
|
ModbusSerialParams,
|
|
ModbusTcpParams,
|
|
ModbusTimeoutError,
|
|
)
|
|
from modbus_connection.mock import MockModbusConnection, MockModbusUnit
|
|
|
|
from homeassistant.components.flexit import create_modbus_params
|
|
from homeassistant.components.flexit.const import CONF_UNIT, DOMAIN, TYPE_TCP
|
|
from homeassistant.config_entries import ConfigEntryState
|
|
from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_PORT, CONF_TYPE
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
def test_create_tcp_params() -> None:
|
|
"""Test creating TCP connection parameters."""
|
|
assert create_modbus_params(
|
|
{CONF_TYPE: TYPE_TCP, CONF_HOST: "192.168.1.100", CONF_PORT: 5020}
|
|
) == ModbusTcpParams(host="192.168.1.100", port=5020)
|
|
|
|
|
|
def test_create_serial_params() -> None:
|
|
"""Test creating serial connection parameters."""
|
|
assert create_modbus_params(
|
|
{
|
|
CONF_TYPE: "serial",
|
|
CONF_DEVICE: "/dev/ttyUSB0",
|
|
"baudrate": 57600,
|
|
}
|
|
) == ModbusSerialParams(
|
|
device="/dev/ttyUSB0",
|
|
baudrate=57600,
|
|
bytesize=8,
|
|
parity="E",
|
|
stopbits=1,
|
|
)
|
|
|
|
|
|
async def test_async_setup_entry_success(
|
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test successful setup of the integration."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
assert result is True
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
|
|
async def test_async_setup_entry_with_custom_port(
|
|
hass: HomeAssistant,
|
|
mock_get_modbus_unit: MagicMock,
|
|
) -> None:
|
|
"""Test setup with custom port."""
|
|
config_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Flexit",
|
|
data={
|
|
CONF_TYPE: TYPE_TCP,
|
|
CONF_HOST: "192.168.1.100",
|
|
CONF_PORT: 5020,
|
|
CONF_UNIT: 1,
|
|
},
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.async_setup(config_entry.entry_id)
|
|
|
|
assert result is True
|
|
mock_get_modbus_unit.assert_called_once_with(
|
|
hass,
|
|
config_entry,
|
|
ModbusTcpParams(host="192.168.1.100", port=5020),
|
|
1,
|
|
)
|
|
|
|
|
|
async def test_async_setup_entry_without_port(
|
|
hass: HomeAssistant,
|
|
mock_get_modbus_unit: MagicMock,
|
|
) -> None:
|
|
"""Test setup without port (should use default)."""
|
|
config_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Flexit",
|
|
data={CONF_TYPE: TYPE_TCP, CONF_HOST: "192.168.1.100", CONF_UNIT: 1},
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.async_setup(config_entry.entry_id)
|
|
|
|
assert result is True
|
|
mock_get_modbus_unit.assert_called_once_with(
|
|
hass,
|
|
config_entry,
|
|
ModbusTcpParams(host="192.168.1.100", port=502),
|
|
1,
|
|
)
|
|
|
|
|
|
async def test_async_setup_entry_serial(
|
|
hass: HomeAssistant,
|
|
mock_serial_config_entry: MockConfigEntry,
|
|
mock_get_modbus_unit: MagicMock,
|
|
) -> None:
|
|
"""Test setup of a serial (RTU) config entry."""
|
|
mock_serial_config_entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.async_setup(mock_serial_config_entry.entry_id)
|
|
|
|
assert result is True
|
|
assert mock_serial_config_entry.state is ConfigEntryState.LOADED
|
|
mock_get_modbus_unit.assert_called_once_with(
|
|
hass,
|
|
mock_serial_config_entry,
|
|
ModbusSerialParams(
|
|
device="/dev/ttyUSB0",
|
|
baudrate=57600,
|
|
bytesize=8,
|
|
parity="E",
|
|
stopbits=1,
|
|
),
|
|
1,
|
|
)
|
|
|
|
|
|
async def test_async_setup_entry_cannot_connect(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_modbus_unit: MockModbusUnit,
|
|
) -> None:
|
|
"""Test setup retries when the first request cannot connect."""
|
|
mock_modbus_unit.fail_requests(ModbusTimeoutError("could not connect"))
|
|
mock_config_entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
assert result is False
|
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
|
assert not hasattr(mock_config_entry, "runtime_data")
|
|
|
|
|
|
async def test_async_setup_entry_coordinator_update_fails(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_modbus_unit: MockModbusUnit,
|
|
) -> None:
|
|
"""Test setup retries when the first update fails."""
|
|
mock_modbus_unit.fail_requests(ModbusError("update failed"))
|
|
mock_config_entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
assert result is False
|
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
|
|
|
|
|
async def test_connection_lost_recovers_on_next_update(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_modbus_connection: MockModbusConnection,
|
|
) -> None:
|
|
"""Test the next update reconnects without reloading the config entry."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
mock_modbus_connection.simulate_connection_lost()
|
|
with patch.object(
|
|
hass.config_entries, "async_schedule_reload"
|
|
) as mock_schedule_reload:
|
|
await mock_config_entry.runtime_data.async_refresh()
|
|
|
|
assert mock_config_entry.runtime_data.last_update_success
|
|
assert mock_modbus_connection.connected
|
|
mock_schedule_reload.assert_not_called()
|
|
|
|
|
|
async def test_unload_entry(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test unloading the config entry."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
assert await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
|
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
|
|
|
|
|
async def test_unload_entry_fails(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test a platform unload failure marks the config entry accordingly."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
with patch(
|
|
"homeassistant.config_entries.ConfigEntries.async_unload_platforms",
|
|
return_value=False,
|
|
):
|
|
assert not await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
|
|
|
assert mock_config_entry.state is ConfigEntryState.FAILED_UNLOAD
|