Skip to content

Commit

Permalink
add scaffolding for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
raman325 committed Jan 30, 2024
1 parent 05f18b3 commit bdba1a4
Show file tree
Hide file tree
Showing 10 changed files with 5,806 additions and 1 deletion.
3 changes: 2 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Fixtures for lock_code_manager tests."""

import pytest

pytest_plugins = "pytest_homeassistant_custom_component"
pytest_plugins = ["pytest_homeassistant_custom_component"]


@pytest.fixture(autouse=True)
Expand Down
12 changes: 12 additions & 0 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Helpers for lock_code_manager tests."""

from functools import lru_cache
from pathlib import Path
import traceback


@lru_cache
def load_fixture(path_from_fixtures_folder: str) -> str:
"""Load a fixture."""
parent_path = Path(traceback.extract_stack()[-2].filename).parent
return (parent_path / "fixtures" / path_from_fixtures_folder).read_text()
1 change: 1 addition & 0 deletions tests/zwave_js/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Z-Wave JS lock tests."""
186 changes: 186 additions & 0 deletions tests/zwave_js/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
"""Fixtures for lock_code_manager tests."""

import asyncio
import copy
import json
from unittest.mock import DEFAULT, AsyncMock, patch

import pytest
from zwave_js_server.model.driver import Driver
from zwave_js_server.model.node import Node
from zwave_js_server.version import VersionInfo

from homeassistant.core import HomeAssistant

from pytest_homeassistant_custom_component.common import MockConfigEntry

from tests.helpers import load_fixture


# Z-Wave JS fixtures


@pytest.fixture(name="controller_state", scope="session")
def controller_state_fixture():
"""Load the controller state fixture data."""
return json.loads(load_fixture("controller_state.json"))


@pytest.fixture(name="controller_node_state", scope="session")
def controller_node_state_fixture():
"""Load the controller node state fixture data."""
return json.loads(load_fixture("controller_node_state.json"))


@pytest.fixture(name="version_state", scope="session")
def version_state_fixture():
"""Load the version state fixture data."""
return {
"type": "version",
"driverVersion": "6.0.0-beta.0",
"serverVersion": "1.0.0",
"homeId": 1234567890,
}


@pytest.fixture(name="log_config_state")
def log_config_state_fixture():
"""Return log config state fixture data."""
return {
"enabled": True,
"level": "info",
"logToFile": False,
"filename": "",
"forceConsole": False,
}


@pytest.fixture(name="lock_schlage_be469_state", scope="session")
def lock_schlage_be469_state_fixture():
"""Load the schlage lock node state fixture data."""
return json.loads(
load_fixture("lock_schlage_be469_state.json")
)


@pytest.fixture(name="lock_august_asl03_state", scope="session")
def lock_august_asl03_state_fixture():
"""Load the August Pro lock node state fixture data."""
return json.loads(
load_fixture("lock_august_asl03_state.json")
)


@pytest.fixture(name="lock_id_lock_as_id150_state", scope="session")
def lock_id_lock_as_id150_state_fixture():
"""Load the id lock id-150 lock node state fixture data."""
return json.loads(
load_fixture("/lock_id_lock_as_id150_state.json")
)


# model fixtures


@pytest.fixture(name="listen_block")
def mock_listen_block_fixture():
"""Mock a listen block."""
return asyncio.Event()


@pytest.fixture(name="client")
def mock_client_fixture(
controller_state,
controller_node_state,
version_state,
log_config_state,
listen_block,
):
"""Mock a client."""
with patch(
"homeassistant.components.zwave_js.ZwaveClient", autospec=True
) as client_class:
client = client_class.return_value

async def connect():
await asyncio.sleep(0)
client.connected = True

async def listen(driver_ready: asyncio.Event) -> None:
driver_ready.set()
await listen_block.wait()

async def disconnect():
client.connected = False

client.connect = AsyncMock(side_effect=connect)
client.listen = AsyncMock(side_effect=listen)
client.disconnect = AsyncMock(side_effect=disconnect)
client.driver = Driver(
client, copy.deepcopy(controller_state), copy.deepcopy(log_config_state)
)
node = Node(client, copy.deepcopy(controller_node_state))
client.driver.controller.nodes[node.node_id] = node

client.version = VersionInfo.from_message(version_state)
client.ws_server_url = "ws://test:3000/zjs"

async def async_send_command_side_effect(message, require_schema=None):
"""Return the command response."""
if message["command"] == "node.has_device_config_changed":
return {"changed": False}
return DEFAULT

client.async_send_command.return_value = {
"result": {"success": True, "status": 255}
}
client.async_send_command.side_effect = async_send_command_side_effect

yield client


@pytest.fixture(name="lock_schlage_be469")
def lock_schlage_be469_fixture(client, lock_schlage_be469_state):
"""Mock a schlage lock node."""
node = Node(client, copy.deepcopy(lock_schlage_be469_state))
client.driver.controller.nodes[node.node_id] = node
return node


@pytest.fixture(name="lock_august_pro")
def lock_august_asl03_fixture(client, lock_august_asl03_state):
"""Mock a August Pro lock node."""
node = Node(client, copy.deepcopy(lock_august_asl03_state))
client.driver.controller.nodes[node.node_id] = node
return node


@pytest.fixture(name="lock_id_lock_as_id150")
def lock_id_lock_as_id150(client, lock_id_lock_as_id150_state):
"""Mock an id lock id-150 lock node."""
node = Node(client, copy.deepcopy(lock_id_lock_as_id150_state))
client.driver.controller.nodes[node.node_id] = node
return node


@pytest.fixture(name="integration")
async def integration_fixture(hass: HomeAssistant, client):
"""Set up the zwave_js integration."""
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()

client.async_send_command.reset_mock()

return entry


@pytest.fixture(name="lock_id_lock_as_id150_not_ready")
def node_not_ready(client, lock_id_lock_as_id150_state):
"""Mock an id lock id-150 lock node that's not ready."""
state = copy.deepcopy(lock_id_lock_as_id150_state)
state["ready"] = False
node = Node(client, state)
client.driver.controller.nodes[node.node_id] = node
return node
104 changes: 104 additions & 0 deletions tests/zwave_js/fixtures/controller_node_state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"nodeId": 1,
"index": 0,
"status": 4,
"ready": true,
"isListening": true,
"isRouting": false,
"isSecure": "unknown",
"manufacturerId": 134,
"productId": 90,
"productType": 1,
"firmwareVersion": "1.2",
"deviceConfig": {
"filename": "/data/db/devices/0x0086/zw090.json",
"isEmbedded": true,
"manufacturer": "AEON Labs",
"manufacturerId": 134,
"label": "ZW090",
"description": "Z\u2010Stick Gen5 USB Controller",
"devices": [
{
"productType": 1,
"productId": 90
},
{
"productType": 257,
"productId": 90
},
{
"productType": 513,
"productId": 90
}
],
"firmwareVersion": {
"min": "0.0",
"max": "255.255"
},
"associations": {},
"paramInformation": {
"_map": {}
},
"metadata": {
"reset": "Use this procedure only in the event that the primary controller is missing or otherwise inoperable.\n\nPress and hold the Action Button on Z-Stick for 20 seconds and then release",
"manual": "https://products.z-wavealliance.org/ProductManual/File?folder=&filename=MarketCertificationFiles/1345/Z%20Stick%20Gen5%20manual%201.pdf"
}
},
"label": "ZW090",
"interviewAttempts": 0,
"endpoints": [
{
"nodeId": 1,
"index": 0,
"deviceClass": {
"basic": {
"key": 2,
"label": "Static Controller"
},
"generic": {
"key": 2,
"label": "Static Controller"
},
"specific": {
"key": 1,
"label": "PC Controller"
},
"mandatorySupportedCCs": [],
"mandatoryControlledCCs": [32]
},
"commandClasses": []
}
],
"values": [],
"isFrequentListening": false,
"maxDataRate": 40000,
"supportedDataRates": [40000],
"protocolVersion": 3,
"deviceClass": {
"basic": {
"key": 2,
"label": "Static Controller"
},
"generic": {
"key": 2,
"label": "Static Controller"
},
"specific": {
"key": 1,
"label": "PC Controller"
},
"mandatorySupportedCCs": [],
"mandatoryControlledCCs": [32]
},
"interviewStage": "Complete",
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0086:0x0001:0x005a:1.2",
"statistics": {
"commandsTX": 0,
"commandsRX": 0,
"commandsDroppedRX": 0,
"commandsDroppedTX": 0,
"timeoutResponse": 0
},
"isControllerNode": true,
"keepAwake": false
}
31 changes: 31 additions & 0 deletions tests/zwave_js/fixtures/controller_state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"controller": {
"libraryVersion": "Z-Wave 3.95",
"type": 1,
"homeId": 3245146787,
"ownNodeId": 1,
"isSecondary": false,
"isUsingHomeIdFromOtherNetwork": false,
"isSISPresent": true,
"wasRealPrimary": true,
"isStaticUpdateController": true,
"isSlave": false,
"serialApiVersion": "1.0",
"manufacturerId": 134,
"productType": 257,
"productId": 90,
"supportedFunctionTypes": [
2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 28, 32, 33,
34, 35, 36, 39, 41, 42, 43, 44, 45, 65, 66, 68, 69, 70, 71, 72, 73, 74,
75, 76, 77, 80, 81, 83, 84, 85, 86, 87, 94, 96, 97, 98, 99, 102, 103, 128,
144, 146, 147, 152, 180, 182, 183, 184, 185, 186, 189, 190, 191, 210, 211,
212, 238, 239
],
"sucNodeId": 1,
"supportsTimers": false,
"isHealNetworkActive": false,
"inclusionState": 0,
"status": 0
},
"nodes": []
}
Loading

0 comments on commit bdba1a4

Please sign in to comment.