1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-26 04:46:08 +00:00
Files
core/tests/components/indevolt/test_switch.py
2026-02-19 17:46:13 +01:00

220 lines
6.6 KiB
Python

"""Tests for the Indevolt switch platform."""
from datetime import timedelta
from unittest.mock import AsyncMock, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.indevolt.coordinator import SCAN_INTERVAL
from homeassistant.components.switch import SERVICE_TURN_OFF, SERVICE_TURN_ON
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
KEY_READ_GRID_CHARGING = "2618"
KEY_WRITE_GRID_CHARGING = "1143"
KEY_READ_LIGHT = "7171"
KEY_WRITE_LIGHT = "7265"
KEY_READ_BYPASS = "680"
KEY_WRITE_BYPASS = "7266"
DEFAULT_STATE_ON = 1
DEFAULT_STATE_OFF = 0
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@pytest.mark.parametrize("generation", [2], indirect=True)
async def test_switch(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_indevolt: AsyncMock,
snapshot: SnapshotAssertion,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test switch entity registration and states."""
with patch("homeassistant.components.indevolt.PLATFORMS", [Platform.SWITCH]):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.parametrize("generation", [2], indirect=True)
@pytest.mark.parametrize(
("entity_id", "read_key", "write_key", "on_value"),
[
(
"switch.cms_sf2000_allow_grid_charging",
KEY_READ_GRID_CHARGING,
KEY_WRITE_GRID_CHARGING,
1001,
),
(
"switch.cms_sf2000_led_indicator",
KEY_READ_LIGHT,
KEY_WRITE_LIGHT,
DEFAULT_STATE_ON,
),
(
"switch.cms_sf2000_bypass_socket",
KEY_READ_BYPASS,
KEY_WRITE_BYPASS,
DEFAULT_STATE_ON,
),
],
)
async def test_switch_turn_on(
hass: HomeAssistant,
mock_indevolt: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_id: str,
read_key: str,
write_key: str,
on_value: int,
) -> None:
"""Test turning switches on."""
with patch("homeassistant.components.indevolt.PLATFORMS", [Platform.SWITCH]):
await setup_integration(hass, mock_config_entry)
# Reset mock call count for this iteration
mock_indevolt.set_data.reset_mock()
# Update mock data to reflect the new value
mock_indevolt.fetch_data.return_value[read_key] = on_value
# Call the service to turn on
await hass.services.async_call(
Platform.SWITCH,
SERVICE_TURN_ON,
{"entity_id": entity_id},
blocking=True,
)
# Verify set_data was called with correct parameters
mock_indevolt.set_data.assert_called_with(write_key, 1)
# Verify updated state
assert (state := hass.states.get(entity_id)) is not None
assert state.state == STATE_ON
@pytest.mark.parametrize("generation", [2], indirect=True)
@pytest.mark.parametrize(
("entity_id", "read_key", "write_key", "off_value"),
[
(
"switch.cms_sf2000_allow_grid_charging",
KEY_READ_GRID_CHARGING,
KEY_WRITE_GRID_CHARGING,
1000,
),
(
"switch.cms_sf2000_led_indicator",
KEY_READ_LIGHT,
KEY_WRITE_LIGHT,
DEFAULT_STATE_OFF,
),
(
"switch.cms_sf2000_bypass_socket",
KEY_READ_BYPASS,
KEY_WRITE_BYPASS,
DEFAULT_STATE_OFF,
),
],
)
async def test_switch_turn_off(
hass: HomeAssistant,
mock_indevolt: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_id: str,
read_key: str,
write_key: str,
off_value: int,
) -> None:
"""Test turning switches off."""
with patch("homeassistant.components.indevolt.PLATFORMS", [Platform.SWITCH]):
await setup_integration(hass, mock_config_entry)
# Reset mock call count for this iteration
mock_indevolt.set_data.reset_mock()
# Update mock data to reflect the new value
mock_indevolt.fetch_data.return_value[read_key] = off_value
# Call the service to turn off
await hass.services.async_call(
Platform.SWITCH,
SERVICE_TURN_OFF,
{"entity_id": entity_id},
blocking=True,
)
# Verify set_data was called with correct parameters
mock_indevolt.set_data.assert_called_with(write_key, 0)
# Verify updated state
assert (state := hass.states.get(entity_id)) is not None
assert state.state == STATE_OFF
@pytest.mark.parametrize("generation", [2], indirect=True)
async def test_switch_set_value_error(
hass: HomeAssistant,
mock_indevolt: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test error handling when toggling a switch."""
with patch("homeassistant.components.indevolt.PLATFORMS", [Platform.SWITCH]):
await setup_integration(hass, mock_config_entry)
# Mock set_data to raise an error
mock_indevolt.set_data.side_effect = HomeAssistantError(
"Device communication failed"
)
# Attempt to switch on
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
Platform.SWITCH,
SERVICE_TURN_ON,
{"entity_id": "switch.cms_sf2000_allow_grid_charging"},
blocking=True,
)
# Verify set_data was called before failing
mock_indevolt.set_data.assert_called_once()
@pytest.mark.parametrize("generation", [2], indirect=True)
async def test_switch_availability(
hass: HomeAssistant,
mock_indevolt: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test switch entity availability / non-availability."""
with patch("homeassistant.components.indevolt.PLATFORMS", [Platform.SWITCH]):
await setup_integration(hass, mock_config_entry)
# Confirm current state is "on"
assert (state := hass.states.get("switch.cms_sf2000_allow_grid_charging"))
assert state.state == STATE_ON
# Simulate fetch_data error
mock_indevolt.fetch_data.side_effect = ConnectionError
freezer.tick(delta=timedelta(seconds=SCAN_INTERVAL))
async_fire_time_changed(hass)
await hass.async_block_till_done()
# Confirm current state is "unavailable"
assert (state := hass.states.get("switch.cms_sf2000_allow_grid_charging"))
assert state.state == STATE_UNAVAILABLE