hass-core/tests/components/shelly/test_utils.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

277 lines
8.1 KiB
Python
Raw Normal View History

"""Tests for Shelly utils."""
from typing import Any
from unittest.mock import Mock
from aioshelly.const import (
MODEL_1,
MODEL_1L,
MODEL_BUTTON1,
MODEL_BUTTON1_V2,
MODEL_DIMMER_2,
MODEL_EM3,
MODEL_I3,
MODEL_MOTION,
MODEL_PLUS_2PM_V2,
MODEL_WALL_DISPLAY,
)
import pytest
from homeassistant.components.shelly.const import GEN1_RELEASE_URL, GEN2_RELEASE_URL
from homeassistant.components.shelly.utils import (
get_block_channel_name,
get_block_device_sleep_period,
get_block_input_triggers,
get_device_uptime,
get_number_of_channels,
get_release_url,
get_rpc_channel_name,
get_rpc_input_triggers,
is_block_momentary_input,
)
from homeassistant.util import dt as dt_util
DEVICE_BLOCK_ID = 4
async def test_block_get_number_of_channels(
mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test block get number of channels."""
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "type", "emeter")
monkeypatch.setitem(mock_block_device.shelly, "num_emeters", 3)
assert (
get_number_of_channels(
mock_block_device,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
== 3
)
monkeypatch.setitem(mock_block_device.shelly, "num_inputs", 4)
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "type", "input")
assert (
get_number_of_channels(
mock_block_device,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
== 4
)
monkeypatch.setitem(mock_block_device.settings["device"], "type", MODEL_DIMMER_2)
assert (
get_number_of_channels(
mock_block_device,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
== 2
)
async def test_block_get_block_channel_name(
mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test block get block channel name."""
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "type", "relay")
assert (
get_block_channel_name(
mock_block_device,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
== "Test name channel 1"
)
monkeypatch.setitem(mock_block_device.settings["device"], "type", MODEL_EM3)
assert (
get_block_channel_name(
mock_block_device,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
== "Test name channel A"
)
monkeypatch.setitem(
mock_block_device.settings, "relays", [{"name": "test-channel"}]
)
assert (
get_block_channel_name(
mock_block_device,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
== "test-channel"
)
async def test_is_block_momentary_input(
mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test is block momentary input."""
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "type", "relay")
monkeypatch.setitem(mock_block_device.settings, "mode", "roller")
monkeypatch.setitem(
mock_block_device.settings, "rollers", [{"button_type": "detached"}]
)
assert (
is_block_momentary_input(
mock_block_device.settings,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
is False
)
assert (
is_block_momentary_input(
mock_block_device.settings, mock_block_device.blocks[DEVICE_BLOCK_ID], True
)
is True
)
monkeypatch.setitem(mock_block_device.settings, "mode", "relay")
monkeypatch.setitem(mock_block_device.settings["device"], "type", MODEL_1L)
assert (
is_block_momentary_input(
mock_block_device.settings, mock_block_device.blocks[DEVICE_BLOCK_ID], True
)
is False
)
monkeypatch.delitem(mock_block_device.settings, "relays")
monkeypatch.delitem(mock_block_device.settings, "rollers")
assert (
is_block_momentary_input(
mock_block_device.settings,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
is False
)
monkeypatch.setitem(mock_block_device.settings["device"], "type", MODEL_BUTTON1_V2)
assert (
is_block_momentary_input(
mock_block_device.settings,
mock_block_device.blocks[DEVICE_BLOCK_ID],
)
is True
)
@pytest.mark.parametrize(
("settings", "sleep_period"),
[
({}, 0),
({"sleep_mode": {"period": 1000, "unit": "m"}}, 1000 * 60),
({"sleep_mode": {"period": 5, "unit": "h"}}, 5 * 3600),
],
)
async def test_get_block_device_sleep_period(
settings: dict[str, Any], sleep_period: int
) -> None:
"""Test get block device sleep period."""
assert get_block_device_sleep_period(settings) == sleep_period
@pytest.mark.freeze_time("2019-01-10 18:43:00+00:00")
async def test_get_device_uptime() -> None:
"""Test block test get device uptime."""
assert get_device_uptime(
55, dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:00+00:00"))
) == dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:00+00:00"))
assert get_device_uptime(
50, dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:00+00:00"))
) == dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:10+00:00"))
async def test_get_block_input_triggers(
mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test get block input triggers."""
monkeypatch.setattr(
mock_block_device.blocks[DEVICE_BLOCK_ID],
"sensor_ids",
{"inputEvent": "S", "inputEventCnt": 0},
)
monkeypatch.setitem(
mock_block_device.settings, "rollers", [{"button_type": "detached"}]
)
assert set(
get_block_input_triggers(
mock_block_device, mock_block_device.blocks[DEVICE_BLOCK_ID]
)
) == {("long", "button"), ("single", "button")}
monkeypatch.setitem(mock_block_device.settings["device"], "type", MODEL_BUTTON1)
assert set(
get_block_input_triggers(
mock_block_device, mock_block_device.blocks[DEVICE_BLOCK_ID]
)
) == {
("long", "button"),
("double", "button"),
("single", "button"),
("triple", "button"),
}
monkeypatch.setitem(mock_block_device.settings["device"], "type", MODEL_I3)
assert set(
get_block_input_triggers(
mock_block_device, mock_block_device.blocks[DEVICE_BLOCK_ID]
)
) == {
("long_single", "button"),
("single_long", "button"),
("triple", "button"),
("long", "button"),
("single", "button"),
("double", "button"),
}
async def test_get_rpc_channel_name(mock_rpc_device: Mock) -> None:
"""Test get RPC channel name."""
assert get_rpc_channel_name(mock_rpc_device, "input:0") == "Test name input 0"
assert get_rpc_channel_name(mock_rpc_device, "input:3") == "Test name input_3"
async def test_get_rpc_input_triggers(
mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test get RPC input triggers."""
monkeypatch.setattr(mock_rpc_device, "config", {"input:0": {"type": "button"}})
assert set(get_rpc_input_triggers(mock_rpc_device)) == {
("btn_down", "button1"),
("btn_up", "button1"),
("single_push", "button1"),
("double_push", "button1"),
("triple_push", "button1"),
("long_push", "button1"),
}
monkeypatch.setattr(mock_rpc_device, "config", {"input:0": {"type": "switch"}})
assert not get_rpc_input_triggers(mock_rpc_device)
@pytest.mark.parametrize(
("gen", "model", "beta", "expected"),
[
(1, MODEL_MOTION, False, None),
(1, MODEL_1, False, GEN1_RELEASE_URL),
(1, MODEL_1, True, None),
(2, MODEL_WALL_DISPLAY, False, None),
(2, MODEL_PLUS_2PM_V2, False, GEN2_RELEASE_URL),
(2, MODEL_PLUS_2PM_V2, True, None),
],
)
def test_get_release_url(
gen: int, model: str, beta: bool, expected: str | None
) -> None:
"""Test get_release_url() with a device without a release note URL."""
result = get_release_url(gen, model, beta)
assert result is expected