mirror of https://github.com/home-assistant/core
Add zwave_js init module tests (#45048)
* Add entry setup and unload test * Test home assistant stop * Test on connect and on disconnect * Test client connect timeout * Test ready node added * Test non ready node added * Test existing node not ready * Test device registry state * Add common test tools module * Add existing ready node test * Include init module in coverage calculation * Clean docstrings
This commit is contained in:
parent
d60fc0de38
commit
d270f9515b
|
@ -1092,7 +1092,6 @@ omit =
|
|||
homeassistant/components/zoneminder/*
|
||||
homeassistant/components/supla/*
|
||||
homeassistant/components/zwave/util.py
|
||||
homeassistant/components/zwave_js/__init__.py
|
||||
homeassistant/components/zwave_js/discovery.py
|
||||
homeassistant/components/zwave_js/entity.py
|
||||
homeassistant/components/zwave_js/light.py
|
||||
|
|
|
@ -18,6 +18,7 @@ from .const import DATA_CLIENT, DATA_UNSUBSCRIBE, DOMAIN, PLATFORMS
|
|||
from .discovery import async_discover_values
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
CONNECT_TIMEOUT = 10
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
|
||||
|
@ -113,7 +114,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
# connect and throw error if connection failed
|
||||
asyncio.create_task(client.connect())
|
||||
try:
|
||||
async with timeout(10):
|
||||
async with timeout(CONNECT_TIMEOUT):
|
||||
await initialized.wait()
|
||||
except asyncio.TimeoutError as err:
|
||||
for unsub in unsubs:
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
"""Provide common test tools for Z-Wave JS."""
|
||||
AIR_TEMPERATURE_SENSOR = "sensor.multisensor_6_air_temperature"
|
|
@ -1,14 +1,24 @@
|
|||
"""Provide common Z-Wave JS fixtures."""
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import DEFAULT, patch
|
||||
|
||||
import pytest
|
||||
from zwave_js_server.model.driver import Driver
|
||||
from zwave_js_server.model.node import Node
|
||||
|
||||
from homeassistant.helpers.device_registry import (
|
||||
async_get_registry as async_get_device_registry,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
||||
|
||||
@pytest.fixture(name="device_registry")
|
||||
async def device_registry_fixture(hass):
|
||||
"""Return the device registry."""
|
||||
return await async_get_device_registry(hass)
|
||||
|
||||
|
||||
@pytest.fixture(name="controller_state", scope="session")
|
||||
def controller_state_fixture():
|
||||
"""Load the controller state fixture data."""
|
||||
|
@ -49,6 +59,7 @@ async def integration_fixture(hass, client):
|
|||
def initialize_client(async_on_initialized):
|
||||
"""Init the client."""
|
||||
hass.async_create_task(async_on_initialized())
|
||||
return DEFAULT
|
||||
|
||||
client.register_on_initialized.side_effect = initialize_client
|
||||
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
"""Test the Z-Wave JS init module."""
|
||||
from copy import deepcopy
|
||||
from unittest.mock import DEFAULT, patch
|
||||
|
||||
import pytest
|
||||
from zwave_js_server.model.node import Node
|
||||
|
||||
from homeassistant.components.zwave_js.const import DOMAIN
|
||||
from homeassistant.config_entries import (
|
||||
ENTRY_STATE_LOADED,
|
||||
ENTRY_STATE_NOT_LOADED,
|
||||
ENTRY_STATE_SETUP_RETRY,
|
||||
)
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
|
||||
from .common import AIR_TEMPERATURE_SENSOR
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture(name="connect_timeout")
|
||||
def connect_timeout_fixture():
|
||||
"""Mock the connect timeout."""
|
||||
with patch("homeassistant.components.zwave_js.CONNECT_TIMEOUT", new=0) as timeout:
|
||||
yield timeout
|
||||
|
||||
|
||||
async def test_entry_setup_unload(hass, client, integration):
|
||||
"""Test the integration set up and unload."""
|
||||
entry = integration
|
||||
|
||||
assert client.connect.call_count == 1
|
||||
assert client.register_on_initialized.call_count == 1
|
||||
assert client.register_on_disconnect.call_count == 1
|
||||
assert client.register_on_connect.call_count == 1
|
||||
assert entry.state == ENTRY_STATE_LOADED
|
||||
|
||||
await hass.config_entries.async_unload(entry.entry_id)
|
||||
|
||||
assert client.disconnect.call_count == 1
|
||||
assert client.register_on_initialized.return_value.call_count == 1
|
||||
assert client.register_on_disconnect.return_value.call_count == 1
|
||||
assert client.register_on_connect.return_value.call_count == 1
|
||||
assert entry.state == ENTRY_STATE_NOT_LOADED
|
||||
|
||||
|
||||
async def test_home_assistant_stop(hass, client, integration):
|
||||
"""Test we clean up on home assistant stop."""
|
||||
await hass.async_stop()
|
||||
|
||||
assert client.disconnect.call_count == 1
|
||||
|
||||
|
||||
async def test_on_connect_disconnect(hass, client, multisensor_6, integration):
|
||||
"""Test we handle disconnect and reconnect."""
|
||||
on_connect = client.register_on_connect.call_args[0][0]
|
||||
on_disconnect = client.register_on_disconnect.call_args[0][0]
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
|
||||
client.connected = False
|
||||
|
||||
await on_disconnect()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
client.connected = True
|
||||
|
||||
await on_connect()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_initialized_timeout(hass, client, connect_timeout):
|
||||
"""Test we handle a timeout during client initialization."""
|
||||
entry = MockConfigEntry(domain="zwave_js", data={"url": "ws://test.org"})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == ENTRY_STATE_SETUP_RETRY
|
||||
|
||||
|
||||
async def test_on_node_added_ready(
|
||||
hass, multisensor_6_state, client, integration, device_registry
|
||||
):
|
||||
"""Test we handle a ready node added event."""
|
||||
node = Node(client, multisensor_6_state)
|
||||
event = {"node": node}
|
||||
air_temperature_device_id = f"{client.driver.controller.home_id}-{node.node_id}"
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert not state # entity and device not yet added
|
||||
assert not device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
||||
|
||||
client.driver.controller.emit("node added", event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state # entity and device added
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
||||
|
||||
|
||||
async def test_on_node_added_not_ready(
|
||||
hass, multisensor_6_state, client, integration, device_registry
|
||||
):
|
||||
"""Test we handle a non ready node added event."""
|
||||
node_data = deepcopy(multisensor_6_state) # Copy to allow modification in tests.
|
||||
node = Node(client, node_data)
|
||||
node.data["ready"] = False
|
||||
event = {"node": node}
|
||||
air_temperature_device_id = f"{client.driver.controller.home_id}-{node.node_id}"
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert not state # entity and device not yet added
|
||||
assert not device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
||||
|
||||
client.driver.controller.emit("node added", event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert not state # entity not yet added but device added in registry
|
||||
assert device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
||||
|
||||
node.data["ready"] = True
|
||||
node.emit("ready", event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state # entity added
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_existing_node_ready(
|
||||
hass, client, multisensor_6, integration, device_registry
|
||||
):
|
||||
"""Test we handle a ready node that exists during integration setup."""
|
||||
node = multisensor_6
|
||||
air_temperature_device_id = f"{client.driver.controller.home_id}-{node.node_id}"
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state # entity and device added
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
||||
|
||||
|
||||
async def test_existing_node_not_ready(hass, client, multisensor_6, device_registry):
|
||||
"""Test we handle a non ready node that exists during integration setup."""
|
||||
node = multisensor_6
|
||||
node.data = deepcopy(node.data) # Copy to allow modification in tests.
|
||||
node.data["ready"] = False
|
||||
event = {"node": node}
|
||||
air_temperature_device_id = f"{client.driver.controller.home_id}-{node.node_id}"
|
||||
entry = MockConfigEntry(domain="zwave_js", data={"url": "ws://test.org"})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
def initialize_client(async_on_initialized):
|
||||
"""Init the client."""
|
||||
hass.async_create_task(async_on_initialized())
|
||||
return DEFAULT
|
||||
|
||||
client.register_on_initialized.side_effect = initialize_client
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert not state # entity and device not yet added
|
||||
assert not device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
||||
|
||||
node.data["ready"] = True
|
||||
node.emit("ready", event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(AIR_TEMPERATURE_SENSOR)
|
||||
|
||||
assert state # entity and device added
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, air_temperature_device_id)}
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
"""Test the Z-Wave JS sensor platform."""
|
||||
from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS
|
||||
|
||||
AIR_TEMPERATURE_SENSOR = "sensor.multisensor_6_air_temperature"
|
||||
from .common import AIR_TEMPERATURE_SENSOR
|
||||
|
||||
|
||||
async def test_numeric_sensor(hass, multisensor_6, integration):
|
||||
|
|
Loading…
Reference in New Issue