From 990d474d02cb6dad0d52d690398ce318c3abe9b2 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Mon, 13 Sep 2021 00:08:46 +0200 Subject: [PATCH] use fixtures. (#56130) --- tests/components/template/test_cover.py | 1427 +++++++++-------------- 1 file changed, 579 insertions(+), 848 deletions(-) diff --git a/tests/components/template/test_cover.py b/tests/components/template/test_cover.py index e2b65abcf25..0f629fdd239 100644 --- a/tests/components/template/test_cover.py +++ b/tests/components/template/test_cover.py @@ -23,25 +23,18 @@ from homeassistant.const import ( STATE_UNAVAILABLE, ) -from tests.common import assert_setup_component, async_mock_service +from tests.common import assert_setup_component ENTITY_COVER = "cover.test_template_cover" -@pytest.fixture(name="calls") -def calls_fixture(hass): - """Track calls to a mock service.""" - return async_mock_service(hass, "test", "automation") - - -async def test_template_state_text(hass, calls, caplog): - """Test the state text of a template.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config, states", + [ + ( { - "cover": { + DOMAIN: { "platform": "template", "covers": { "test_template_cover": { @@ -58,74 +51,42 @@ async def test_template_state_text(hass, calls, caplog): }, } }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - hass.states.async_set("cover.test_state", STATE_OPEN) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - - hass.states.async_set("cover.test_state", STATE_CLOSED) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSED - - hass.states.async_set("cover.test_state", STATE_OPENING) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPENING - - hass.states.async_set("cover.test_state", STATE_CLOSING) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSING - - # Unknown state sets position to None - "closing" takes precedence - state = hass.states.async_set("cover.test_state", "dog") - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSING - assert "Received invalid cover is_on state: dog" in caplog.text - - # Set state to open - hass.states.async_set("cover.test_state", STATE_OPEN) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - - # Unknown state sets position to None -> Open - state = hass.states.async_set("cover.test_state", "cat") - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - assert "Received invalid cover is_on state: cat" in caplog.text - - # Set state to closed - hass.states.async_set("cover.test_state", STATE_CLOSED) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSED - - # Unknown state sets position to None -> Open - state = hass.states.async_set("cover.test_state", "bear") - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - assert "Received invalid cover is_on state: bear" in caplog.text - - -async def test_template_state_text_combined(hass, calls, caplog): - """Test the state text of a template which combines position and value templates.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", + [ + ("cover.test_state", STATE_OPEN, STATE_OPEN, {}, -1, ""), + ("cover.test_state", STATE_CLOSED, STATE_CLOSED, {}, -1, ""), + ("cover.test_state", STATE_OPENING, STATE_OPENING, {}, -1, ""), + ("cover.test_state", STATE_CLOSING, STATE_CLOSING, {}, -1, ""), + ( + "cover.test_state", + "dog", + STATE_CLOSING, + {}, + -1, + "Received invalid cover is_on state: dog", + ), + ("cover.test_state", STATE_OPEN, STATE_OPEN, {}, -1, ""), + ( + "cover.test_state", + "cat", + STATE_OPEN, + {}, + -1, + "Received invalid cover is_on state: cat", + ), + ("cover.test_state", STATE_CLOSED, STATE_CLOSED, {}, -1, ""), + ( + "cover.test_state", + "bear", + STATE_OPEN, + {}, + -1, + "Received invalid cover is_on state: bear", + ), + ], + ), + ( { - "cover": { + DOMAIN: { "platform": "template", "covers": { "test_template_cover": { @@ -143,344 +104,256 @@ async def test_template_state_text_combined(hass, calls, caplog): }, } }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - # Test default state + [ + ("cover.test_state", STATE_OPEN, STATE_OPEN, {}, -1, ""), + ("cover.test_state", STATE_CLOSED, STATE_OPEN, {}, -1, ""), + ("cover.test_state", STATE_OPENING, STATE_OPENING, {}, -1, ""), + ("cover.test_state", STATE_CLOSING, STATE_CLOSING, {}, -1, ""), + ("cover.test", STATE_CLOSED, STATE_CLOSING, {"position": 0}, 0, ""), + ("cover.test_state", STATE_OPEN, STATE_CLOSED, {}, -1, ""), + ("cover.test", STATE_CLOSED, STATE_OPEN, {"position": 10}, 10, ""), + ( + "cover.test_state", + "dog", + STATE_OPEN, + {}, + -1, + "Received invalid cover is_on state: dog", + ), + ], + ), + ], +) +async def test_template_state_text(hass, states, start_ha, caplog): + """Test the state text of a template.""" state = hass.states.get("cover.test_template_cover") assert state.state == STATE_OPEN - # Change to "open" should be ignored - state = hass.states.async_set("cover.test_state", STATE_OPEN) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - - # Change to "closed" should be ignored - state = hass.states.async_set("cover.test_state", STATE_CLOSED) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - - # Change to "opening" should be accepted - state = hass.states.async_set("cover.test_state", STATE_OPENING) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPENING - - # Change to "closing" should be accepted - state = hass.states.async_set("cover.test_state", STATE_CLOSING) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSING - - # Set position to 0=closed - hass.states.async_set("cover.test", STATE_CLOSED, attributes={"position": 0}) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSING - assert state.attributes["current_position"] == 0 - - # Clear "closing" state, STATE_OPEN will be ignored and state derived from position - state = hass.states.async_set("cover.test_state", STATE_OPEN) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSED - - # Set position to 10 - hass.states.async_set("cover.test", STATE_CLOSED, attributes={"position": 10}) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - assert state.attributes["current_position"] == 10 - - # Unknown state should be ignored - state = hass.states.async_set("cover.test_state", "dog") - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - assert state.attributes["current_position"] == 10 - assert "Received invalid cover is_on state: dog" in caplog.text + for entity, set_state, test_state, attr, pos, text in states: + hass.states.async_set(entity, set_state, attributes=attr) + await hass.async_block_till_done() + state = hass.states.get("cover.test_template_cover") + assert state.state == test_state + if pos >= 0: + assert state.attributes.get("current_position") == pos + assert text in caplog.text -async def test_template_state_boolean(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, + } + }, + } + }, + ], +) +async def test_template_state_boolean(hass, start_ha): """Test the value_template attribute.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.state == STATE_OPEN -async def test_template_position(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, + } + }, + } + }, + ], +) +async def test_template_position(hass, start_ha): """Test the position_template attribute.""" hass.states.async_set("cover.test", STATE_OPEN) - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - state = hass.states.async_set("cover.test", STATE_CLOSED) - await hass.async_block_till_done() - - entity = hass.states.get("cover.test") attrs = {} - attrs["position"] = 42 - hass.states.async_set(entity.entity_id, entity.state, attributes=attrs) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_position") == 42.0 - assert state.state == STATE_OPEN - - state = hass.states.async_set("cover.test", STATE_OPEN) - await hass.async_block_till_done() - entity = hass.states.get("cover.test") - attrs["position"] = 0.0 - hass.states.async_set(entity.entity_id, entity.state, attributes=attrs) - await hass.async_block_till_done() - - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_position") == 0.0 - assert state.state == STATE_CLOSED + for set_state, pos, test_state in [ + (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) + await hass.async_block_till_done() + state = hass.states.get("cover.test_template_cover") + assert state.attributes.get("current_position") == pos + assert state.state == test_state -async def test_template_tilt(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, + } + }, + } + }, + ], +) +async def test_template_tilt(hass, start_ha): """Test the tilt_template attribute.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_tilt_position") == 42.0 -async def test_template_out_of_bounds(hass, calls): - """Test template out-of-bounds condition.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, + } + }, + } + }, + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - + }, + } + }, + ], +) +async def test_template_out_of_bounds(hass, start_ha): + """Test template out-of-bounds condition.""" state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_tilt_position") is None assert state.attributes.get("current_position") is None -async def test_template_open_or_position(hass, caplog): - """Test that at least one of open_cover or set_position is used.""" - assert await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(0, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ { - "cover": { + DOMAIN: { "platform": "template", "covers": {"test_template_cover": {"value_template": "{{ 1 == 1 }}"}}, } }, - ) - await hass.async_block_till_done() - + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "value_template": "{{ 1 == 1 }}", + "open_cover": { + "service": "cover.open_cover", + "entity_id": "cover.test_state", + }, + } + }, + } + }, + ], +) +async def test_template_open_or_position(hass, start_ha, caplog_setup_text): + """Test that at least one of open_cover or set_position is used.""" assert hass.states.async_all() == [] - assert "Invalid config for [cover.template]" in caplog.text + assert "Invalid config for [cover.template]" in caplog_setup_text -async def test_template_open_and_close(hass, calls): - """Test that if open_cover is specified, close_cover is too.""" - with assert_setup_component(0, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "value_template": "{{ 1 == 1 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - assert hass.states.async_all() == [] - - -async def test_template_non_numeric(hass, calls): - """Test that tilt_template values are numeric.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_tilt_position") is None - assert state.attributes.get("current_position") is None - - -async def test_open_action(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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): """Test the open_cover command.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "position_template": "{{ 0 }}", - "open_cover": {"service": "test.automation"}, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.state == STATE_CLOSED @@ -492,34 +365,30 @@ async def test_open_action(hass, calls): assert len(calls) == 1 -async def test_close_stop_action(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "position_template": "{{ 100 }}", + "open_cover": { + "service": "cover.open_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): """Test the close-cover and stop_cover commands.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "position_template": "{{ 100 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": {"service": "test.automation"}, - "stop_cover": {"service": "test.automation"}, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.state == STATE_OPEN @@ -536,14 +405,16 @@ async def test_close_stop_action(hass, calls): assert len(calls) == 2 -async def test_set_position(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, "input_number")]) +@pytest.mark.parametrize( + "config", + [ + {"input_number": {"test": {"min": "0", "max": "100", "initial": "42"}}}, + ], +) +async def test_set_position(hass, start_ha, calls): """Test the set_position command.""" with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "input_number", - {"input_number": {"test": {"min": "0", "max": "100", "initial": "42"}}}, - ) assert await setup.async_setup_component( hass, "cover", @@ -612,41 +483,48 @@ async def test_set_position(hass, calls): assert state.attributes.get("current_position") == 25.0 -async def test_set_tilt_position(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "position_template": "{{ 100 }}", + "open_cover": { + "service": "cover.open_cover", + "entity_id": "cover.test_state", + }, + "close_cover": { + "service": "cover.close_cover", + "entity_id": "cover.test_state", + }, + "set_cover_tilt_position": {"service": "test.automation"}, + } + }, + } + }, + ], +) +@pytest.mark.parametrize( + "service,attr", + [ + ( + SERVICE_SET_COVER_TILT_POSITION, + {ATTR_ENTITY_ID: ENTITY_COVER, ATTR_TILT_POSITION: 42}, + ), + (SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}), + (SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}), + ], +) +async def test_set_tilt_position(hass, service, attr, start_ha, calls): """Test the set_tilt_position command.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "position_template": "{{ 100 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, - "set_cover_tilt_position": {"service": "test.automation"}, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - await hass.services.async_call( DOMAIN, - SERVICE_SET_COVER_TILT_POSITION, - {ATTR_ENTITY_ID: ENTITY_COVER, ATTR_TILT_POSITION: 42}, + service, + attr, blocking=True, ) await hass.async_block_till_done() @@ -654,105 +532,24 @@ async def test_set_tilt_position(hass, calls): assert len(calls) == 1 -async def test_open_tilt_action(hass, calls): - """Test the open_cover_tilt command.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "position_template": "{{ 100 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, - "set_cover_tilt_position": {"service": "test.automation"}, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - await hass.services.async_call( - DOMAIN, SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - - assert len(calls) == 1 - - -async def test_close_tilt_action(hass, calls): - """Test the close_cover_tilt command.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "position_template": "{{ 100 }}", - "open_cover": { - "service": "cover.open_cover", - "entity_id": "cover.test_state", - }, - "close_cover": { - "service": "cover.close_cover", - "entity_id": "cover.test_state", - }, - "set_cover_tilt_position": {"service": "test.automation"}, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - - await hass.services.async_call( - DOMAIN, SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - - assert len(calls) == 1 - - -async def test_set_position_optimistic(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "set_cover_position": {"service": "test.automation"} + } + }, + } + }, + ], +) +async def test_set_position_optimistic(hass, start_ha, calls): """Test optimistic position mode.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "set_cover_position": {"service": "test.automation"} - } - }, - } - }, - ) - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") is None @@ -766,58 +563,40 @@ async def test_set_position_optimistic(hass, calls): state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_position") == 42.0 - await hass.services.async_call( - DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSED - - await hass.services.async_call( - DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - - await hass.services.async_call( - DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_CLOSED - - await hass.services.async_call( - DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.state == STATE_OPEN - - -async def test_set_tilt_position_optimistic(hass, calls): - """Test the optimistic tilt_position mode.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "position_template": "{{ 100 }}", - "set_cover_position": {"service": "test.automation"}, - "set_cover_tilt_position": {"service": "test.automation"}, - } - }, - } - }, + for service, test_state in [ + (SERVICE_CLOSE_COVER, STATE_CLOSED), + (SERVICE_OPEN_COVER, STATE_OPEN), + (SERVICE_TOGGLE, STATE_CLOSED), + (SERVICE_TOGGLE, STATE_OPEN), + ]: + await hass.services.async_call( + DOMAIN, service, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True ) - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() + await hass.async_block_till_done() + state = hass.states.get("cover.test_template_cover") + assert state.state == test_state + +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "position_template": "{{ 100 }}", + "set_cover_position": {"service": "test.automation"}, + "set_cover_tilt_position": {"service": "test.automation"}, + } + }, + } + }, + ], +) +async def test_set_tilt_position_optimistic(hass, start_ha, calls): + """Test the optimistic tilt_position mode.""" state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_tilt_position") is None @@ -831,68 +610,49 @@ async def test_set_tilt_position_optimistic(hass, calls): state = hass.states.get("cover.test_template_cover") assert state.attributes.get("current_tilt_position") == 42.0 - await hass.services.async_call( - DOMAIN, SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_tilt_position") == 0.0 - - await hass.services.async_call( - DOMAIN, SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_tilt_position") == 100.0 - - await hass.services.async_call( - DOMAIN, SERVICE_TOGGLE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_tilt_position") == 0.0 - - await hass.services.async_call( - DOMAIN, SERVICE_TOGGLE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True - ) - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") - assert state.attributes.get("current_tilt_position") == 100.0 - - -async def test_icon_template(hass, calls): - """Test icon template.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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 %}", - } - }, - } - }, + for service, pos in [ + (SERVICE_CLOSE_COVER_TILT, 0.0), + (SERVICE_OPEN_COVER_TILT, 100.0), + (SERVICE_TOGGLE_COVER_TILT, 0.0), + (SERVICE_TOGGLE_COVER_TILT, 100.0), + ]: + await hass.services.async_call( + DOMAIN, service, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True ) + await hass.async_block_till_done() + state = hass.states.get("cover.test_template_cover") + assert state.attributes.get("current_tilt_position") == pos - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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 %}", + } + }, + } + }, + ], +) +async def test_icon_template(hass, start_ha): + """Test icon template.""" state = hass.states.get("cover.test_template_cover") assert state.attributes.get("icon") == "" @@ -904,39 +664,35 @@ async def test_icon_template(hass, calls): assert state.attributes["icon"] == "mdi:check" -async def test_entity_picture_template(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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 %}", + } + }, + } + }, + ], +) +async def test_entity_picture_template(hass, start_ha): """Test icon template.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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 %}", - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.attributes.get("entity_picture") == "" @@ -948,37 +704,33 @@ async def test_entity_picture_template(hass, calls): assert state.attributes["entity_picture"] == "/local/cover.png" -async def test_availability_template(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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') }}", + } + }, + } + }, + ], +) +async def test_availability_template(hass, start_ha): """Test availability template.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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') }}", - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - hass.states.async_set("availability_state.state", STATE_OFF) await hass.async_block_till_done() @@ -990,13 +742,12 @@ async def test_availability_template(hass, calls): assert hass.states.get("cover.test_template_cover").state != STATE_UNAVAILABLE -async def test_availability_without_availability_template(hass, calls): - """Test that component is available if there is no.""" - assert await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ { - "cover": { + DOMAIN: { "platform": "template", "covers": { "test_template_cover": { @@ -1013,23 +764,20 @@ async def test_availability_without_availability_template(hass, calls): }, } }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - + ], +) +async def test_availability_without_availability_template(hass, start_ha): + """Test that component is available if there is no.""" state = hass.states.get("cover.test_template_cover") assert state.state != STATE_UNAVAILABLE -async def test_invalid_availability_template_keeps_component_available(hass, caplog): - """Test that an invalid availability keeps the device available.""" - assert await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ { - "cover": { + DOMAIN: { "platform": "template", "covers": { "test_template_cover": { @@ -1047,93 +795,84 @@ async def test_invalid_availability_template_keeps_component_available(hass, cap }, } }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - + ], +) +async def test_invalid_availability_template_keeps_component_available( + hass, start_ha, caplog_setup_text +): + """Test that an invalid availability keeps the device available.""" assert hass.states.get("cover.test_template_cover") != STATE_UNAVAILABLE - assert ("UndefinedError: 'x' is undefined") in caplog.text + assert ("UndefinedError: 'x' is undefined") in caplog_setup_text -async def test_device_class(hass, calls): +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, + } + }, + } + }, + ], +) +async def test_device_class(hass, start_ha): """Test device class.""" - with assert_setup_component(1, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert state.attributes.get("device_class") == "door" -async def test_invalid_device_class(hass, calls): +@pytest.mark.parametrize("count,domain", [(0, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ + { + DOMAIN: { + "platform": "template", + "covers": { + "test_template_cover": { + "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", + }, + } + }, + } + }, + ], +) +async def test_invalid_device_class(hass, start_ha): """Test device class.""" - with assert_setup_component(0, "cover"): - assert await setup.async_setup_component( - hass, - "cover", - { - "cover": { - "platform": "template", - "covers": { - "test_template_cover": { - "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", - }, - } - }, - } - }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - state = hass.states.get("cover.test_template_cover") assert not state -async def test_unique_id(hass): - """Test unique_id option only creates one cover per id.""" - await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ { - "cover": { + DOMAIN: { "platform": "template", "covers": { "test_template_cover_01": { @@ -1161,27 +900,21 @@ async def test_unique_id(hass): }, }, }, - }, + } }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - + ], +) +async def test_unique_id(hass, start_ha): + """Test unique_id option only creates one cover per id.""" assert len(hass.states.async_all()) == 1 -async def test_state_gets_lowercased(hass): - """Test True/False is lowercased.""" - - hass.states.async_set("binary_sensor.garage_door_sensor", "off") - - await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ { - "cover": { + DOMAIN: { "platform": "template", "covers": { "garage_door": { @@ -1197,12 +930,14 @@ async def test_state_gets_lowercased(hass): }, }, }, - }, + } }, - ) + ], +) +async def test_state_gets_lowercased(hass, start_ha): + """Test True/False is lowercased.""" - await hass.async_block_till_done() - await hass.async_start() + hass.states.async_set("binary_sensor.garage_door_sensor", "off") await hass.async_block_till_done() assert len(hass.states.async_all()) == 2 @@ -1213,24 +948,20 @@ async def test_state_gets_lowercased(hass): assert hass.states.get("cover.garage_door").state == STATE_CLOSED -async def test_self_referencing_icon_with_no_template_is_not_a_loop(hass, caplog): - """Test a self referencing icon with no value template is not a loop.""" - - icon_template_str = """{% if is_state('cover.office', 'open') %} - mdi:window-shutter-open - {% else %} - mdi:window-shutter - {% endif %}""" - - await setup.async_setup_component( - hass, - "cover", +@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) +@pytest.mark.parametrize( + "config", + [ { - "cover": { + DOMAIN: { "platform": "template", "covers": { "office": { - "icon_template": icon_template_str, + "icon_template": """{% if is_state('cover.office', 'open') %} + mdi:window-shutter-open + {% else %} + mdi:window-shutter + {% endif %}""", "open_cover": { "service": "switch.turn_on", "entity_id": "switch.office_blinds_up", @@ -1247,12 +978,12 @@ async def test_self_referencing_icon_with_no_template_is_not_a_loop(hass, caplog }, } }, - ) - - await hass.async_block_till_done() - await hass.async_start() - await hass.async_block_till_done() - + ], +) +async def test_self_referencing_icon_with_no_template_is_not_a_loop( + hass, start_ha, caplog +): + """Test a self referencing icon with no value template is not a loop.""" assert len(hass.states.async_all()) == 1 assert "Template loop detected" not in caplog.text