Skip to content

Commit

Permalink
Improve deCONZ websocket fixture (#121332)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kane610 authored Jul 5, 2024
1 parent 9d20461 commit 1b8944d
Show file tree
Hide file tree
Showing 17 changed files with 185 additions and 114 deletions.
43 changes: 35 additions & 8 deletions tests/components/deconz/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from collections.abc import Callable
from collections.abc import Callable, Generator
from types import MappingProxyType
from typing import Any
from unittest.mock import patch
Expand All @@ -20,6 +20,9 @@
from tests.test_util.aiohttp import AiohttpClientMocker

type ConfigEntryFactoryType = Callable[[ConfigEntry | None], ConfigEntry]
type WebsocketDataType = Callable[[dict[str, Any]], None]
type WebsocketStateType = Callable[[str], None]
type _WebsocketMock = Generator[Any, Any, Callable[[dict[str, Any] | None, str], None]]

# Config entry fixtures

Expand Down Expand Up @@ -217,22 +220,46 @@ async def fixture_config_entry_setup(
# Websocket fixtures


@pytest.fixture(autouse=True)
def mock_deconz_websocket():
@pytest.fixture(autouse=True, name="_mock_websocket")
def fixture_websocket() -> _WebsocketMock:
"""No real websocket allowed."""
with patch("pydeconz.gateway.WSClient") as mock:

async def make_websocket_call(data: dict | None = None, state: str = ""):
async def make_websocket_call(
data: dict[str, Any] | None = None, state: str = ""
) -> None:
"""Generate a websocket call."""
pydeconz_gateway_session_handler = mock.call_args[0][3]

signal: Signal
if data:
mock.return_value.data = data
await pydeconz_gateway_session_handler(signal=Signal.DATA)
signal = Signal.DATA
elif state:
mock.return_value.state = state
await pydeconz_gateway_session_handler(signal=Signal.CONNECTION_STATE)
else:
raise NotImplementedError
signal = Signal.CONNECTION_STATE
await pydeconz_gateway_session_handler(signal)

yield make_websocket_call


@pytest.fixture(name="mock_websocket_data")
def fixture_websocket_data(_mock_websocket: _WebsocketMock) -> WebsocketDataType:
"""Fixture to send websocket data."""

async def change_websocket_data(data: dict[str, Any]) -> None:
"""Provide new data on the websocket."""
await _mock_websocket(data=data)

return change_websocket_data


@pytest.fixture(name="mock_websocket_state")
def fixture_websocket_state(_mock_websocket: _WebsocketMock) -> WebsocketStateType:
"""Fixture to set websocket state."""

async def change_websocket_state(state: str) -> None:
"""Simulate a change to the websocket connection state."""
await _mock_websocket(state=state)

return change_websocket_state
20 changes: 11 additions & 9 deletions tests/components/deconz/test_alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
)
from homeassistant.core import HomeAssistant

from .conftest import WebsocketDataType

from tests.test_util.aiohttp import AiohttpClientMocker


Expand Down Expand Up @@ -102,7 +104,7 @@ async def test_alarm_control_panel(
aioclient_mock: AiohttpClientMocker,
config_entry_setup: ConfigEntry,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
mock_deconz_websocket,
mock_websocket_data: WebsocketDataType,
) -> None:
"""Test successful creation of alarm control panel entities."""
assert len(hass.states.async_all()) == 4
Expand All @@ -117,7 +119,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": AncillaryControlPanel.ARMED_AWAY},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMED_AWAY
Expand All @@ -131,7 +133,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": AncillaryControlPanel.ARMED_NIGHT},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert (
Expand All @@ -147,7 +149,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": AncillaryControlPanel.ARMED_STAY},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMED_HOME
Expand All @@ -161,7 +163,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": AncillaryControlPanel.DISARMED},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_DISARMED
Expand All @@ -180,7 +182,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": arming_event},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_ARMING
Expand All @@ -198,7 +200,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": pending_event},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert (
Expand All @@ -214,7 +216,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": AncillaryControlPanel.IN_ALARM},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_TRIGGERED
Expand All @@ -228,7 +230,7 @@ async def test_alarm_control_panel(
"id": "0",
"state": {"panel": AncillaryControlPanel.NOT_READY},
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()

assert hass.states.get("alarm_control_panel.keypad").state == STATE_ALARM_TRIGGERED
Expand Down
19 changes: 11 additions & 8 deletions tests/components/deconz/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er

from .conftest import WebsocketDataType

TEST_DATA = [
( # Alarm binary sensor
{
Expand Down Expand Up @@ -458,7 +460,7 @@ async def test_binary_sensors(
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
config_entry_setup: ConfigEntry,
mock_deconz_websocket,
mock_websocket_data: WebsocketDataType,
expected: dict[str, Any],
) -> None:
"""Test successful creation of binary sensor entities."""
Expand Down Expand Up @@ -497,7 +499,7 @@ async def test_binary_sensors(
"id": "1",
"state": expected["websocket_event"],
}
await mock_deconz_websocket(data=event_changed_sensor)
await mock_websocket_data(event_changed_sensor)
await hass.async_block_till_done()
assert hass.states.get(expected["entity_id"]).state == expected["next_state"]

Expand Down Expand Up @@ -598,7 +600,8 @@ async def test_allow_clip_sensor(hass: HomeAssistant, config_entry_setup) -> Non

@pytest.mark.usefixtures("config_entry_setup")
async def test_add_new_binary_sensor(
hass: HomeAssistant, mock_deconz_websocket
hass: HomeAssistant,
mock_websocket_data: WebsocketDataType,
) -> None:
"""Test that adding a new binary sensor works."""
assert len(hass.states.async_all()) == 0
Expand All @@ -617,7 +620,7 @@ async def test_add_new_binary_sensor(
"uniqueid": "00:00:00:00:00:00:00:00-00",
},
}
await mock_deconz_websocket(data=event_added_sensor)
await mock_websocket_data(event_added_sensor)
await hass.async_block_till_done()

assert len(hass.states.async_all()) == 1
Expand All @@ -633,7 +636,7 @@ async def test_add_new_binary_sensor_ignored_load_entities_on_service_call(
config_entry_setup: ConfigEntry,
deconz_payload: dict[str, Any],
mock_requests: Callable[[str], None],
mock_deconz_websocket,
mock_websocket_data: WebsocketDataType,
) -> None:
"""Test that adding a new binary sensor is not allowed."""
sensor = {
Expand All @@ -653,7 +656,7 @@ async def test_add_new_binary_sensor_ignored_load_entities_on_service_call(

assert len(hass.states.async_all()) == 0

await mock_deconz_websocket(data=event_added_sensor)
await mock_websocket_data(event_added_sensor)
await hass.async_block_till_done()

assert len(hass.states.async_all()) == 0
Expand Down Expand Up @@ -687,7 +690,7 @@ async def test_add_new_binary_sensor_ignored_load_entities_on_options_change(
config_entry_setup: ConfigEntry,
deconz_payload: dict[str, Any],
mock_requests: Callable[[str], None],
mock_deconz_websocket,
mock_websocket_data: WebsocketDataType,
) -> None:
"""Test that adding a new binary sensor is not allowed."""
sensor = {
Expand All @@ -707,7 +710,7 @@ async def test_add_new_binary_sensor_ignored_load_entities_on_options_change(

assert len(hass.states.async_all()) == 0

await mock_deconz_websocket(data=event_added_sensor)
await mock_websocket_data(event_added_sensor)
await hass.async_block_till_done()

assert len(hass.states.async_all()) == 0
Expand Down
Loading

0 comments on commit 1b8944d

Please sign in to comment.