First step towards fixtures in deCONZ tests (#120863)

* config entry fixture

* Mock web request

* Make siren tests use new fixtures

* Replace old constants

* Add mock put request

* Change comment
This commit is contained in:
Robert Svensson 2024-07-01 12:33:51 +02:00 committed by GitHub
parent f08638eead
commit 44640ef9e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 201 additions and 25 deletions

View File

@ -2,12 +2,191 @@
from __future__ import annotations
from collections.abc import Callable
from types import MappingProxyType
from typing import Any
from unittest.mock import patch
from pydeconz.websocket import Signal
import pytest
from homeassistant.components.deconz.const import DOMAIN as DECONZ_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT, CONTENT_TYPE_JSON
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
from tests.components.light.conftest import mock_light_profiles # noqa: F401
from tests.test_util.aiohttp import AiohttpClientMocker
# Config entry fixtures
API_KEY = "1234567890ABCDEF"
BRIDGEID = "01234E56789A"
HOST = "1.2.3.4"
PORT = 80
@pytest.fixture(name="config_entry")
def fixture_config_entry(
hass: HomeAssistant,
config_entry_data: MappingProxyType[str, Any],
config_entry_options: MappingProxyType[str, Any],
) -> ConfigEntry:
"""Define a config entry fixture."""
config_entry = MockConfigEntry(
domain=DECONZ_DOMAIN,
entry_id="1",
unique_id=BRIDGEID,
data=config_entry_data,
options=config_entry_options,
)
config_entry.add_to_hass(hass)
return config_entry
@pytest.fixture(name="config_entry_data")
def fixture_config_entry_data() -> MappingProxyType[str, Any]:
"""Define a config entry data fixture."""
return {
CONF_API_KEY: API_KEY,
CONF_HOST: HOST,
CONF_PORT: PORT,
}
@pytest.fixture(name="config_entry_options")
def fixture_config_entry_options() -> MappingProxyType[str, Any]:
"""Define a config entry options fixture."""
return {}
# Request mocks
@pytest.fixture(name="mock_put_request")
def fixture_put_request(
aioclient_mock: AiohttpClientMocker, config_entry_data: MappingProxyType[str, Any]
) -> Callable[[str, str], AiohttpClientMocker]:
"""Mock a deCONZ put request."""
_host = config_entry_data[CONF_HOST]
_port = config_entry_data[CONF_PORT]
_api_key = config_entry_data[CONF_API_KEY]
def __mock_requests(path: str, host: str = "") -> AiohttpClientMocker:
url = f"http://{host or _host}:{_port}/api/{_api_key}{path}"
aioclient_mock.put(url, json={}, headers={"content-type": CONTENT_TYPE_JSON})
return aioclient_mock
return __mock_requests
@pytest.fixture(name="mock_requests")
def fixture_get_request(
aioclient_mock: AiohttpClientMocker,
config_entry_data: MappingProxyType[str, Any],
deconz_payload: dict[str, Any],
) -> Callable[[str], None]:
"""Mock default deCONZ requests responses."""
_host = config_entry_data[CONF_HOST]
_port = config_entry_data[CONF_PORT]
_api_key = config_entry_data[CONF_API_KEY]
def __mock_requests(host: str = "") -> None:
url = f"http://{host or _host}:{_port}/api/{_api_key}"
aioclient_mock.get(
url, json=deconz_payload, headers={"content-type": CONTENT_TYPE_JSON}
)
return __mock_requests
# Request payload fixtures
@pytest.fixture(name="deconz_payload")
def fixture_data(
alarm_system_payload: dict[str, Any],
config_payload: dict[str, Any],
group_payload: dict[str, Any],
light_payload: dict[str, Any],
sensor_payload: dict[str, Any],
) -> dict[str, Any]:
"""DeCONZ data."""
return {
"alarmsystems": alarm_system_payload,
"config": config_payload,
"groups": group_payload,
"lights": light_payload,
"sensors": sensor_payload,
}
@pytest.fixture(name="alarm_system_payload")
def fixture_alarm_system_data() -> dict[str, Any]:
"""Alarm system data."""
return {}
@pytest.fixture(name="config_payload")
def fixture_config_data() -> dict[str, Any]:
"""Config data."""
return {
"bridgeid": BRIDGEID,
"ipaddress": HOST,
"mac": "00:11:22:33:44:55",
"modelid": "deCONZ",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"uuid": "1234",
"websocketport": 1234,
}
@pytest.fixture(name="group_payload")
def fixture_group_data() -> dict[str, Any]:
"""Group data."""
return {}
@pytest.fixture(name="light_payload")
def fixture_light_data() -> dict[str, Any]:
"""Light data."""
return {}
@pytest.fixture(name="sensor_payload")
def fixture_sensor_data() -> dict[str, Any]:
"""Sensor data."""
return {}
@pytest.fixture(name="config_entry_factory")
async def fixture_config_entry_factory(
hass: HomeAssistant,
config_entry: ConfigEntry,
mock_requests: Callable[[str, str], None],
) -> Callable[[], ConfigEntry]:
"""Fixture factory that can set up UniFi network integration."""
async def __mock_setup_config_entry() -> ConfigEntry:
mock_requests(config_entry.data[CONF_HOST])
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry
return __mock_setup_config_entry
@pytest.fixture(name="config_entry_setup")
async def fixture_config_entry_setup(
hass: HomeAssistant, config_entry_factory: Callable[[], ConfigEntry]
) -> ConfigEntry:
"""Fixture providing a set up instance of deCONZ integration."""
return await config_entry_factory()
# Websocket fixtures
@pytest.fixture(autouse=True)

View File

@ -47,14 +47,11 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.typing import UNDEFINED, UndefinedType
from .conftest import API_KEY, BRIDGEID, HOST, PORT
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
API_KEY = "1234567890ABCDEF"
BRIDGEID = "01234E56789A"
HOST = "1.2.3.4"
PORT = 80
DEFAULT_URL = f"http://{HOST}:{PORT}/api/{API_KEY}"
ENTRY_CONFIG = {CONF_API_KEY: API_KEY, CONF_HOST: HOST, CONF_PORT: PORT}

View File

@ -1,8 +1,11 @@
"""deCONZ switch platform tests."""
from unittest.mock import patch
from collections.abc import Callable
import pytest
from homeassistant.components.siren import ATTR_DURATION, DOMAIN as SIREN_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
@ -13,21 +16,13 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from .test_gateway import (
DECONZ_WEB_REQUEST,
mock_deconz_put_request,
setup_deconz_integration,
)
from tests.test_util.aiohttp import AiohttpClientMocker
async def test_sirens(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_deconz_websocket
) -> None:
"""Test that siren entities are created."""
data = {
"lights": {
@pytest.mark.parametrize(
"light_payload",
[
{
"1": {
"name": "Warning device",
"type": "Warning device",
@ -41,10 +36,15 @@ async def test_sirens(
"uniqueid": "00:00:00:00:00:00:00:01-00",
},
}
}
with patch.dict(DECONZ_WEB_REQUEST, data):
config_entry = await setup_deconz_integration(hass, aioclient_mock)
],
)
async def test_sirens(
hass: HomeAssistant,
config_entry_setup: ConfigEntry,
mock_deconz_websocket,
mock_put_request: Callable[[str, str], AiohttpClientMocker],
) -> None:
"""Test that siren entities are created."""
assert len(hass.states.async_all()) == 2
assert hass.states.get("siren.warning_device").state == STATE_ON
assert not hass.states.get("siren.unsupported_siren")
@ -63,7 +63,7 @@ async def test_sirens(
# Verify service calls
mock_deconz_put_request(aioclient_mock, config_entry.data, "/lights/1/state")
aioclient_mock = mock_put_request("/lights/1/state")
# Service turn on siren
@ -95,13 +95,13 @@ async def test_sirens(
)
assert aioclient_mock.mock_calls[3][2] == {"alert": "lselect", "ontime": 100}
await hass.config_entries.async_unload(config_entry.entry_id)
await hass.config_entries.async_unload(config_entry_setup.entry_id)
states = hass.states.async_all()
assert len(states) == 2
for state in states:
assert state.state == STATE_UNAVAILABLE
await hass.config_entries.async_remove(config_entry.entry_id)
await hass.config_entries.async_remove(config_entry_setup.entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0