From 91042e3e46d333651ae26af9c64e3baea3ac411a Mon Sep 17 00:00:00 2001 From: sycx2 Date: Fri, 16 Oct 2020 13:25:57 +0200 Subject: [PATCH] Improve template test lock (#41195) Co-authored-by: Paulus Schoutsen --- tests/components/template/test_lock.py | 581 ++++++++++++------------- 1 file changed, 287 insertions(+), 294 deletions(-) diff --git a/tests/components/template/test_lock.py b/tests/components/template/test_lock.py index db1be64c379..f054a67cbbc 100644 --- a/tests/components/template/test_lock.py +++ b/tests/components/template/test_lock.py @@ -1,280 +1,38 @@ """The tests for the Template lock platform.""" import logging +import pytest + from homeassistant import setup from homeassistant.components import lock from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNAVAILABLE -from homeassistant.core import callback -from tests.common import assert_setup_component, get_test_home_assistant +from tests.common import assert_setup_component, async_mock_service _LOGGER = logging.getLogger(__name__) -class TestTemplateLock: - """Test the Template lock.""" +@pytest.fixture +def calls(hass): + """Track calls to a mock service.""" + return async_mock_service(hass, "test", "automation") - hass = None - calls = None - # pylint: disable=invalid-name - def setup_method(self, method): - """Set up things to be run when tests are started.""" - self.hass = get_test_home_assistant() - self.calls = [] - - @callback - def record_call(service): - """Track function calls.""" - self.calls.append(service) - - self.hass.services.register("test", "automation", record_call) - - def teardown_method(self, method): - """Stop everything that was started.""" - self.hass.stop() - - def test_template_state(self): - """Test template.""" - with assert_setup_component(1, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "lock": { - "platform": "template", - "name": "Test template lock", - "value_template": "{{ states.switch.test_state.state }}", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - self.hass.states.set("switch.test_state", STATE_ON) - self.hass.block_till_done() - - state = self.hass.states.get("lock.test_template_lock") - assert state.state == lock.STATE_LOCKED - - self.hass.states.set("switch.test_state", STATE_OFF) - self.hass.block_till_done() - - state = self.hass.states.get("lock.test_template_lock") - assert state.state == lock.STATE_UNLOCKED - - def test_template_state_boolean_on(self): - """Test the setting of the state with boolean on.""" - with assert_setup_component(1, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "lock": { - "platform": "template", - "value_template": "{{ 1 == 1 }}", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - state = self.hass.states.get("lock.template_lock") - assert state.state == lock.STATE_LOCKED - - def test_template_state_boolean_off(self): - """Test the setting of the state with off.""" - with assert_setup_component(1, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "lock": { - "platform": "template", - "value_template": "{{ 1 == 2 }}", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - state = self.hass.states.get("lock.template_lock") - assert state.state == lock.STATE_UNLOCKED - - def test_template_syntax_error(self): - """Test templating syntax error.""" - with assert_setup_component(0, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "lock": { - "platform": "template", - "value_template": "{% if rubbish %}", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - assert self.hass.states.all() == [] - - def test_invalid_name_does_not_create(self): - """Test invalid name.""" - with assert_setup_component(0, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "switch": { - "platform": "lock", - "name": "{{%}", - "value_template": "{{ rubbish }", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - assert self.hass.states.all() == [] - - def test_invalid_lock_does_not_create(self): - """Test invalid lock.""" - with assert_setup_component(0, "lock"): - assert setup.setup_component( - self.hass, - "lock", - {"lock": {"platform": "template", "value_template": "Invalid"}}, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - assert self.hass.states.all() == [] - - def test_missing_template_does_not_create(self): - """Test missing template.""" - with assert_setup_component(0, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "lock": { - "platform": "template", - "not_value_template": "{{ states.switch.test_state.state }}", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - assert self.hass.states.all() == [] - - def test_template_static(self, caplog): - """Test that we allow static templates.""" - with assert_setup_component(1, "lock"): - assert setup.setup_component( - self.hass, - "lock", - { - "lock": { - "platform": "template", - "value_template": "{{ 1 + 1 }}", - "lock": { - "service": "switch.turn_on", - "entity_id": "switch.test_state", - }, - "unlock": { - "service": "switch.turn_off", - "entity_id": "switch.test_state", - }, - } - }, - ) - - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() - - state = self.hass.states.get("lock.template_lock") - assert state.state == lock.STATE_UNLOCKED - - self.hass.states.set("lock.template_lock", lock.STATE_LOCKED) - self.hass.block_till_done() - state = self.hass.states.get("lock.template_lock") - assert state.state == lock.STATE_LOCKED - - def test_lock_action(self): - """Test lock action.""" - assert setup.setup_component( - self.hass, - "lock", +async def test_template_state(hass): + """Test template.""" + with assert_setup_component(1, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, { "lock": { "platform": "template", + "name": "Test template lock", "value_template": "{{ states.switch.test_state.state }}", - "lock": {"service": "test.automation"}, + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, "unlock": { "service": "switch.turn_off", "entity_id": "switch.test_state", @@ -283,57 +41,292 @@ class TestTemplateLock: }, ) - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() - self.hass.states.set("switch.test_state", STATE_OFF) - self.hass.block_till_done() + hass.states.async_set("switch.test_state", STATE_ON) + await hass.async_block_till_done() - state = self.hass.states.get("lock.template_lock") - assert state.state == lock.STATE_UNLOCKED + state = hass.states.get("lock.test_template_lock") + assert state.state == lock.STATE_LOCKED - self.hass.services.call( - lock.DOMAIN, lock.SERVICE_LOCK, {ATTR_ENTITY_ID: "lock.template_lock"} - ) - self.hass.block_till_done() + hass.states.async_set("switch.test_state", STATE_OFF) + await hass.async_block_till_done() - assert len(self.calls) == 1 + state = hass.states.get("lock.test_template_lock") + assert state.state == lock.STATE_UNLOCKED - def test_unlock_action(self): - """Test unlock action.""" - assert setup.setup_component( - self.hass, - "lock", + +async def test_template_state_boolean_on(hass): + """Test the setting of the state with boolean on.""" + with assert_setup_component(1, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, { "lock": { "platform": "template", - "value_template": "{{ states.switch.test_state.state }}", + "value_template": "{{ 1 == 1 }}", "lock": { "service": "switch.turn_on", "entity_id": "switch.test_state", }, - "unlock": {"service": "test.automation"}, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.test_state", + }, } }, ) - self.hass.block_till_done() - self.hass.start() - self.hass.block_till_done() + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() - self.hass.states.set("switch.test_state", STATE_ON) - self.hass.block_till_done() + state = hass.states.get("lock.template_lock") + assert state.state == lock.STATE_LOCKED - state = self.hass.states.get("lock.template_lock") - assert state.state == lock.STATE_LOCKED - self.hass.services.call( - lock.DOMAIN, lock.SERVICE_UNLOCK, {ATTR_ENTITY_ID: "lock.template_lock"} +async def test_template_state_boolean_off(hass): + """Test the setting of the state with off.""" + with assert_setup_component(1, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "lock": { + "platform": "template", + "value_template": "{{ 1 == 2 }}", + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.test_state", + }, + } + }, ) - self.hass.block_till_done() - assert len(self.calls) == 1 + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() + + state = hass.states.get("lock.template_lock") + assert state.state == lock.STATE_UNLOCKED + + +async def test_template_syntax_error(hass): + """Test templating syntax error.""" + with assert_setup_component(0, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "lock": { + "platform": "template", + "value_template": "{% if rubbish %}", + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.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_invalid_name_does_not_create(hass): + """Test invalid name.""" + with assert_setup_component(0, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "switch": { + "platform": "lock", + "name": "{{%}", + "value_template": "{{ rubbish }", + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.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_invalid_lock_does_not_create(hass): + """Test invalid lock.""" + with assert_setup_component(0, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + {"lock": {"platform": "template", "value_template": "Invalid"}}, + ) + + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() + + assert hass.states.async_all() == [] + + +async def test_missing_template_does_not_create(hass): + """Test missing template.""" + with assert_setup_component(0, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "lock": { + "platform": "template", + "not_value_template": "{{ states.switch.test_state.state }}", + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.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_static(hass, caplog): + """Test that we allow static templates.""" + with assert_setup_component(1, lock.DOMAIN): + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "lock": { + "platform": "template", + "value_template": "{{ 1 + 1 }}", + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.test_state", + }, + } + }, + ) + + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() + + state = hass.states.get("lock.template_lock") + assert state.state == lock.STATE_UNLOCKED + + hass.states.async_set("lock.template_lock", lock.STATE_LOCKED) + await hass.async_block_till_done() + state = hass.states.get("lock.template_lock") + assert state.state == lock.STATE_LOCKED + + +async def test_lock_action(hass, calls): + """Test lock action.""" + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "lock": { + "platform": "template", + "value_template": "{{ states.switch.test_state.state }}", + "lock": {"service": "test.automation"}, + "unlock": { + "service": "switch.turn_off", + "entity_id": "switch.test_state", + }, + } + }, + ) + + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() + + hass.states.async_set("switch.test_state", STATE_OFF) + await hass.async_block_till_done() + + state = hass.states.get("lock.template_lock") + assert state.state == lock.STATE_UNLOCKED + + await hass.services.async_call( + lock.DOMAIN, lock.SERVICE_LOCK, {ATTR_ENTITY_ID: "lock.template_lock"} + ) + await hass.async_block_till_done() + + assert len(calls) == 1 + + +async def test_unlock_action(hass, calls): + """Test unlock action.""" + assert await setup.async_setup_component( + hass, + lock.DOMAIN, + { + "lock": { + "platform": "template", + "value_template": "{{ states.switch.test_state.state }}", + "lock": { + "service": "switch.turn_on", + "entity_id": "switch.test_state", + }, + "unlock": {"service": "test.automation"}, + } + }, + ) + + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() + + hass.states.async_set("switch.test_state", STATE_ON) + await hass.async_block_till_done() + + state = hass.states.get("lock.template_lock") + assert state.state == lock.STATE_LOCKED + + await hass.services.async_call( + lock.DOMAIN, lock.SERVICE_UNLOCK, {ATTR_ENTITY_ID: "lock.template_lock"} + ) + await hass.async_block_till_done() + + assert len(calls) == 1 async def test_available_template_with_entities(hass): @@ -341,7 +334,7 @@ async def test_available_template_with_entities(hass): await setup.async_setup_component( hass, - "lock", + lock.DOMAIN, { "lock": { "platform": "template", @@ -379,7 +372,7 @@ async def test_invalid_availability_template_keeps_component_available(hass, cap """Test that an invalid availability keeps the device available.""" await setup.async_setup_component( hass, - "lock", + lock.DOMAIN, { "lock": { "platform": "template", @@ -406,7 +399,7 @@ async def test_unique_id(hass): """Test unique_id option only creates one lock per id.""" await setup.async_setup_component( hass, - "lock", + lock.DOMAIN, { "lock": { "platform": "template", @@ -424,7 +417,7 @@ async def test_unique_id(hass): await setup.async_setup_component( hass, - "lock", + lock.DOMAIN, { "lock": { "platform": "template",