mirror of
https://github.com/home-assistant/core.git
synced 2026-09-18 14:38:02 +01:00
254 lines
7.7 KiB
Python
254 lines
7.7 KiB
Python
"""Tests for the OpenEVSE select platform."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from aiohttp import ContentTypeError, ServerTimeoutError
|
|
from openevsehttp.exceptions import (
|
|
AuthenticationError,
|
|
ParseJSONError,
|
|
UnknownError,
|
|
UnsupportedFeature,
|
|
)
|
|
import pytest
|
|
from syrupy.assertion import SnapshotAssertion
|
|
|
|
from homeassistant.components.openevse.const import DOMAIN
|
|
from homeassistant.components.select import (
|
|
ATTR_OPTION,
|
|
DOMAIN as SELECT_DOMAIN,
|
|
SERVICE_SELECT_OPTION,
|
|
)
|
|
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import (
|
|
ConfigEntryAuthFailed,
|
|
HomeAssistantError,
|
|
ServiceValidationError,
|
|
)
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
from tests.common import MockConfigEntry, snapshot_platform
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
async def test_entities(
|
|
hass: HomeAssistant,
|
|
entity_registry: er.EntityRegistry,
|
|
snapshot: SnapshotAssertion,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_charger: MagicMock,
|
|
) -> None:
|
|
"""Test the select entities."""
|
|
with patch("homeassistant.components.openevse.PLATFORMS", [Platform.SELECT]):
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
|
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("option", "method_name", "kwargs"),
|
|
[
|
|
pytest.param(
|
|
"auto",
|
|
"clear_override",
|
|
{},
|
|
id="override_state_auto",
|
|
),
|
|
pytest.param(
|
|
"active",
|
|
"set_override",
|
|
{"state": "active"},
|
|
id="override_state_active",
|
|
),
|
|
pytest.param(
|
|
"disabled",
|
|
"set_override",
|
|
{"state": "disabled"},
|
|
id="override_state_disabled",
|
|
),
|
|
],
|
|
)
|
|
async def test_select_option(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_charger: MagicMock,
|
|
option: str,
|
|
method_name: str,
|
|
kwargs: dict[str, str],
|
|
) -> None:
|
|
"""Test selecting an option on the select 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 hass.services.async_call(
|
|
SELECT_DOMAIN,
|
|
SERVICE_SELECT_OPTION,
|
|
{
|
|
ATTR_ENTITY_ID: "select.openevse_mock_config_override_state",
|
|
ATTR_OPTION: option,
|
|
},
|
|
blocking=True,
|
|
)
|
|
getattr(mock_charger, method_name).assert_called_once_with(**kwargs)
|
|
state = hass.states.get("select.openevse_mock_config_override_state")
|
|
assert state is not None
|
|
assert state.state == option
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("raised", "expected", "translation_key", "translation_placeholders"),
|
|
[
|
|
pytest.param(
|
|
ValueError("invalid mode"),
|
|
ServiceValidationError,
|
|
"invalid_value",
|
|
{"value": "active"},
|
|
id="value_error",
|
|
),
|
|
pytest.param(
|
|
AuthenticationError("bad creds"),
|
|
ConfigEntryAuthFailed,
|
|
"authentication_error",
|
|
None,
|
|
id="auth_error",
|
|
),
|
|
pytest.param(
|
|
TimeoutError("timed out"),
|
|
HomeAssistantError,
|
|
"communication_error",
|
|
None,
|
|
id="timeout_error",
|
|
),
|
|
pytest.param(
|
|
ServerTimeoutError("timed out"),
|
|
HomeAssistantError,
|
|
"communication_error",
|
|
None,
|
|
id="server_timeout_error",
|
|
),
|
|
pytest.param(
|
|
ParseJSONError("bad json"),
|
|
HomeAssistantError,
|
|
"communication_error",
|
|
None,
|
|
id="parse_json_error",
|
|
),
|
|
pytest.param(
|
|
UnsupportedFeature("old firmware"),
|
|
HomeAssistantError,
|
|
"unsupported_feature",
|
|
None,
|
|
id="unsupported_feature",
|
|
),
|
|
pytest.param(
|
|
ContentTypeError(MagicMock(), (), message="bad content"),
|
|
HomeAssistantError,
|
|
"communication_error",
|
|
None,
|
|
id="content_type_error",
|
|
),
|
|
pytest.param(
|
|
UnknownError("unknown error"),
|
|
HomeAssistantError,
|
|
"communication_error",
|
|
None,
|
|
id="unknown_error",
|
|
),
|
|
pytest.param(
|
|
RuntimeError("runtime error"),
|
|
HomeAssistantError,
|
|
"communication_error",
|
|
None,
|
|
id="runtime_error",
|
|
),
|
|
],
|
|
)
|
|
async def test_select_raises(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_charger: MagicMock,
|
|
raised: Exception,
|
|
expected: type[HomeAssistantError],
|
|
translation_key: str,
|
|
translation_placeholders: dict[str, str] | None,
|
|
) -> None:
|
|
"""Test that errors from the charger are translated to HA exceptions."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
mock_charger.set_override.side_effect = raised
|
|
|
|
with pytest.raises(expected) as exc_info:
|
|
await hass.services.async_call(
|
|
SELECT_DOMAIN,
|
|
SERVICE_SELECT_OPTION,
|
|
{
|
|
ATTR_ENTITY_ID: "select.openevse_mock_config_override_state",
|
|
ATTR_OPTION: "active",
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert exc_info.value.translation_key == translation_key
|
|
assert exc_info.value.translation_domain == DOMAIN
|
|
assert exc_info.value.translation_placeholders == translation_placeholders
|
|
|
|
|
|
async def test_select_unavailable_when_unsupported(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_charger: MagicMock,
|
|
) -> None:
|
|
"""Test select entity is unavailable when override state is unsupported."""
|
|
mock_charger.get_override_state.return_value = None
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("select.openevse_mock_config_override_state")
|
|
assert state is not None
|
|
assert state.state == "unavailable"
|
|
|
|
|
|
async def test_select_unavailable_when_initial_read_fails(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_charger: MagicMock,
|
|
) -> None:
|
|
"""Test select entity is registered and unavailable when initial read fails."""
|
|
mock_charger.get_override_state.side_effect = TimeoutError
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("select.openevse_mock_config_override_state")
|
|
assert state is not None
|
|
assert state.state == "unavailable"
|
|
|
|
|
|
async def test_select_coordinator_update_failure_marks_unavailable(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_charger: MagicMock,
|
|
) -> None:
|
|
"""Test coordinator update failure marks select entity unavailable."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("select.openevse_mock_config_override_state")
|
|
assert state is not None
|
|
assert state.state == "auto"
|
|
|
|
mock_charger.get_override_state.side_effect = TimeoutError
|
|
coordinator = mock_config_entry.runtime_data
|
|
await coordinator.async_refresh()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("select.openevse_mock_config_override_state")
|
|
assert state is not None
|
|
assert state.state == "unavailable"
|