Add tests coverage for Shelly number platform (#82480)

This commit is contained in:
Shay Levy 2022-11-21 18:55:06 +02:00 committed by GitHub
parent 13c03d022b
commit 91a44b697b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 162 additions and 6 deletions

View File

@ -1111,7 +1111,6 @@ omit =
homeassistant/components/seventeentrack/sensor.py homeassistant/components/seventeentrack/sensor.py
homeassistant/components/shelly/climate.py homeassistant/components/shelly/climate.py
homeassistant/components/shelly/coordinator.py homeassistant/components/shelly/coordinator.py
homeassistant/components/shelly/number.py
homeassistant/components/shelly/utils.py homeassistant/components/shelly/utils.py
homeassistant/components/shiftr/* homeassistant/components/shiftr/*
homeassistant/components/shodan/sensor.py homeassistant/components/shodan/sensor.py

View File

@ -25,7 +25,6 @@ from .entity import (
ShellySleepingBlockAttributeEntity, ShellySleepingBlockAttributeEntity,
async_setup_entry_attribute_entities, async_setup_entry_attribute_entities,
) )
from .utils import get_device_entry_gen
@dataclass @dataclass
@ -77,9 +76,6 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up numbers for device.""" """Set up numbers for device."""
if get_device_entry_gen(config_entry) == 2:
return
if config_entry.data[CONF_SLEEP_PERIOD]: if config_entry.data[CONF_SLEEP_PERIOD]:
async_setup_entry_attribute_entities( async_setup_entry_attribute_entities(
hass, hass,

View File

@ -1,6 +1,7 @@
"""Tests for the Shelly integration.""" """Tests for the Shelly integration."""
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping
from copy import deepcopy from copy import deepcopy
from datetime import timedelta from datetime import timedelta
from typing import Any from typing import Any
@ -99,6 +100,7 @@ def register_entity(
object_id: str, object_id: str,
unique_id: str, unique_id: str,
config_entry: ConfigEntry | None = None, config_entry: ConfigEntry | None = None,
capabilities: Mapping[str, Any] | None = None,
) -> str: ) -> str:
"""Register enabled entity, return entity_id.""" """Register enabled entity, return entity_id."""
entity_registry = async_get(hass) entity_registry = async_get(hass)
@ -109,6 +111,7 @@ def register_entity(
suggested_object_id=object_id, suggested_object_id=object_id,
disabled_by=None, disabled_by=None,
config_entry=config_entry, config_entry=config_entry,
capabilities=capabilities,
) )
return f"{domain}.{object_id}" return f"{domain}.{object_id}"

View File

@ -30,6 +30,7 @@ MOCK_SETTINGS = {
"relays": [{"btn_type": "momentary"}, {"btn_type": "toggle"}], "relays": [{"btn_type": "momentary"}, {"btn_type": "toggle"}],
"rollers": [{"positioning": True}], "rollers": [{"positioning": True}],
"external_power": 0, "external_power": 0,
"thermostats": [{"schedule_profile_names": {}}],
} }
@ -106,9 +107,11 @@ MOCK_BLOCKS = [
type="sensor", type="sensor",
), ),
Mock( Mock(
sensor_ids={"battery": 98}, sensor_ids={"battery": 98, "valvePos": 50},
channel="0",
battery=98, battery=98,
cfgChanged=0, cfgChanged=0,
valvePos=50,
description="device_0", description="device_0",
type="device", type="device",
), ),

View File

@ -0,0 +1,152 @@
"""Tests for Shelly number platform."""
from unittest.mock import AsyncMock
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError
import pytest
from homeassistant.components.number import (
ATTR_VALUE,
DOMAIN as NUMBER_DOMAIN,
SERVICE_SET_VALUE,
)
from homeassistant.components.shelly.const import DOMAIN
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import State
from homeassistant.exceptions import HomeAssistantError
from . import init_integration, register_device, register_entity
from tests.common import mock_restore_cache
DEVICE_BLOCK_ID = 4
async def test_block_number_update(hass, mock_block_device, monkeypatch):
"""Test block device number update."""
await init_integration(hass, 1, sleep_period=1000)
assert hass.states.get("number.test_name_valve_position") is None
# Make device online
mock_block_device.mock_update()
await hass.async_block_till_done()
assert hass.states.get("number.test_name_valve_position").state == "50"
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valvePos", 30)
mock_block_device.mock_update()
assert hass.states.get("number.test_name_valve_position").state == "30"
async def test_block_restored_number(hass, mock_block_device, device_reg, monkeypatch):
"""Test block restored number."""
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
register_device(device_reg, entry)
capabilities = {
"min": 0,
"max": 100,
"step": 1,
"mode": "slider",
}
entity_id = register_entity(
hass,
NUMBER_DOMAIN,
"test_name_valve_position",
"device_0-valvePos",
entry,
capabilities,
)
mock_restore_cache(hass, [State(entity_id, "40")])
monkeypatch.setattr(mock_block_device, "initialized", False)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == "40"
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_update()
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == "50"
async def test_block_number_set_value(hass, mock_block_device):
"""Test block device number set value."""
await init_integration(hass, 1, sleep_period=1000)
# Make device online
mock_block_device.mock_update()
await hass.async_block_till_done()
mock_block_device.reset_mock()
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: "number.test_name_valve_position", ATTR_VALUE: 30},
blocking=True,
)
mock_block_device.http_request.assert_called_once_with(
"get", "thermostat/0", {"pos": 30.0}
)
async def test_block_set_value_connection_error(hass, mock_block_device, monkeypatch):
"""Test block device set value connection error."""
monkeypatch.setattr(
mock_block_device,
"http_request",
AsyncMock(side_effect=DeviceConnectionError),
)
await init_integration(hass, 1, sleep_period=1000)
# Make device online
mock_block_device.mock_update()
await hass.async_block_till_done()
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: "number.test_name_valve_position", ATTR_VALUE: 30},
blocking=True,
)
async def test_block_set_value_auth_error(hass, mock_block_device, monkeypatch):
"""Test block device set value authentication error."""
monkeypatch.setattr(
mock_block_device,
"http_request",
AsyncMock(side_effect=InvalidAuthError),
)
entry = await init_integration(hass, 1, sleep_period=1000)
# Make device online
mock_block_device.mock_update()
await hass.async_block_till_done()
assert entry.state == ConfigEntryState.LOADED
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: "number.test_name_valve_position", ATTR_VALUE: 30},
blocking=True,
)
assert entry.state == ConfigEntryState.LOADED
flows = hass.config_entries.flow.async_progress()
assert len(flows) == 1
flow = flows[0]
assert flow.get("step_id") == "reauth_confirm"
assert flow.get("handler") == DOMAIN
assert "context" in flow
assert flow["context"].get("source") == SOURCE_REAUTH
assert flow["context"].get("entry_id") == entry.entry_id

View File

@ -50,6 +50,9 @@ async def test_block_rest_sensor(hass, mock_block_device, monkeypatch):
async def test_block_sleeping_sensor(hass, mock_block_device, monkeypatch): async def test_block_sleeping_sensor(hass, mock_block_device, monkeypatch):
"""Test block sleeping sensor.""" """Test block sleeping sensor."""
monkeypatch.setattr(
mock_block_device.blocks[DEVICE_BLOCK_ID], "sensor_ids", {"battery": 98}
)
entity_id = f"{SENSOR_DOMAIN}.test_name_temperature" entity_id = f"{SENSOR_DOMAIN}.test_name_temperature"
await init_integration(hass, 1, sleep_period=1000) await init_integration(hass, 1, sleep_period=1000)