1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-25 20:35:09 +00:00
Files
core/tests/components/systemnexa2/test_switch.py
konsulten b73beba152 System Nexa 2 Core Integration (#159140)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-19 13:31:17 +01:00

276 lines
9.0 KiB
Python

"""Test the System Nexa 2 switch platform."""
from unittest.mock import AsyncMock, MagicMock
import pytest
from sn2 import ConnectionStatus, OnOffSetting, SettingsUpdate, StateChange
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TOGGLE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant
import homeassistant.helpers.entity_registry as er
from . import find_update_callback
from tests.common import MockConfigEntry, snapshot_platform
@pytest.mark.usefixtures("mock_system_nexa_2_device")
async def test_switch_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the switch entities."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
async def test_switch_turn_on_off_toggle(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_system_nexa_2_device,
) -> None:
"""Test switch turn on, turn off, and toggle."""
device = mock_system_nexa_2_device.return_value
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Get the coordinator and update it with state
entry = hass.config_entries.async_get_entry(mock_config_entry.entry_id)
assert entry
coordinator = entry.runtime_data
await coordinator._async_handle_update(StateChange(state=0.0))
await hass.async_block_till_done()
# Test turn on
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.test_device_relay_1"},
blocking=True,
)
device.turn_on.assert_called_once()
# Test turn off
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.test_device_relay_1"},
blocking=True,
)
device.turn_off.assert_called_once()
# Test toggle
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TOGGLE,
{ATTR_ENTITY_ID: "switch.test_device_relay_1"},
blocking=True,
)
device.toggle.assert_called_once()
async def test_switch_is_on_property(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_system_nexa_2_device,
) -> None:
"""Test switch is_on property."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Get the coordinator and update it with state
entry = hass.config_entries.async_get_entry(mock_config_entry.entry_id)
coordinator = entry.runtime_data
# Test with state = 1.0 (on)
await coordinator._async_handle_update(StateChange(state=1.0))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_relay_1")
assert state.state == "on"
# Test with state = 0.0 (off)
await coordinator._async_handle_update(StateChange(state=0.0))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_relay_1")
assert state.state == "off"
async def test_configuration_switches(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_system_nexa_2_device,
) -> None:
"""Test configuration switch entities."""
device = mock_system_nexa_2_device.return_value
# Create mock OnOffSettings with keys matching SWITCH_TYPES
mock_setting_433mhz = MagicMock(spec=OnOffSetting)
mock_setting_433mhz.name = "433Mhz" # Must match key in SWITCH_TYPES
mock_setting_433mhz.enable = AsyncMock()
mock_setting_433mhz.disable = AsyncMock()
mock_setting_433mhz.is_enabled = MagicMock(return_value=True)
mock_setting_cloud = MagicMock(spec=OnOffSetting)
mock_setting_cloud.name = "Cloud Access" # Must match key in SWITCH_TYPES
mock_setting_cloud.enable = AsyncMock()
mock_setting_cloud.disable = AsyncMock()
mock_setting_cloud.is_enabled = MagicMock(return_value=False)
# Set settings before setup
device.settings = [mock_setting_433mhz, mock_setting_cloud]
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Make coordinator data available
entry = hass.config_entries.async_get_entry(mock_config_entry.entry_id)
coordinator = entry.runtime_data
await coordinator._async_handle_update(StateChange(state=1.0))
await hass.async_block_till_done()
# Check 433mhz switch state (should be on)
state = hass.states.get("switch.test_device_433_mhz")
assert state is not None
assert state.state == "on"
# Check cloud_access switch state (should be off)
state = hass.states.get("switch.test_device_cloud_access")
assert state is not None
assert state.state == "off"
# Test turn off 433mhz
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.test_device_433_mhz"},
blocking=True,
)
mock_setting_433mhz.disable.assert_called_once_with(device)
# Test turn on cloud_access
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.test_device_cloud_access"},
blocking=True,
)
mock_setting_cloud.enable.assert_called_once_with(device)
async def test_coordinator_connection_status(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_system_nexa_2_device: MagicMock,
) -> None:
"""Test coordinator handles connection status updates."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Find the callback that was registered with the device
update_callback = find_update_callback(mock_system_nexa_2_device)
# Initially, the relay switch should be off (state=1.0 from fixture)
state = hass.states.get("switch.test_device_relay_1")
assert state is not None
assert state.state == STATE_ON
# Simulate device disconnection
await update_callback(ConnectionStatus(connected=False))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_relay_1")
assert state.state == STATE_UNAVAILABLE
# Simulate reconnection and state update
await update_callback(ConnectionStatus(connected=True))
await update_callback(StateChange(state=1.0))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_relay_1")
assert state.state == STATE_ON
async def test_coordinator_state_change(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_system_nexa_2_device: MagicMock,
) -> None:
"""Test coordinator handles state change updates."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Find the callback that was registered with the device
update_callback = find_update_callback(mock_system_nexa_2_device)
# Change state to off (0.0)
await update_callback(StateChange(state=0.0))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_relay_1")
assert state is not None
assert state.state == STATE_OFF
# Change state to on (1.0)
await update_callback(StateChange(state=1.0))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_relay_1")
assert state.state == STATE_ON
async def test_coordinator_settings_update(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_system_nexa_2_device: MagicMock,
) -> None:
"""Test coordinator handles settings updates."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Find the callback that was registered with the device
update_callback = find_update_callback(mock_system_nexa_2_device)
# Get initial state of 433Mhz switch (should be on from fixture)
state = hass.states.get("switch.test_device_433_mhz")
assert state is not None
assert state.state == STATE_ON
# Get the settings from the device mock and change 433Mhz to disabled
device = mock_system_nexa_2_device.return_value
device.settings[0].is_enabled.return_value = False # 433Mhz
# Simulate settings update where 433Mhz is now disabled
await update_callback(SettingsUpdate(settings=device.settings))
# Need state update to trigger coordinator data update
await update_callback(StateChange(state=1.0))
await hass.async_block_till_done()
state = hass.states.get("switch.test_device_433_mhz")
assert state.state == STATE_OFF