All tests ok
This commit is contained in:
@@ -228,8 +228,8 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
self._on_time_sec = 0
|
self._on_time_sec = 0
|
||||||
self._off_time_sec = 0
|
self._off_time_sec = 0
|
||||||
self._keep_alive = IntervalCaller(hass, keep_alive_sec)
|
self._keep_alive = IntervalCaller(hass, keep_alive_sec)
|
||||||
self._vswitch_on = vswitch_on
|
self._vswitch_on = vswitch_on.strip() if vswitch_on else None
|
||||||
self._vswitch_off = vswitch_off
|
self._vswitch_off = vswitch_off.strip() if vswitch_off else None
|
||||||
self._domain = self._entity_id.split(".")[0]
|
self._domain = self._entity_id.split(".")[0]
|
||||||
# build command
|
# build command
|
||||||
command, data, state_on = self.build_command(use_on=True)
|
command, data, state_on = self.build_command(use_on=True)
|
||||||
@@ -312,9 +312,10 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
|
|
||||||
value = None
|
value = None
|
||||||
data = {ATTR_ENTITY_ID: self._entity_id}
|
data = {ATTR_ENTITY_ID: self._entity_id}
|
||||||
vswitch = self._vswitch_on if use_on and not self.is_inversed else self._vswitch_off
|
take_on = (use_on and not self.is_inversed) or (not use_on and self.is_inversed)
|
||||||
|
vswitch = self._vswitch_on if take_on else self._vswitch_off
|
||||||
if vswitch:
|
if vswitch:
|
||||||
pattern = r"^(?P<command>[^/]+)(?:/(?P<argument>[^:]+)(?::(?P<value>.*))?)?$"
|
pattern = r"^(?P<command>[^\s/]+)(?:/(?P<argument>[^\s:]+)(?::(?P<value>[^\s]+))?)?$"
|
||||||
match = re.match(pattern, vswitch)
|
match = re.match(pattern, vswitch)
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
@@ -322,13 +323,16 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
command = match.group("command")
|
command = match.group("command")
|
||||||
argument = match.group("argument")
|
argument = match.group("argument")
|
||||||
value = match.group("value")
|
value = match.group("value")
|
||||||
data.update({argument: value})
|
if argument is not None and value is not None:
|
||||||
|
data.update({argument: value})
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Invalid input format: {vswitch}")
|
raise ValueError(f"Invalid input format: {vswitch}. Must be conform to 'command[/argument[:value]]'")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
command = SERVICE_TURN_ON if use_on and not self.is_inversed else SERVICE_TURN_OFF
|
command = SERVICE_TURN_ON if use_on and not self.is_inversed else SERVICE_TURN_OFF
|
||||||
value = STATE_ON if use_on and not self.is_inversed else STATE_OFF
|
|
||||||
|
if value is None:
|
||||||
|
value = STATE_ON if take_on else STATE_OFF
|
||||||
|
|
||||||
return command, data, value
|
return command, data, value
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,68 @@ from custom_components.versatile_thermostat.thermostat_switch import ThermostatO
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"is_inversed, vswitch_on_command, vswitch_off_command, expected_command_on, expected_data_on, expected_state_on, expected_command_off, expected_data_off, expected_state_off",
|
"is_inversed, vswitch_on_command, vswitch_off_command, expected_command_on, expected_data_on, expected_state_on, expected_command_off, expected_data_off, expected_state_off, is_ok",
|
||||||
[
|
[
|
||||||
# Select
|
# Select (with stripping - trim)
|
||||||
(
|
(
|
||||||
False,
|
False,
|
||||||
|
" select_option/option:comfort ",
|
||||||
|
" select_option/option:frost ",
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "comfort"},
|
||||||
|
PRESET_COMFORT,
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "frost"},
|
||||||
|
PRESET_FROST_PROTECTION,
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# Inversed Select
|
||||||
|
(
|
||||||
|
True,
|
||||||
"select_option/option:comfort",
|
"select_option/option:comfort",
|
||||||
|
"select_option/option:eco",
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "eco"},
|
||||||
|
PRESET_ECO,
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "comfort"},
|
||||||
|
PRESET_COMFORT,
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# switch
|
||||||
|
(False, "turn_on", "turn_off", "turn_on", {"entity_id": "switch.test"}, STATE_ON, "turn_off", {"entity_id": "switch.test"}, STATE_OFF, True),
|
||||||
|
# inversed switch
|
||||||
|
(True, "turn_on", "turn_off", "turn_off", {"entity_id": "switch.test"}, STATE_OFF, "turn_on", {"entity_id": "switch.test"}, STATE_ON, True),
|
||||||
|
# Climate
|
||||||
|
(
|
||||||
|
False,
|
||||||
|
"set_hvac_mode/hvac_mode:heat",
|
||||||
|
"set_hvac_mode/hvac_mode:off",
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": "switch.test", "hvac_mode": "heat"},
|
||||||
|
HVACMode.HEAT,
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": "switch.test", "hvac_mode": "off"},
|
||||||
|
HVACMode.OFF,
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# Inversed Climate
|
||||||
|
(
|
||||||
|
True,
|
||||||
|
"set_hvac_mode/hvac_mode:heat",
|
||||||
|
"set_hvac_mode/hvac_mode:off",
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": "switch.test", "hvac_mode": "off"},
|
||||||
|
HVACMode.OFF,
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": "switch.test", "hvac_mode": "heat"},
|
||||||
|
HVACMode.HEAT,
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# Error cases invalid command
|
||||||
|
(
|
||||||
|
False,
|
||||||
|
"select_ option/option:comfort", # whitespace
|
||||||
"select_option/option:frost",
|
"select_option/option:frost",
|
||||||
"select_option",
|
"select_option",
|
||||||
{"entity_id": "switch.test", "option": "comfort"},
|
{"entity_id": "switch.test", "option": "comfort"},
|
||||||
@@ -26,12 +82,35 @@ from custom_components.versatile_thermostat.thermostat_switch import ThermostatO
|
|||||||
"select_option",
|
"select_option",
|
||||||
{"entity_id": "switch.test", "option": "frost"},
|
{"entity_id": "switch.test", "option": "frost"},
|
||||||
PRESET_FROST_PROTECTION,
|
PRESET_FROST_PROTECTION,
|
||||||
|
False,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
False,
|
||||||
|
"select_option/option comfort", # whitespace
|
||||||
|
"select_option/option:frost",
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "comfort"},
|
||||||
|
PRESET_COMFORT,
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "frost"},
|
||||||
|
PRESET_FROST_PROTECTION,
|
||||||
|
False,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
False,
|
||||||
|
"select_option/option:com fort", # whitespace
|
||||||
|
"select_option/option:frost",
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "comfort"},
|
||||||
|
PRESET_COMFORT,
|
||||||
|
"select_option",
|
||||||
|
{"entity_id": "switch.test", "option": "frost"},
|
||||||
|
PRESET_FROST_PROTECTION,
|
||||||
|
False,
|
||||||
),
|
),
|
||||||
# switch
|
|
||||||
(False, "turn_on/:on", "turn_off/:off", "turn_on", {"entity_id": "switch.test", None: None}, STATE_ON, "turn_off", {"entity_id": "switch.test", None: None}, STATE_OFF),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_build_command(
|
async def test_build_command(
|
||||||
hass,
|
hass,
|
||||||
is_inversed,
|
is_inversed,
|
||||||
vswitch_on_command,
|
vswitch_on_command,
|
||||||
@@ -42,6 +121,7 @@ def test_build_command(
|
|||||||
expected_command_off,
|
expected_command_off,
|
||||||
expected_data_off,
|
expected_data_off,
|
||||||
expected_state_off,
|
expected_state_off,
|
||||||
|
is_ok,
|
||||||
):
|
):
|
||||||
"""Test the initialisation of a UnderlyingSwitch with some personnalisations commands"""
|
"""Test the initialisation of a UnderlyingSwitch with some personnalisations commands"""
|
||||||
|
|
||||||
@@ -49,7 +129,18 @@ def test_build_command(
|
|||||||
type(vtherm).is_inversed = PropertyMock(return_value=is_inversed)
|
type(vtherm).is_inversed = PropertyMock(return_value=is_inversed)
|
||||||
|
|
||||||
assert vtherm.is_inversed == is_inversed
|
assert vtherm.is_inversed == is_inversed
|
||||||
under = UnderlyingSwitch(hass, vtherm, "switch.test", 0, 0, vswitch_on_command, vswitch_off_command)
|
|
||||||
|
try:
|
||||||
|
under = UnderlyingSwitch(hass, vtherm, "switch.test", 0, 0, vswitch_on_command, vswitch_off_command)
|
||||||
|
except ValueError as e:
|
||||||
|
if is_ok:
|
||||||
|
pytest.fail(f"Initialization failed with ValueError: {e}")
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not is_ok:
|
||||||
|
pytest.fail("There should be a ValueError")
|
||||||
|
return
|
||||||
|
|
||||||
assert under.is_inversed == is_inversed
|
assert under.is_inversed == is_inversed
|
||||||
|
|
||||||
@@ -60,3 +151,18 @@ def test_build_command(
|
|||||||
assert under._off_command.get("command") == expected_command_off
|
assert under._off_command.get("command") == expected_command_off
|
||||||
assert under._off_command.get("data") == expected_data_off
|
assert under._off_command.get("data") == expected_data_off
|
||||||
assert under._off_command.get("state") == expected_state_off
|
assert under._off_command.get("state") == expected_state_off
|
||||||
|
|
||||||
|
# Calling turn-on
|
||||||
|
# fmt: off
|
||||||
|
with patch.object(under, "check_overpowering", return_value=True), \
|
||||||
|
patch("homeassistant.core.ServiceRegistry.async_call") as mock_service_call:
|
||||||
|
#fmt: on
|
||||||
|
await under.turn_on()
|
||||||
|
mock_service_call.assert_called_once_with("switch", expected_command_on, expected_data_on)
|
||||||
|
|
||||||
|
# Calling turn-off
|
||||||
|
#fmt: off
|
||||||
|
with patch("homeassistant.core.ServiceRegistry.async_call") as mock_service_call:
|
||||||
|
#fmt: on
|
||||||
|
await under.turn_off()
|
||||||
|
mock_service_call.assert_called_once_with("switch", expected_command_off, expected_data_off)
|
||||||
|
|||||||
Reference in New Issue
Block a user