From 1ef3800844236a389df93c481b4e5724becf4c2f Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 12 May 2022 15:22:57 +0200 Subject: [PATCH] Tweak template cover tests (#71732) --- tests/components/template/test_cover.py | 269 +++++++++--------------- 1 file changed, 98 insertions(+), 171 deletions(-) diff --git a/tests/components/template/test_cover.py b/tests/components/template/test_cover.py index b4bc00ee6a2..92842dc5bfe 100644 --- a/tests/components/template/test_cover.py +++ b/tests/components/template/test_cover.py @@ -4,7 +4,10 @@ import pytest from homeassistant import setup from homeassistant.components.cover import ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN from homeassistant.const import ( + ATTR_DOMAIN, ATTR_ENTITY_ID, + ATTR_SERVICE_DATA, + EVENT_CALL_SERVICE, SERVICE_CLOSE_COVER, SERVICE_CLOSE_COVER_TILT, SERVICE_OPEN_COVER, @@ -22,12 +25,45 @@ from homeassistant.const import ( STATE_OPENING, STATE_UNAVAILABLE, ) +from homeassistant.core import callback from tests.common import assert_setup_component ENTITY_COVER = "cover.test_template_cover" +@pytest.fixture +def service_calls(hass): + """Track service call events for cover.test_state.""" + events = [] + entity_id = "cover.test_state" + + @callback + def capture_events(event): + print(event.data) + if event.data[ATTR_DOMAIN] != DOMAIN: + return + if event.data[ATTR_SERVICE_DATA][ATTR_ENTITY_ID] != [entity_id]: + return + events.append(event) + + hass.bus.async_listen(EVENT_CALL_SERVICE, capture_events) + + return events + + +OPEN_CLOSE_COVER_CONFIG = { + "open_cover": { + "service": "cover.open_cover", + "entity_id": "cover.test_state", + }, + "close_cover": { + "service": "cover.close_cover", + "entity_id": "cover.test_state", + }, +} + + @pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @pytest.mark.parametrize( "config, states", @@ -38,15 +74,8 @@ ENTITY_COVER = "cover.test_template_cover" "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ states.cover.test_state.state }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -90,16 +119,9 @@ ENTITY_COVER = "cover.test_template_cover" "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "position_template": "{{ states.cover.test.attributes.position }}", "value_template": "{{ states.cover.test_state.state }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -148,15 +170,8 @@ async def test_template_state_text(hass, states, start_ha, caplog): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ 1 == 1 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -178,15 +193,8 @@ async def test_template_state_boolean(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "position_template": "{{ states.cover.test.attributes.position }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test", - }, } }, } @@ -202,11 +210,8 @@ async def test_template_position(hass, start_ha): (STATE_CLOSED, 42, STATE_OPEN), (STATE_OPEN, 0.0, STATE_CLOSED), ]: - state = hass.states.async_set("cover.test", set_state) - await hass.async_block_till_done() - entity = hass.states.get("cover.test") attrs["position"] = pos - hass.states.async_set(entity.entity_id, entity.state, attributes=attrs) + hass.states.async_set("cover.test", set_state, attributes=attrs) await hass.async_block_till_done() state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == pos @@ -222,16 +227,9 @@ async def test_template_position(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ 1 == 1 }}", "tilt_template": "{{ 42 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -253,16 +251,9 @@ async def test_template_tilt(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "position_template": "{{ -1 }}", "tilt_template": "{{ 110 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -272,20 +263,13 @@ async def test_template_tilt(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "position_template": "{{ on }}", "tilt_template": "{% if states.cover.test_state.state %}" "on" "{% else %}" "off" "{% endif %}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, }, }, } @@ -340,19 +324,15 @@ async def test_template_open_or_position(hass, start_ha, caplog_setup_text): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "position_template": "{{ 0 }}", - "open_cover": {"service": "test.automation"}, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } }, ], ) -async def test_open_action(hass, start_ha, calls): +async def test_open_action(hass, start_ha, service_calls): """Test the open_cover command.""" state = hass.states.get("cover.test_template_cover") assert state.state == STATE_CLOSED @@ -362,7 +342,8 @@ async def test_open_action(hass, start_ha, calls): ) await hass.async_block_till_done() - assert len(calls) == 1 + assert len(service_calls) == 1 + assert service_calls[0].data["service"] == "open_cover" @pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @@ -374,20 +355,19 @@ async def test_open_action(hass, start_ha, calls): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "position_template": "{{ 100 }}", - "open_cover": { - "service": "cover.open_cover", + "stop_cover": { + "service": "cover.stop_cover", "entity_id": "cover.test_state", }, - "close_cover": {"service": "test.automation"}, - "stop_cover": {"service": "test.automation"}, } }, } }, ], ) -async def test_close_stop_action(hass, start_ha, calls): +async def test_close_stop_action(hass, start_ha, service_calls): """Test the close-cover and stop_cover commands.""" state = hass.states.get("cover.test_template_cover") assert state.state == STATE_OPEN @@ -402,7 +382,9 @@ async def test_close_stop_action(hass, start_ha, calls): ) await hass.async_block_till_done() - assert len(calls) == 2 + assert len(service_calls) == 2 + assert service_calls[0].data["service"] == "close_cover" + assert service_calls[1].data["service"] == "stop_cover" @pytest.mark.parametrize("count,domain", [(1, "input_number")]) @@ -412,7 +394,7 @@ async def test_close_stop_action(hass, start_ha, calls): {"input_number": {"test": {"min": "0", "max": "100", "initial": "42"}}}, ], ) -async def test_set_position(hass, start_ha, calls): +async def test_set_position(hass, start_ha, service_calls): """Test the set_position command.""" with assert_setup_component(1, "cover"): assert await setup.async_setup_component( @@ -423,11 +405,10 @@ async def test_set_position(hass, start_ha, calls): "platform": "template", "covers": { "test_template_cover": { - "position_template": "{{ states.input_number.test.state | int }}", "set_cover_position": { - "service": "input_number.set_value", - "entity_id": "input_number.test", - "data_template": {"value": "{{ position }}"}, + "service": "cover.set_cover_position", + "entity_id": "cover.test_state", + "data_template": {"position": "{{ position }}"}, }, } }, @@ -450,6 +431,9 @@ async def test_set_position(hass, start_ha, calls): await hass.async_block_till_done() state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == 100.0 + assert len(service_calls) == 1 + assert service_calls[-1].data["service"] == "set_cover_position" + assert service_calls[-1].data["service_data"]["position"] == 100 await hass.services.async_call( DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True @@ -457,6 +441,9 @@ async def test_set_position(hass, start_ha, calls): await hass.async_block_till_done() state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == 0.0 + assert len(service_calls) == 2 + assert service_calls[-1].data["service"] == "set_cover_position" + assert service_calls[-1].data["service_data"]["position"] == 0 await hass.services.async_call( DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True @@ -464,6 +451,9 @@ async def test_set_position(hass, start_ha, calls): await hass.async_block_till_done() state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == 100.0 + assert len(service_calls) == 3 + assert service_calls[-1].data["service"] == "set_cover_position" + assert service_calls[-1].data["service_data"]["position"] == 100 await hass.services.async_call( DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True @@ -471,6 +461,9 @@ async def test_set_position(hass, start_ha, calls): await hass.async_block_till_done() state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == 0.0 + assert len(service_calls) == 4 + assert service_calls[-1].data["service"] == "set_cover_position" + assert service_calls[-1].data["service_data"]["position"] == 0 await hass.services.async_call( DOMAIN, @@ -481,6 +474,9 @@ async def test_set_position(hass, start_ha, calls): await hass.async_block_till_done() state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == 25.0 + assert len(service_calls) == 5 + assert service_calls[-1].data["service"] == "set_cover_position" + assert service_calls[-1].data["service_data"]["position"] == 25 @pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @@ -492,16 +488,12 @@ async def test_set_position(hass, start_ha, calls): "platform": "template", "covers": { "test_template_cover": { - "position_template": "{{ 100 }}", - "open_cover": { - "service": "cover.open_cover", + **OPEN_CLOSE_COVER_CONFIG, + "set_cover_tilt_position": { + "service": "cover.set_cover_tilt_position", "entity_id": "cover.test_state", + "data_template": {"tilt_position": "{{ tilt }}"}, }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, - "set_cover_tilt_position": {"service": "test.automation"}, } }, } @@ -509,17 +501,20 @@ async def test_set_position(hass, start_ha, calls): ], ) @pytest.mark.parametrize( - "service,attr", + "service,attr,tilt_position", [ ( SERVICE_SET_COVER_TILT_POSITION, {ATTR_ENTITY_ID: ENTITY_COVER, ATTR_TILT_POSITION: 42}, + 42, ), - (SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}), - (SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}), + (SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, 100), + (SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, 0), ], ) -async def test_set_tilt_position(hass, service, attr, start_ha, calls): +async def test_set_tilt_position( + hass, service, attr, start_ha, service_calls, tilt_position +): """Test the set_tilt_position command.""" await hass.services.async_call( DOMAIN, @@ -529,7 +524,9 @@ async def test_set_tilt_position(hass, service, attr, start_ha, calls): ) await hass.async_block_till_done() - assert len(calls) == 1 + assert len(service_calls) == 1 + assert service_calls[-1].data["service"] == "set_cover_tilt_position" + assert service_calls[-1].data["service_data"]["tilt_position"] == tilt_position @pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @@ -633,15 +630,8 @@ async def test_set_tilt_position_optimistic(hass, start_ha, calls): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ states.cover.test_state.state }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, "icon_template": "{% if states.cover.test_state.state %}" "mdi:check" "{% endif %}", @@ -673,15 +663,8 @@ async def test_icon_template(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ states.cover.test_state.state }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, "entity_picture_template": "{% if states.cover.test_state.state %}" "/local/cover.png" "{% endif %}", @@ -713,15 +696,8 @@ async def test_entity_picture_template(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "open", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, "availability_template": "{{ is_state('availability_state.state','on') }}", } }, @@ -751,15 +727,8 @@ async def test_availability_template(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "open", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -781,16 +750,9 @@ async def test_availability_without_availability_template(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "availability_template": "{{ x - 12 }}", "value_template": "open", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -814,16 +776,9 @@ async def test_invalid_availability_template_keeps_component_available( "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ states.cover.test_state.state }}", "device_class": "door", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -845,16 +800,9 @@ async def test_device_class(hass, start_ha): "platform": "template", "covers": { "test_template_cover": { + **OPEN_CLOSE_COVER_CONFIG, "value_template": "{{ states.cover.test_state.state }}", "device_class": "barnacle_bill", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, } }, } @@ -876,28 +824,14 @@ async def test_invalid_device_class(hass, start_ha): "platform": "template", "covers": { "test_template_cover_01": { + **OPEN_CLOSE_COVER_CONFIG, "unique_id": "not-so-unique-anymore", "value_template": "{{ true }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, }, "test_template_cover_02": { + **OPEN_CLOSE_COVER_CONFIG, "unique_id": "not-so-unique-anymore", "value_template": "{{ false }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, }, }, } @@ -918,16 +852,9 @@ async def test_unique_id(hass, start_ha): "platform": "template", "covers": { "garage_door": { + **OPEN_CLOSE_COVER_CONFIG, "friendly_name": "Garage Door", "value_template": "{{ is_state('binary_sensor.garage_door_sensor', 'off') }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, }, }, }