Coverage for tests/tests/test_apis_binding.py: 0%
39 statements
« prev ^ index » next coverage.py v7.11.3, created at 2026-01-05 21:46 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2026-01-05 21:46 +0100
1#!/usr/bin/env python3
2"""RAMSES RF - Test the wait_for_binding_request, initiate_binding_process APIs."""
4import unittest.mock
5from types import SimpleNamespace
6from typing import TypeVar
8import pytest
10from ramses_rf.database import MessageIndex
11from ramses_rf.device.base import Fakeable # initiate_binding_, wait_for_binding_
12from ramses_rf.device.heat import DhwSensor, Thermostat # initiate_binding_process
13from ramses_rf.device.hvac import ( # initiate_binding_process
14 HvacCarbonDioxideSensor,
15 HvacDisplayRemote,
16 HvacRemote,
17)
18from ramses_tx.address import Address
19from ramses_tx.const import Code
21_FakeableDeviceT = TypeVar("_FakeableDeviceT", bound=Fakeable)
24# ### TEST SUITE ######################################################################
25ADDR_CLASS_LOOKUP: dict[str, type[Fakeable]] = {
26 "07:123456": DhwSensor,
27 "03:123456": Thermostat,
28 # "09:123456": OutSensor,
29 "31:123456": HvacCarbonDioxideSensor,
30 "32:123456": HvacDisplayRemote,
31 "33:123456": HvacRemote,
32}
33ADDR_CLASS_MAP = {v: k for k, v in ADDR_CLASS_LOOKUP.items()}
35CLASS_CODES_MAP: dict[type[Fakeable], Code | tuple[Code, ...]] = {
36 DhwSensor: Code._1260,
37 Thermostat: (Code._2309, Code._30C9, Code._0008),
38 HvacCarbonDioxideSensor: (Code._31E0, Code._1298, Code._2E10),
39 HvacRemote: (Code._22F1, Code._22F3),
40}
43class GatewayStub:
44 config = SimpleNamespace(**{"disable_discovery": True})
46 device_by_id: dict[str, Fakeable] = {}
47 devices: list[Fakeable] = []
49 _include: dict[str] = {}
50 msg_db = MessageIndex(maintain=False)
52 def _add_device(self, dev: Fakeable) -> None:
53 self.device_by_id[dev.id] = dev
54 self.devices.append(dev)
57# ### FIXTURES ########################################################################
60def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
61 def id_fnc(dev_class: type[Fakeable]) -> str:
62 return dev_class._SLUG
64 metafunc.parametrize("dev_class", ADDR_CLASS_MAP.keys(), ids=id_fnc)
67# ### TESTS ###########################################################################
70async def test_initiate_binding_process(dev_class: type[Fakeable]) -> None:
71 assert issubclass(dev_class, Fakeable)
73 gwy = GatewayStub()
74 dev_addr = Address(ADDR_CLASS_MAP[dev_class])
76 with unittest.mock.patch.object(
77 Fakeable, "_initiate_binding_process", return_value=None
78 ) as mocked_method:
79 gwy._include[dev_addr.id] = {} # this shouldn't be needed? a BUG?
81 dev = dev_class(gwy, dev_addr)
82 dev._make_fake()
84 _ = await dev.initiate_binding_process()
86 if codes := CLASS_CODES_MAP.get(dev_class):
87 mocked_method.assert_called_once_with(codes)
88 else:
89 mocked_method.assert_called_once()