mirror of
https://github.com/home-assistant/core.git
synced 2026-02-25 20:35:09 +00:00
276 lines
9.0 KiB
Python
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
|