Convert automation tests to async (#17794)

* Convert automation tests to async

* Fix 8 last tests

* Lint
This commit is contained in:
Paulus Schoutsen 2018-10-26 11:31:14 +02:00 committed by GitHub
parent 3f4798b5c3
commit e276e899cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 3544 additions and 3514 deletions

View file

@ -11,43 +11,34 @@ from homeassistant.loader import bind_hass
@bind_hass
def turn_on(hass, entity_id=None):
async def async_turn_on(hass, entity_id=None):
"""Turn on specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TURN_ON, data)
await hass.services.async_call(DOMAIN, SERVICE_TURN_ON, data)
@bind_hass
def turn_off(hass, entity_id=None):
async def async_turn_off(hass, entity_id=None):
"""Turn off specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TURN_OFF, data)
await hass.services.async_call(DOMAIN, SERVICE_TURN_OFF, data)
@bind_hass
def toggle(hass, entity_id=None):
async def async_toggle(hass, entity_id=None):
"""Toggle specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TOGGLE, data)
await hass.services.async_call(DOMAIN, SERVICE_TOGGLE, data)
@bind_hass
def trigger(hass, entity_id=None):
async def async_trigger(hass, entity_id=None):
"""Trigger specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TRIGGER, data)
await hass.services.async_call(DOMAIN, SERVICE_TRIGGER, data)
@bind_hass
def reload(hass):
async def async_reload(hass):
"""Reload the automation from config."""
hass.services.call(DOMAIN, SERVICE_RELOAD)
@bind_hass
def async_reload(hass):
"""Reload the automation from config.
Returns a coroutine object.
"""
return hass.services.async_call(DOMAIN, SERVICE_RELOAD)
await hass.services.async_call(DOMAIN, SERVICE_RELOAD)

View file

@ -1,40 +1,32 @@
"""The tests for the Event automation."""
import unittest
import pytest
from homeassistant.core import Context, callback
from homeassistant.setup import setup_component
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
import homeassistant.components.automation as automation
from tests.common import get_test_home_assistant, mock_component
from tests.common import mock_component
from tests.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name
class TestAutomationEvent(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
self.calls = []
@callback
def record_call(service):
"""Record the call."""
self.calls.append(service)
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_event(self):
async def test_if_fires_on_event(hass, calls):
"""Test the firing of events."""
context = Context()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -46,21 +38,22 @@ class TestAutomationEvent(unittest.TestCase):
}
})
self.hass.bus.fire('test_event', context=context)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
hass.bus.async_fire('test_event', context=context)
await hass.async_block_till_done()
assert 1 == len(calls)
assert calls[0].context is context
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_event_extra_data(self):
async def test_if_fires_on_event_extra_data(hass, calls):
"""Test the firing of events still matches with event data."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -72,20 +65,21 @@ class TestAutomationEvent(unittest.TestCase):
}
})
self.hass.bus.fire('test_event', {'extra_key': 'extra_data'})
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event', {'extra_key': 'extra_data'})
await hass.async_block_till_done()
assert 1 == len(calls)
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_event_with_data(self):
async def test_if_fires_on_event_with_data(hass, calls):
"""Test the firing of events with data."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -98,18 +92,19 @@ class TestAutomationEvent(unittest.TestCase):
}
})
self.hass.bus.fire('test_event', {'some_attr': 'some_value',
hass.bus.async_fire('test_event', {'some_attr': 'some_value',
'another': 'value'})
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_event_with_empty_data_config(self):
async def test_if_fires_on_event_with_empty_data_config(hass, calls):
"""Test the firing of events with empty data config.
The frontend automation editor can produce configurations with an
empty dict for event_data instead of no key.
"""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -122,14 +117,15 @@ class TestAutomationEvent(unittest.TestCase):
}
})
self.hass.bus.fire('test_event', {'some_attr': 'some_value',
hass.bus.async_fire('test_event', {'some_attr': 'some_value',
'another': 'value'})
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_event_with_nested_data(self):
async def test_if_fires_on_event_with_nested_data(hass, calls):
"""Test the firing of events with nested data."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -146,18 +142,19 @@ class TestAutomationEvent(unittest.TestCase):
}
})
self.hass.bus.fire('test_event', {
hass.bus.async_fire('test_event', {
'parent_attr': {
'some_attr': 'some_value',
'another': 'value'
}
})
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_if_event_data_not_matches(self):
async def test_if_not_fires_if_event_data_not_matches(hass, calls):
"""Test firing of event if no match."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -170,6 +167,6 @@ class TestAutomationEvent(unittest.TestCase):
}
})
self.hass.bus.fire('test_event', {'some_attr': 'some_other_value'})
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event', {'some_attr': 'some_other_value'})
await hass.async_block_till_done()
assert 0 == len(calls)

View file

@ -1,54 +1,46 @@
"""The tests for the geo location trigger."""
import unittest
import pytest
from homeassistant.components import automation, zone
from homeassistant.core import callback, Context
from homeassistant.setup import setup_component
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
from tests.common import get_test_home_assistant, mock_component
from tests.common import mock_component
from tests.components.automation import common
from tests.common import async_mock_service
class TestAutomationGeoLocation(unittest.TestCase):
"""Test the geo location trigger."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
assert setup_component(self.hass, zone.DOMAIN, {
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
hass.loop.run_until_complete(async_setup_component(hass, zone.DOMAIN, {
'zone': {
'name': 'test',
'latitude': 32.880837,
'longitude': -117.237561,
'radius': 250,
}
})
}))
self.calls = []
@callback
def record_call(service):
"""Record calls."""
self.calls.append(service)
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_zone_enter(self):
async def test_if_fires_on_zone_enter(hass, calls):
"""Test for firing on zone enter."""
context = Context()
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
@ -69,45 +61,46 @@ class TestAutomationGeoLocation(unittest.TestCase):
}
})
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
}, context=context)
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
assert 1 == len(calls)
assert calls[0].context is context
assert 'geo_location - geo_location.entity - hello - hello - test' == \
self.calls[0].data['some']
calls[0].data['some']
# Set out of zone again so we can trigger call
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_not_fires_for_enter_on_zone_leave(self):
async def test_if_not_fires_for_enter_on_zone_leave(hass, calls):
"""Test for not firing on zone leave."""
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
@ -121,24 +114,25 @@ class TestAutomationGeoLocation(unittest.TestCase):
}
})
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 0 == len(self.calls)
assert 0 == len(calls)
def test_if_fires_on_zone_leave(self):
async def test_if_fires_on_zone_leave(hass, calls):
"""Test for firing on zone leave."""
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
@ -152,25 +146,26 @@ class TestAutomationGeoLocation(unittest.TestCase):
}
})
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_not_fires_for_leave_on_zone_enter(self):
async def test_if_not_fires_for_leave_on_zone_enter(hass, calls):
"""Test for not firing on zone enter."""
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
@ -184,17 +179,18 @@ class TestAutomationGeoLocation(unittest.TestCase):
}
})
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 0 == len(self.calls)
assert 0 == len(calls)
def test_if_fires_on_zone_appear(self):
async def test_if_fires_on_zone_appear(hass, calls):
"""Test for firing if entity appears in zone."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
@ -217,28 +213,29 @@ class TestAutomationGeoLocation(unittest.TestCase):
# Entity appears in zone without previously existing outside the zone.
context = Context()
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
}, context=context)
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
assert 1 == len(calls)
assert calls[0].context is context
assert 'geo_location - geo_location.entity - - hello - test' == \
self.calls[0].data['some']
calls[0].data['some']
def test_if_fires_on_zone_disappear(self):
async def test_if_fires_on_zone_disappear(hass, calls):
"""Test for firing if entity disappears from zone."""
self.hass.states.set('geo_location.entity', 'hello', {
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
@ -260,9 +257,9 @@ class TestAutomationGeoLocation(unittest.TestCase):
})
# Entity disappears from zone without new coordinates outside the zone.
self.hass.states.async_remove('geo_location.entity')
self.hass.block_till_done()
hass.states.async_remove('geo_location.entity')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
assert 'geo_location - geo_location.entity - hello - - test' == \
self.calls[0].data['some']
calls[0].data['some']

View file

@ -1,11 +1,12 @@
"""The tests for the automation component."""
import asyncio
from datetime import timedelta
import unittest
from unittest.mock import patch
import pytest
from homeassistant.core import State, CoreState
from homeassistant.setup import setup_component, async_setup_component
from homeassistant.setup import async_setup_component
import homeassistant.components.automation as automation
from homeassistant.const import (
ATTR_ENTITY_ID, STATE_ON, STATE_OFF, EVENT_HOMEASSISTANT_START)
@ -13,28 +14,21 @@ from homeassistant.exceptions import HomeAssistantError
import homeassistant.util.dt as dt_util
from tests.common import (
assert_setup_component, get_test_home_assistant, fire_time_changed,
mock_service, async_mock_service, mock_restore_cache)
assert_setup_component, async_fire_time_changed,
mock_restore_cache, async_mock_service)
from tests.components.automation import common
# pylint: disable=invalid-name
class TestAutomation(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.calls = mock_service(self.hass, 'test', 'automation')
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_service_data_not_a_dict(self):
async def test_service_data_not_a_dict(hass, calls):
"""Test service data not dict."""
with assert_setup_component(0, automation.DOMAIN):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -47,9 +41,10 @@ class TestAutomation(unittest.TestCase):
}
})
def test_service_specify_data(self):
async def test_service_specify_data(hass, calls):
"""Test service data."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'hello',
'trigger': {
@ -70,21 +65,23 @@ class TestAutomation(unittest.TestCase):
with patch('homeassistant.components.automation.utcnow',
return_value=time):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 1
assert self.calls[0].data['some'] == 'event - test_event'
state = self.hass.states.get('automation.hello')
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 1
assert calls[0].data['some'] == 'event - test_event'
state = hass.states.get('automation.hello')
assert state is not None
assert state.attributes.get('last_triggered') == time
state = self.hass.states.get('group.all_automations')
state = hass.states.get('group.all_automations')
assert state is not None
assert state.attributes.get('entity_id') == ('automation.hello',)
def test_action_delay(self):
async def test_action_delay(hass, calls):
"""Test action delay."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'hello',
'trigger': {
@ -115,29 +112,30 @@ class TestAutomation(unittest.TestCase):
with patch('homeassistant.components.automation.utcnow',
return_value=time):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(self.calls) == 1
assert self.calls[0].data['some'] == 'event - test_event'
assert len(calls) == 1
assert calls[0].data['some'] == 'event - test_event'
future = dt_util.utcnow() + timedelta(minutes=10)
fire_time_changed(self.hass, future)
self.hass.block_till_done()
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert len(self.calls) == 2
assert self.calls[1].data['some'] == 'event - test_event'
assert len(calls) == 2
assert calls[1].data['some'] == 'event - test_event'
state = self.hass.states.get('automation.hello')
state = hass.states.get('automation.hello')
assert state is not None
assert state.attributes.get('last_triggered') == time
state = self.hass.states.get('group.all_automations')
state = hass.states.get('group.all_automations')
assert state is not None
assert state.attributes.get('entity_id') == ('automation.hello',)
def test_service_specify_entity_id(self):
async def test_service_specify_entity_id(hass, calls):
"""Test service data."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -150,15 +148,16 @@ class TestAutomation(unittest.TestCase):
}
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
assert ['hello.world'] == \
self.calls[0].data.get(ATTR_ENTITY_ID)
calls[0].data.get(ATTR_ENTITY_ID)
def test_service_specify_entity_id_list(self):
async def test_service_specify_entity_id_list(hass, calls):
"""Test service data."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -171,15 +170,16 @@ class TestAutomation(unittest.TestCase):
}
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
assert ['hello.world', 'hello.world2'] == \
self.calls[0].data.get(ATTR_ENTITY_ID)
calls[0].data.get(ATTR_ENTITY_ID)
def test_two_triggers(self):
async def test_two_triggers(hass, calls):
"""Test triggers."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': [
{
@ -197,16 +197,17 @@ class TestAutomation(unittest.TestCase):
}
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 2 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert 2 == len(calls)
def test_trigger_service_ignoring_condition(self):
async def test_trigger_service_ignoring_condition(hass, calls):
"""Test triggers."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'test',
'trigger': [
@ -226,20 +227,21 @@ class TestAutomation(unittest.TestCase):
}
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 0
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 0
self.hass.services.call('automation', 'trigger',
await hass.services.async_call(
'automation', 'trigger',
{'entity_id': 'automation.test'},
blocking=True)
self.hass.block_till_done()
assert len(self.calls) == 1
assert len(calls) == 1
def test_two_conditions_with_and(self):
async def test_two_conditions_with_and(hass, calls):
"""Test two and conditions."""
entity_id = 'test.entity'
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': [
{
@ -265,24 +267,25 @@ class TestAutomation(unittest.TestCase):
}
})
self.hass.states.set(entity_id, 100)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set(entity_id, 100)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
self.hass.states.set(entity_id, 101)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set(entity_id, 101)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
self.hass.states.set(entity_id, 151)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set(entity_id, 151)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_automation_list_setting(self):
async def test_automation_list_setting(hass, calls):
"""Event is not a valid condition."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: [{
'trigger': {
'platform': 'event',
@ -303,17 +306,18 @@ class TestAutomation(unittest.TestCase):
}]
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
self.hass.bus.fire('test_event_2')
self.hass.block_till_done()
assert 2 == len(self.calls)
hass.bus.async_fire('test_event_2')
await hass.async_block_till_done()
assert 2 == len(calls)
def test_automation_calling_two_actions(self):
"""Test if we can call two actions from automation definition."""
assert setup_component(self.hass, automation.DOMAIN, {
async def test_automation_calling_two_actions(hass, calls):
"""Test if we can call two actions from automation async definition."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -330,21 +334,22 @@ class TestAutomation(unittest.TestCase):
}
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(self.calls) == 2
assert self.calls[0].data['position'] == 0
assert self.calls[1].data['position'] == 1
assert len(calls) == 2
assert calls[0].data['position'] == 0
assert calls[1].data['position'] == 1
def test_services(self):
async def test_services(hass, calls):
"""Test the automation services for turning entities on/off."""
entity_id = 'automation.hello'
assert self.hass.states.get(entity_id) is None
assert not automation.is_on(self.hass, entity_id)
assert hass.states.get(entity_id) is None
assert not automation.is_on(hass, entity_id)
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'hello',
'trigger': {
@ -357,46 +362,47 @@ class TestAutomation(unittest.TestCase):
}
})
assert self.hass.states.get(entity_id) is not None
assert automation.is_on(self.hass, entity_id)
assert hass.states.get(entity_id) is not None
assert automation.is_on(hass, entity_id)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 1
common.turn_off(self.hass, entity_id)
self.hass.block_till_done()
await common.async_turn_off(hass, entity_id)
await hass.async_block_till_done()
assert not automation.is_on(self.hass, entity_id)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 1
assert not automation.is_on(hass, entity_id)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 1
common.toggle(self.hass, entity_id)
self.hass.block_till_done()
await common.async_toggle(hass, entity_id)
await hass.async_block_till_done()
assert automation.is_on(self.hass, entity_id)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 2
assert automation.is_on(hass, entity_id)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 2
common.trigger(self.hass, entity_id)
self.hass.block_till_done()
assert len(self.calls) == 3
await common.async_trigger(hass, entity_id)
await hass.async_block_till_done()
assert len(calls) == 3
common.turn_off(self.hass, entity_id)
self.hass.block_till_done()
common.trigger(self.hass, entity_id)
self.hass.block_till_done()
assert len(self.calls) == 4
await common.async_turn_off(hass, entity_id)
await hass.async_block_till_done()
await common.async_trigger(hass, entity_id)
await hass.async_block_till_done()
assert len(calls) == 4
common.turn_on(self.hass, entity_id)
self.hass.block_till_done()
assert automation.is_on(self.hass, entity_id)
await common.async_turn_on(hass, entity_id)
await hass.async_block_till_done()
assert automation.is_on(hass, entity_id)
def test_reload_config_service(self):
async def test_reload_config_service(hass, calls):
"""Test the reload config service."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'hello',
'trigger': {
@ -411,17 +417,17 @@ class TestAutomation(unittest.TestCase):
}
}
})
assert self.hass.states.get('automation.hello') is not None
assert self.hass.states.get('automation.bye') is None
listeners = self.hass.bus.listeners
assert hass.states.get('automation.hello') is not None
assert hass.states.get('automation.bye') is None
listeners = hass.bus.async_listeners()
assert listeners.get('test_event') == 1
assert listeners.get('test_event2') is None
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(self.calls) == 1
assert self.calls[0].data.get('event') == 'test_event'
assert len(calls) == 1
assert calls[0].data.get('event') == 'test_event'
with patch('homeassistant.config.load_yaml_config_file', autospec=True,
return_value={
@ -440,30 +446,31 @@ class TestAutomation(unittest.TestCase):
}}):
with patch('homeassistant.config.find_config_file',
return_value=''):
common.reload(self.hass)
self.hass.block_till_done()
await common.async_reload(hass)
await hass.async_block_till_done()
# De-flake ?!
self.hass.block_till_done()
await hass.async_block_till_done()
assert self.hass.states.get('automation.hello') is None
assert self.hass.states.get('automation.bye') is not None
listeners = self.hass.bus.listeners
assert hass.states.get('automation.hello') is None
assert hass.states.get('automation.bye') is not None
listeners = hass.bus.async_listeners()
assert listeners.get('test_event') is None
assert listeners.get('test_event2') == 1
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 1
self.hass.bus.fire('test_event2')
self.hass.block_till_done()
assert len(self.calls) == 2
assert self.calls[1].data.get('event') == 'test_event2'
hass.bus.async_fire('test_event2')
await hass.async_block_till_done()
assert len(calls) == 2
assert calls[1].data.get('event') == 'test_event2'
def test_reload_config_when_invalid_config(self):
async def test_reload_config_when_invalid_config(hass, calls):
"""Test the reload config service handling invalid config."""
with assert_setup_component(1, automation.DOMAIN):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'hello',
'trigger': {
@ -478,30 +485,31 @@ class TestAutomation(unittest.TestCase):
}
}
})
assert self.hass.states.get('automation.hello') is not None
assert hass.states.get('automation.hello') is not None
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(self.calls) == 1
assert self.calls[0].data.get('event') == 'test_event'
assert len(calls) == 1
assert calls[0].data.get('event') == 'test_event'
with patch('homeassistant.config.load_yaml_config_file', autospec=True,
return_value={automation.DOMAIN: 'not valid'}):
with patch('homeassistant.config.find_config_file',
return_value=''):
common.reload(self.hass)
self.hass.block_till_done()
await common.async_reload(hass)
await hass.async_block_till_done()
assert self.hass.states.get('automation.hello') is None
assert hass.states.get('automation.hello') is None
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 1
def test_reload_config_handles_load_fails(self):
async def test_reload_config_handles_load_fails(hass, calls):
"""Test the reload config service."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'alias': 'hello',
'trigger': {
@ -516,26 +524,26 @@ class TestAutomation(unittest.TestCase):
}
}
})
assert self.hass.states.get('automation.hello') is not None
assert hass.states.get('automation.hello') is not None
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(self.calls) == 1
assert self.calls[0].data.get('event') == 'test_event'
assert len(calls) == 1
assert calls[0].data.get('event') == 'test_event'
with patch('homeassistant.config.load_yaml_config_file',
side_effect=HomeAssistantError('bla')):
with patch('homeassistant.config.find_config_file',
return_value=''):
common.reload(self.hass)
self.hass.block_till_done()
await common.async_reload(hass)
await hass.async_block_till_done()
assert self.hass.states.get('automation.hello') is not None
assert hass.states.get('automation.hello') is not None
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert len(self.calls) == 2
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert len(calls) == 2
@asyncio.coroutine

View file

@ -1,40 +1,30 @@
"""The tests for the MQTT automation."""
import unittest
import pytest
from homeassistant.core import callback
from homeassistant.setup import setup_component
from homeassistant.setup import async_setup_component
import homeassistant.components.automation as automation
from tests.common import (
mock_mqtt_component, fire_mqtt_message, get_test_home_assistant,
mock_component)
async_fire_mqtt_message,
mock_component, async_mock_service, async_mock_mqtt_component)
from tests.components.automation import common
# pylint: disable=invalid-name
class TestAutomationMQTT(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
mock_mqtt_component(self.hass)
self.calls = []
@callback
def record_call(service):
"""Record calls."""
self.calls.append(service)
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
hass.loop.run_until_complete(async_mock_mqtt_component(hass))
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_topic_match(self):
async def test_if_fires_on_topic_match(hass, calls):
"""Test if message is fired on topic match."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'mqtt',
@ -51,21 +41,22 @@ class TestAutomationMQTT(unittest.TestCase):
}
})
fire_mqtt_message(self.hass, 'test-topic', '{ "hello": "world" }')
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_mqtt_message(hass, 'test-topic', '{ "hello": "world" }')
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'mqtt - test-topic - { "hello": "world" } - world' == \
self.calls[0].data['some']
calls[0].data['some']
common.turn_off(self.hass)
self.hass.block_till_done()
fire_mqtt_message(self.hass, 'test-topic', 'test_payload')
self.hass.block_till_done()
assert 1 == len(self.calls)
await common.async_turn_off(hass)
await hass.async_block_till_done()
async_fire_mqtt_message(hass, 'test-topic', 'test_payload')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_topic_and_payload_match(self):
async def test_if_fires_on_topic_and_payload_match(hass, calls):
"""Test if message is fired on topic and payload match."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'mqtt',
@ -78,13 +69,14 @@ class TestAutomationMQTT(unittest.TestCase):
}
})
fire_mqtt_message(self.hass, 'test-topic', 'hello')
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_mqtt_message(hass, 'test-topic', 'hello')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_on_topic_but_no_payload_match(self):
async def test_if_not_fires_on_topic_but_no_payload_match(hass, calls):
"""Test if message is not fired on topic but no payload."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'mqtt',
@ -97,6 +89,6 @@ class TestAutomationMQTT(unittest.TestCase):
}
})
fire_mqtt_message(self.hass, 'test-topic', 'no-hello')
self.hass.block_till_done()
assert 0 == len(self.calls)
async_fire_mqtt_message(hass, 'test-topic', 'no-hello')
await hass.async_block_till_done()
assert 0 == len(calls)

View file

@ -1,44 +1,35 @@
"""The tests for numeric state automation."""
from datetime import timedelta
import unittest
import pytest
from unittest.mock import patch
import homeassistant.components.automation as automation
from homeassistant.core import Context, callback
from homeassistant.setup import setup_component
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from tests.common import (
get_test_home_assistant, mock_component, fire_time_changed,
assert_setup_component)
mock_component, async_fire_time_changed,
assert_setup_component, async_mock_service)
from tests.components.automation import common
# pylint: disable=invalid-name
class TestAutomationNumericState(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
self.calls = []
@callback
def record_call(service):
"""Record calls."""
self.calls.append(service)
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_entity_change_below(self):
async def test_if_fires_on_entity_change_below(hass, calls):
"""Test the firing with changed entity."""
context = Context()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -51,25 +42,26 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 9 is below 10
self.hass.states.set('test.entity', 9, context=context)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
hass.states.async_set('test.entity', 9, context=context)
await hass.async_block_till_done()
assert 1 == len(calls)
assert calls[0].context is context
# Set above 12 so the automation will fire again
self.hass.states.set('test.entity', 12)
common.turn_off(self.hass)
self.hass.block_till_done()
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 12)
await common.async_turn_off(hass)
await hass.async_block_till_done()
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_over_to_below(self):
async def test_if_fires_on_entity_change_over_to_below(hass, calls):
"""Test the firing with changed entity."""
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -83,17 +75,18 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 9 is below 10
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entities_change_over_to_below(self):
async def test_if_fires_on_entities_change_over_to_below(hass, calls):
"""Test the firing with changed entities."""
self.hass.states.set('test.entity_1', 11)
self.hass.states.set('test.entity_2', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity_1', 11)
hass.states.async_set('test.entity_2', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -110,20 +103,21 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 9 is below 10
self.hass.states.set('test.entity_1', 9)
self.hass.block_till_done()
assert 1 == len(self.calls)
self.hass.states.set('test.entity_2', 9)
self.hass.block_till_done()
assert 2 == len(self.calls)
hass.states.async_set('test.entity_1', 9)
await hass.async_block_till_done()
assert 1 == len(calls)
hass.states.async_set('test.entity_2', 9)
await hass.async_block_till_done()
assert 2 == len(calls)
def test_if_not_fires_on_entity_change_below_to_below(self):
async def test_if_not_fires_on_entity_change_below_to_below(hass, calls):
"""Test the firing with changed entity."""
context = Context()
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -137,27 +131,28 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 9 is below 10 so this should fire
self.hass.states.set('test.entity', 9, context=context)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
hass.states.async_set('test.entity', 9, context=context)
await hass.async_block_till_done()
assert 1 == len(calls)
assert calls[0].context is context
# already below so should not fire again
self.hass.states.set('test.entity', 5)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 5)
await hass.async_block_till_done()
assert 1 == len(calls)
# still below so should not fire again
self.hass.states.set('test.entity', 3)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 3)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_below_fires_on_entity_change_to_equal(self):
async def test_if_not_below_fires_on_entity_change_to_equal(hass, calls):
"""Test the firing with changed entity."""
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -171,16 +166,17 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 10 is not below 10 so this should not fire again
self.hass.states.set('test.entity', 10)
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 10)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_initial_entity_below(self):
async def test_if_fires_on_initial_entity_below(hass, calls):
"""Test the firing when starting with a match."""
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -194,16 +190,17 @@ class TestAutomationNumericState(unittest.TestCase):
})
# Fire on first update even if initial state was already below
self.hass.states.set('test.entity', 8)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 8)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_initial_entity_above(self):
async def test_if_fires_on_initial_entity_above(hass, calls):
"""Test the firing when starting with a match."""
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -217,13 +214,14 @@ class TestAutomationNumericState(unittest.TestCase):
})
# Fire on first update even if initial state was already above
self.hass.states.set('test.entity', 12)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 12)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_above(self):
async def test_if_fires_on_entity_change_above(hass, calls):
"""Test the firing with changed entity."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -236,17 +234,18 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 11 is above 10
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_below_to_above(self):
async def test_if_fires_on_entity_change_below_to_above(hass, calls):
"""Test the firing with changed entity."""
# set initial state
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -260,17 +259,18 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 11 is above 10 and 9 is below
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_on_entity_change_above_to_above(self):
async def test_if_not_fires_on_entity_change_above_to_above(hass, calls):
"""Test the firing with changed entity."""
# set initial state
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -284,22 +284,23 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 12 is above 10 so this should fire
self.hass.states.set('test.entity', 12)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 12)
await hass.async_block_till_done()
assert 1 == len(calls)
# already above, should not fire again
self.hass.states.set('test.entity', 15)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 15)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_above_fires_on_entity_change_to_equal(self):
async def test_if_not_above_fires_on_entity_change_to_equal(hass, calls):
"""Test the firing with changed entity."""
# set initial state
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -313,13 +314,14 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 10 is not above 10 so this should not fire again
self.hass.states.set('test.entity', 10)
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 10)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_entity_change_below_range(self):
async def test_if_fires_on_entity_change_below_range(hass, calls):
"""Test the firing with changed entity."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -333,13 +335,14 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 9 is below 10
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_below_above_range(self):
async def test_if_fires_on_entity_change_below_above_range(hass, calls):
"""Test the firing with changed entity."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -353,16 +356,17 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 4 is below 5
self.hass.states.set('test.entity', 4)
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 4)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_entity_change_over_to_below_range(self):
async def test_if_fires_on_entity_change_over_to_below_range(hass, calls):
"""Test the firing with changed entity."""
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -377,16 +381,18 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 9 is below 10
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_over_to_below_above_range(self):
async def test_if_fires_on_entity_change_over_to_below_above_range(
hass, calls):
"""Test the firing with changed entity."""
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -401,13 +407,14 @@ class TestAutomationNumericState(unittest.TestCase):
})
# 4 is below 5 so it should not fire
self.hass.states.set('test.entity', 4)
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 4)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_if_entity_not_match(self):
async def test_if_not_fires_if_entity_not_match(hass, calls):
"""Test if not fired with non matching entity."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -420,13 +427,14 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 11)
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 11)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_entity_change_below_with_attribute(self):
async def test_if_fires_on_entity_change_below_with_attribute(hass, calls):
"""Test attributes change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -439,13 +447,15 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 9 is below 10
self.hass.states.set('test.entity', 9, {'test_attribute': 11})
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 9, {'test_attribute': 11})
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_on_entity_change_not_below_with_attribute(self):
async def test_if_not_fires_on_entity_change_not_below_with_attribute(
hass, calls):
"""Test attributes."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -458,13 +468,14 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 11 is not below 10
self.hass.states.set('test.entity', 11, {'test_attribute': 9})
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 11, {'test_attribute': 9})
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_attribute_change_with_attribute_below(self):
async def test_if_fires_on_attribute_change_with_attribute_below(hass, calls):
"""Test attributes change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -478,13 +489,15 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 9 is below 10
self.hass.states.set('test.entity', 'entity', {'test_attribute': 9})
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'entity', {'test_attribute': 9})
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_on_attribute_change_with_attribute_not_below(self):
async def test_if_not_fires_on_attribute_change_with_attribute_not_below(
hass, calls):
"""Test attributes change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -498,13 +511,14 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 11 is not below 10
self.hass.states.set('test.entity', 'entity', {'test_attribute': 11})
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'entity', {'test_attribute': 11})
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_on_entity_change_with_attribute_below(self):
async def test_if_not_fires_on_entity_change_with_attribute_below(hass, calls):
"""Test attributes change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -518,13 +532,15 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 11 is not below 10, entity state value should not be tested
self.hass.states.set('test.entity', '9', {'test_attribute': 11})
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', '9', {'test_attribute': 11})
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_on_entity_change_with_not_attribute_below(self):
async def test_if_not_fires_on_entity_change_with_not_attribute_below(
hass, calls):
"""Test attributes change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -538,13 +554,15 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 11 is not below 10, entity state value should not be tested
self.hass.states.set('test.entity', 'entity')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'entity')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_fires_on_attr_change_with_attribute_below_and_multiple_attr(self):
async def test_fires_on_attr_change_with_attribute_below_and_multiple_attr(
hass, calls):
"""Test attributes change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -558,14 +576,15 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 9 is not below 10
self.hass.states.set('test.entity', 'entity',
hass.states.async_set('test.entity', 'entity',
{'test_attribute': 9, 'not_test_attribute': 11})
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_template_list(self):
async def test_template_list(hass, calls):
"""Test template list."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -580,14 +599,15 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 3 is below 10
self.hass.states.set('test.entity', 'entity',
hass.states.async_set('test.entity', 'entity',
{'test_attribute': [11, 15, 3]})
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_template_string(self):
async def test_template_string(hass, calls):
"""Test template string."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -606,20 +626,22 @@ class TestAutomationNumericState(unittest.TestCase):
}
}
})
self.hass.states.set('test.entity', 'test state 1',
hass.states.async_set('test.entity', 'test state 1',
{'test_attribute': '1.2'})
self.hass.block_till_done()
self.hass.states.set('test.entity', 'test state 2',
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'test state 2',
{'test_attribute': '0.9'})
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'numeric_state - test.entity - 10.0 - None - test state 1 - ' \
'test state 2' == \
self.calls[0].data['some']
calls[0].data['some']
def test_not_fires_on_attr_change_with_attr_not_below_multiple_attr(self):
async def test_not_fires_on_attr_change_with_attr_not_below_multiple_attr(
hass, calls):
"""Test if not fired changed attributes."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -633,15 +655,16 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
# 11 is not below 10
self.hass.states.set('test.entity', 'entity',
hass.states.async_set('test.entity', 'entity',
{'test_attribute': 11, 'not_test_attribute': 9})
self.hass.block_till_done()
assert 0 == len(self.calls)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_action(self):
async def test_if_action(hass, calls):
"""Test if action."""
entity_id = 'domain.test_entity'
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -659,28 +682,29 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
self.hass.states.set(entity_id, 10)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.states.async_set(entity_id, 10)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
self.hass.states.set(entity_id, 8)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.states.async_set(entity_id, 8)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
self.hass.states.set(entity_id, 9)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.states.async_set(entity_id, 9)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 2 == len(self.calls)
assert 2 == len(calls)
def test_if_fails_setup_bad_for(self):
async def test_if_fails_setup_bad_for(hass, calls):
"""Test for setup failure for bad for."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -696,10 +720,11 @@ class TestAutomationNumericState(unittest.TestCase):
}
}})
def test_if_fails_setup_for_without_above_below(self):
async def test_if_fails_setup_for_without_above_below(hass, calls):
"""Test for setup failures for missing above or below."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -713,9 +738,10 @@ class TestAutomationNumericState(unittest.TestCase):
}
}})
def test_if_not_fires_on_entity_change_with_for(self):
async def test_if_not_fires_on_entity_change_with_for(hass, calls):
"""Test for not firing on entity change with for."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -732,17 +758,19 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
self.hass.states.set('test.entity', 15)
self.hass.block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
hass.states.async_set('test.entity', 15)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_on_entities_change_with_for_after_stop(self):
async def test_if_not_fires_on_entities_change_with_for_after_stop(hass,
calls):
"""Test for not firing on entities change with for after stop."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -762,29 +790,31 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
self.hass.states.set('test.entity_1', 9)
self.hass.states.set('test.entity_2', 9)
self.hass.block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 2 == len(self.calls)
hass.states.async_set('test.entity_1', 9)
hass.states.async_set('test.entity_2', 9)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 2 == len(calls)
self.hass.states.set('test.entity_1', 15)
self.hass.states.set('test.entity_2', 15)
self.hass.block_till_done()
self.hass.states.set('test.entity_1', 9)
self.hass.states.set('test.entity_2', 9)
self.hass.block_till_done()
common.turn_off(self.hass)
self.hass.block_till_done()
hass.states.async_set('test.entity_1', 15)
hass.states.async_set('test.entity_2', 15)
await hass.async_block_till_done()
hass.states.async_set('test.entity_1', 9)
hass.states.async_set('test.entity_2', 9)
await hass.async_block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 2 == len(self.calls)
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 2 == len(calls)
def test_if_fires_on_entity_change_with_for_attribute_change(self):
async def test_if_fires_on_entity_change_with_for_attribute_change(hass,
calls):
"""Test for firing on entity change with for and attribute change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -804,22 +834,23 @@ class TestAutomationNumericState(unittest.TestCase):
utcnow = dt_util.utcnow()
with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow:
mock_utcnow.return_value = utcnow
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
mock_utcnow.return_value += timedelta(seconds=4)
fire_time_changed(self.hass, mock_utcnow.return_value)
self.hass.states.set('test.entity', 9,
async_fire_time_changed(hass, mock_utcnow.return_value)
hass.states.async_set('test.entity', 9,
attributes={"mock_attr": "attr_change"})
self.hass.block_till_done()
assert 0 == len(self.calls)
await hass.async_block_till_done()
assert 0 == len(calls)
mock_utcnow.return_value += timedelta(seconds=4)
fire_time_changed(self.hass, mock_utcnow.return_value)
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, mock_utcnow.return_value)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_with_for(self):
async def test_if_fires_on_entity_change_with_for(hass, calls):
"""Test for firing on entity change with for."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -836,15 +867,16 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 9)
self.hass.block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 9)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 1 == len(calls)
def test_wait_template_with_trigger(self):
async def test_wait_template_with_trigger(hass, calls):
"""Test using wait template with 'trigger.entity_id'."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'numeric_state',
@ -864,13 +896,13 @@ class TestAutomationNumericState(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
self.hass.states.set('test.entity', '12')
self.hass.block_till_done()
self.hass.states.set('test.entity', '8')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', '12')
await hass.async_block_till_done()
hass.states.async_set('test.entity', '8')
await hass.async_block_till_done()
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'numeric_state - test.entity - 12' == \
self.calls[0].data['some']
calls[0].data['some']

View file

@ -1,49 +1,40 @@
"""The test for state automation."""
from datetime import timedelta
import unittest
import pytest
from unittest.mock import patch
from homeassistant.core import Context, callback
from homeassistant.setup import setup_component
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
import homeassistant.components.automation as automation
from tests.common import (
fire_time_changed, get_test_home_assistant, assert_setup_component,
mock_component)
async_fire_time_changed, assert_setup_component, mock_component)
from tests.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name
class TestAutomationState(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
self.hass.states.set('test.entity', 'hello')
self.calls = []
@callback
def record_call(service):
"""Call recorder."""
self.calls.append(service)
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
hass.states.async_set('test.entity', 'hello')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_entity_change(self):
async def test_if_fires_on_entity_change(hass, calls):
"""Test for firing on entity change."""
context = Context()
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -61,22 +52,23 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world', context=context)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
hass.states.async_set('test.entity', 'world', context=context)
await hass.async_block_till_done()
assert 1 == len(calls)
assert calls[0].context is context
assert 'state - test.entity - hello - world - None' == \
self.calls[0].data['some']
calls[0].data['some']
common.turn_off(self.hass)
self.hass.block_till_done()
self.hass.states.set('test.entity', 'planet')
self.hass.block_till_done()
assert 1 == len(self.calls)
await common.async_turn_off(hass)
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'planet')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_with_from_filter(self):
async def test_if_fires_on_entity_change_with_from_filter(hass, calls):
"""Test for firing on entity change with filter."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -89,13 +81,14 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_with_to_filter(self):
async def test_if_fires_on_entity_change_with_to_filter(hass, calls):
"""Test for firing on entity change with no filter."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -108,13 +101,14 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_attribute_change_with_to_filter(self):
async def test_if_fires_on_attribute_change_with_to_filter(hass, calls):
"""Test for not firing on attribute change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -127,14 +121,15 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world', {'test_attribute': 11})
self.hass.states.set('test.entity', 'world', {'test_attribute': 12})
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world', {'test_attribute': 11})
hass.states.async_set('test.entity', 'world', {'test_attribute': 12})
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_with_both_filters(self):
async def test_if_fires_on_entity_change_with_both_filters(hass, calls):
"""Test for firing if both filters are a non match."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -148,13 +143,14 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_if_to_filter_not_match(self):
async def test_if_not_fires_if_to_filter_not_match(hass, calls):
"""Test for not firing if to filter is not a match."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -168,15 +164,16 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'moon')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'moon')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_if_from_filter_not_match(self):
async def test_if_not_fires_if_from_filter_not_match(hass, calls):
"""Test for not firing if from filter is not a match."""
self.hass.states.set('test.entity', 'bye')
hass.states.async_set('test.entity', 'bye')
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -190,13 +187,14 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_if_entity_not_match(self):
async def test_if_not_fires_if_entity_not_match(hass, calls):
"""Test for not firing if entity is not matching."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -208,15 +206,16 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_action(self):
async def test_if_action(hass, calls):
"""Test for to action."""
entity_id = 'domain.test_entity'
test_state = 'new_state'
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -233,22 +232,23 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set(entity_id, test_state)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.states.async_set(entity_id, test_state)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
self.hass.states.set(entity_id, test_state + 'something')
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.states.async_set(entity_id, test_state + 'something')
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_fails_setup_if_to_boolean_value(self):
async def test_if_fails_setup_if_to_boolean_value(hass, calls):
"""Test for setup failure for boolean to."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -260,10 +260,11 @@ class TestAutomationState(unittest.TestCase):
}
}})
def test_if_fails_setup_if_from_boolean_value(self):
async def test_if_fails_setup_if_from_boolean_value(hass, calls):
"""Test for setup failure for boolean from."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -275,10 +276,11 @@ class TestAutomationState(unittest.TestCase):
}
}})
def test_if_fails_setup_bad_for(self):
async def test_if_fails_setup_bad_for(hass, calls):
"""Test for setup failure for bad for."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -293,10 +295,11 @@ class TestAutomationState(unittest.TestCase):
}
}})
def test_if_fails_setup_for_without_to(self):
async def test_if_fails_setup_for_without_to(hass, calls):
"""Test for setup failures for missing to."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -310,9 +313,10 @@ class TestAutomationState(unittest.TestCase):
}
}})
def test_if_not_fires_on_entity_change_with_for(self):
async def test_if_not_fires_on_entity_change_with_for(hass, calls):
"""Test for not firing on entity change with for."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -328,17 +332,19 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
self.hass.states.set('test.entity', 'not_world')
self.hass.block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'not_world')
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_on_entities_change_with_for_after_stop(self):
async def test_if_not_fires_on_entities_change_with_for_after_stop(hass,
calls):
"""Test for not firing on entity change with for after stop trigger."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -357,29 +363,31 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity_1', 'world')
self.hass.states.set('test.entity_2', 'world')
self.hass.block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 2 == len(self.calls)
hass.states.async_set('test.entity_1', 'world')
hass.states.async_set('test.entity_2', 'world')
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 2 == len(calls)
self.hass.states.set('test.entity_1', 'world_no')
self.hass.states.set('test.entity_2', 'world_no')
self.hass.block_till_done()
self.hass.states.set('test.entity_1', 'world')
self.hass.states.set('test.entity_2', 'world')
self.hass.block_till_done()
common.turn_off(self.hass)
self.hass.block_till_done()
hass.states.async_set('test.entity_1', 'world_no')
hass.states.async_set('test.entity_2', 'world_no')
await hass.async_block_till_done()
hass.states.async_set('test.entity_1', 'world')
hass.states.async_set('test.entity_2', 'world')
await hass.async_block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 2 == len(self.calls)
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 2 == len(calls)
def test_if_fires_on_entity_change_with_for_attribute_change(self):
async def test_if_fires_on_entity_change_with_for_attribute_change(hass,
calls):
"""Test for firing on entity change with for and attribute change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -398,22 +406,24 @@ class TestAutomationState(unittest.TestCase):
utcnow = dt_util.utcnow()
with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow:
mock_utcnow.return_value = utcnow
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
mock_utcnow.return_value += timedelta(seconds=4)
fire_time_changed(self.hass, mock_utcnow.return_value)
self.hass.states.set('test.entity', 'world',
async_fire_time_changed(hass, mock_utcnow.return_value)
hass.states.async_set('test.entity', 'world',
attributes={"mock_attr": "attr_change"})
self.hass.block_till_done()
assert 0 == len(self.calls)
await hass.async_block_till_done()
assert 0 == len(calls)
mock_utcnow.return_value += timedelta(seconds=4)
fire_time_changed(self.hass, mock_utcnow.return_value)
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, mock_utcnow.return_value)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_with_for_multiple_force_update(self):
async def test_if_fires_on_entity_change_with_for_multiple_force_update(hass,
calls):
"""Test for firing on entity change with for and force update."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -432,22 +442,23 @@ class TestAutomationState(unittest.TestCase):
utcnow = dt_util.utcnow()
with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow:
mock_utcnow.return_value = utcnow
self.hass.states.set('test.force_entity', 'world', None, True)
self.hass.block_till_done()
hass.states.async_set('test.force_entity', 'world', None, True)
await hass.async_block_till_done()
for _ in range(0, 4):
mock_utcnow.return_value += timedelta(seconds=1)
fire_time_changed(self.hass, mock_utcnow.return_value)
self.hass.states.set('test.force_entity', 'world', None, True)
self.hass.block_till_done()
assert 0 == len(self.calls)
async_fire_time_changed(hass, mock_utcnow.return_value)
hass.states.async_set('test.force_entity', 'world', None, True)
await hass.async_block_till_done()
assert 0 == len(calls)
mock_utcnow.return_value += timedelta(seconds=4)
fire_time_changed(self.hass, mock_utcnow.return_value)
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, mock_utcnow.return_value)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_entity_change_with_for(self):
async def test_if_fires_on_entity_change_with_for(hass, calls):
"""Test for firing on entity change with for."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -463,20 +474,21 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10))
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_for_condition(self):
async def test_if_fires_on_for_condition(hass, calls):
"""Test for firing if condition is on."""
point1 = dt_util.utcnow()
point2 = point1 + timedelta(seconds=10)
with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow:
mock_utcnow.return_value = point1
self.hass.states.set('test.entity', 'on')
assert setup_component(self.hass, automation.DOMAIN, {
hass.states.async_set('test.entity', 'on')
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -495,25 +507,26 @@ class TestAutomationState(unittest.TestCase):
})
# not enough time has passed
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
# Time travel 10 secs into the future
mock_utcnow.return_value = point2
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_for_condition_attribute_change(self):
async def test_if_fires_on_for_condition_attribute_change(hass, calls):
"""Test for firing if condition is on with attribute change."""
point1 = dt_util.utcnow()
point2 = point1 + timedelta(seconds=4)
point3 = point1 + timedelta(seconds=8)
with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow:
mock_utcnow.return_value = point1
self.hass.states.set('test.entity', 'on')
assert setup_component(self.hass, automation.DOMAIN, {
hass.states.async_set('test.entity', 'on')
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -532,28 +545,29 @@ class TestAutomationState(unittest.TestCase):
})
# not enough time has passed
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
# Still not enough time has passed, but an attribute is changed
mock_utcnow.return_value = point2
self.hass.states.set('test.entity', 'on',
hass.states.async_set('test.entity', 'on',
attributes={"mock_attr": "attr_change"})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
# Enough time has now passed
mock_utcnow.return_value = point3
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fails_setup_for_without_time(self):
async def test_if_fails_setup_for_without_time(hass, calls):
"""Test for setup failure if no time is provided."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -568,10 +582,11 @@ class TestAutomationState(unittest.TestCase):
'action': {'service': 'test.automation'},
}})
def test_if_fails_setup_for_without_entity(self):
async def test_if_fails_setup_for_without_entity(hass, calls):
"""Test for setup failure if no entity is provided."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {'event_type': 'bla'},
'condition': {
@ -584,9 +599,10 @@ class TestAutomationState(unittest.TestCase):
'action': {'service': 'test.automation'},
}})
def test_wait_template_with_trigger(self):
async def test_wait_template_with_trigger(hass, calls):
"""Test using wait template with 'trigger.entity_id'."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'state',
@ -607,13 +623,12 @@ class TestAutomationState(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'state - test.entity - hello - world' == \
self.calls[0].data['some']
calls[0].data['some']

View file

@ -1,52 +1,41 @@
"""The tests for the sun automation."""
from datetime import datetime
import unittest
import pytest
from unittest.mock import patch
from homeassistant.core import callback
from homeassistant.setup import setup_component
from homeassistant.setup import async_setup_component
from homeassistant.components import sun
import homeassistant.components.automation as automation
import homeassistant.util.dt as dt_util
from tests.common import (
fire_time_changed, get_test_home_assistant, mock_component)
async_fire_time_changed, mock_component, async_mock_service)
from tests.components.automation import common
# pylint: disable=invalid-name
class TestAutomationSun(unittest.TestCase):
"""Test the sun automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
setup_component(self.hass, sun.DOMAIN, {
sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
self.calls = []
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
hass.loop.run_until_complete(async_setup_component(hass, sun.DOMAIN, {
sun.DOMAIN: {sun.CONF_ELEVATION: 0}}))
@callback
def record_call(service):
"""Call recorder."""
self.calls.append(service)
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_sunset_trigger(self):
async def test_sunset_trigger(hass, calls):
"""Test the sunset trigger."""
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 2, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
@ -58,30 +47,31 @@ class TestAutomationSun(unittest.TestCase):
}
})
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 0 == len(self.calls)
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 0 == len(calls)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
common.turn_on(self.hass)
self.hass.block_till_done()
await common.async_turn_on(hass)
await hass.async_block_till_done()
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_sunrise_trigger(self):
async def test_sunrise_trigger(hass, calls):
"""Test the sunrise trigger."""
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 14, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
@ -93,18 +83,19 @@ class TestAutomationSun(unittest.TestCase):
}
})
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_sunset_trigger_with_offset(self):
async def test_sunset_trigger_with_offset(hass, calls):
"""Test the sunset trigger with offset."""
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 2, 30, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
@ -122,19 +113,20 @@ class TestAutomationSun(unittest.TestCase):
}
})
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert 'sun - sunset - 0:30:00' == self.calls[0].data['some']
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'sun - sunset - 0:30:00' == calls[0].data['some']
def test_sunrise_trigger_with_offset(self):
async def test_sunrise_trigger_with_offset(hass, calls):
"""Test the sunrise trigger with offset."""
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 13, 30, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
@ -147,13 +139,14 @@ class TestAutomationSun(unittest.TestCase):
}
})
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_action_before(self):
async def test_if_action_before(hass, calls):
"""Test if action was before."""
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -172,20 +165,21 @@ class TestAutomationSun(unittest.TestCase):
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
now = datetime(2015, 9, 16, 10, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_action_after(self):
async def test_if_action_after(hass, calls):
"""Test if action was after."""
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -204,20 +198,21 @@ class TestAutomationSun(unittest.TestCase):
now = datetime(2015, 9, 16, 13, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_action_before_with_offset(self):
async def test_if_action_before_with_offset(hass, calls):
"""Test if action was before offset."""
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -237,20 +232,21 @@ class TestAutomationSun(unittest.TestCase):
now = datetime(2015, 9, 16, 14, 32, 44, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_action_after_with_offset(self):
async def test_if_action_after_with_offset(hass, calls):
"""Test if action was after offset."""
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -270,20 +266,21 @@ class TestAutomationSun(unittest.TestCase):
now = datetime(2015, 9, 16, 14, 32, 42, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_action_before_and_after_during(self):
async def test_if_action_before_and_after_during(hass, calls):
"""Test if action was before and after during."""
setup_component(self.hass, automation.DOMAIN, {
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -303,20 +300,20 @@ class TestAutomationSun(unittest.TestCase):
now = datetime(2015, 9, 16, 13, 8, 51, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
now = datetime(2015, 9, 17, 2, 25, 18, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
now = datetime(2015, 9, 16, 16, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)

View file

@ -1,40 +1,31 @@
"""The tests for the Template automation."""
import unittest
import pytest
from homeassistant.core import Context, callback
from homeassistant.setup import setup_component
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
import homeassistant.components.automation as automation
from tests.common import (
get_test_home_assistant, assert_setup_component, mock_component)
from tests.common import (assert_setup_component, mock_component)
from tests.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name
class TestAutomationTemplate(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
self.hass.states.set('test.entity', 'hello')
self.calls = []
@callback
def record_call(service):
"""Record calls."""
self.calls.append(service)
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
hass.states.async_set('test.entity', 'hello')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_change_bool(self):
async def test_if_fires_on_change_bool(hass, calls):
"""Test for firing on boolean change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -46,20 +37,21 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'planet')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'planet')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_change_str(self):
async def test_if_fires_on_change_str(hass, calls):
"""Test for firing on change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -71,13 +63,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_change_str_crazy(self):
async def test_if_fires_on_change_str_crazy(hass, calls):
"""Test for firing on change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -89,13 +82,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_on_change_bool(self):
async def test_if_not_fires_on_change_bool(hass, calls):
"""Test for not firing on boolean change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -107,13 +101,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_on_change_str(self):
async def test_if_not_fires_on_change_str(hass, calls):
"""Test for not firing on string change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -125,13 +120,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_on_change_str_crazy(self):
async def test_if_not_fires_on_change_str_crazy(hass, calls):
"""Test for not firing on string change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -143,13 +139,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_no_change(self):
async def test_if_fires_on_no_change(hass, calls):
"""Test for firing on no change."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -161,16 +158,17 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
cur_len = len(calls)
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert cur_len == len(calls)
def test_if_fires_on_two_change(self):
async def test_if_fires_on_two_change(hass, calls):
"""Test for firing on two changes."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -183,18 +181,19 @@ class TestAutomationTemplate(unittest.TestCase):
})
# Trigger once
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
# Trigger again
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_change_with_template(self):
async def test_if_fires_on_change_with_template(hass, calls):
"""Test for firing on change with template."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -206,13 +205,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_not_fires_on_change_with_template(self):
async def test_if_not_fires_on_change_with_template(hass, calls):
"""Test for not firing on change with template."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -224,17 +224,17 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert len(self.calls) == 0
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert len(calls) == 0
def test_if_fires_on_change_with_template_advanced(self):
async def test_if_fires_on_change_with_template_advanced(hass, calls):
"""Test for firing on change with template advanced."""
context = Context()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -252,19 +252,19 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'world', context=context)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
hass.states.async_set('test.entity', 'world', context=context)
await hass.async_block_till_done()
assert 1 == len(calls)
assert calls[0].context is context
assert 'template - test.entity - hello - world' == \
self.calls[0].data['some']
calls[0].data['some']
def test_if_fires_on_no_change_with_template_advanced(self):
async def test_if_fires_on_no_change_with_template_advanced(hass, calls):
"""Test for firing on no change with template advanced."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -281,18 +281,19 @@ class TestAutomationTemplate(unittest.TestCase):
})
# Different state
self.hass.states.set('test.entity', 'worldz')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'worldz')
await hass.async_block_till_done()
assert 0 == len(calls)
# Different state
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_fires_on_change_with_template_2(self):
async def test_if_fires_on_change_with_template_2(hass, calls):
"""Test for firing on change with template."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -305,36 +306,36 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert len(self.calls) == 0
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert len(calls) == 0
self.hass.states.set('test.entity', 'home')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.states.async_set('test.entity', 'home')
await hass.async_block_till_done()
assert len(calls) == 1
self.hass.states.set('test.entity', 'work')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.states.async_set('test.entity', 'work')
await hass.async_block_till_done()
assert len(calls) == 1
self.hass.states.set('test.entity', 'not_home')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.states.async_set('test.entity', 'not_home')
await hass.async_block_till_done()
assert len(calls) == 1
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert len(self.calls) == 1
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert len(calls) == 1
self.hass.states.set('test.entity', 'home')
self.hass.block_till_done()
assert len(self.calls) == 2
hass.states.async_set('test.entity', 'home')
await hass.async_block_till_done()
assert len(calls) == 2
def test_if_action(self):
async def test_if_action(hass, calls):
"""Test for firing if action."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -351,24 +352,25 @@ class TestAutomationTemplate(unittest.TestCase):
})
# Condition is not true yet
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(calls)
# Change condition to true, but it shouldn't be triggered yet
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
# Condition is true and event is triggered
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_on_change_with_bad_template(self):
async def test_if_fires_on_change_with_bad_template(hass, calls):
"""Test for firing on change with bad template."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -380,9 +382,10 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
def test_if_fires_on_change_with_bad_template_2(self):
async def test_if_fires_on_change_with_bad_template_2(hass, calls):
"""Test for firing on change with bad template."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -394,13 +397,14 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
def test_wait_template_with_trigger(self):
async def test_wait_template_with_trigger(hass, calls):
"""Test using wait template with 'trigger.entity_id'."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
@ -421,13 +425,12 @@ class TestAutomationTemplate(unittest.TestCase):
}
})
self.hass.block_till_done()
self.calls = []
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'template - test.entity - hello - world' == \
self.calls[0].data['some']
calls[0].data['some']

View file

@ -1,43 +1,34 @@
"""The tests for the time automation."""
from datetime import timedelta
import unittest
from unittest.mock import patch
from homeassistant.core import callback
from homeassistant.setup import setup_component
import pytest
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
import homeassistant.components.automation as automation
from tests.common import (
fire_time_changed, get_test_home_assistant, assert_setup_component,
mock_component)
async_fire_time_changed, assert_setup_component, mock_component)
from tests.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name
class TestAutomationTime(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
self.calls = []
@callback
def record_call(service):
"""Record calls."""
self.calls.append(service)
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_when_hour_matches(self):
async def test_if_fires_when_hour_matches(hass, calls):
"""Test for firing if hour is matching."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -49,20 +40,21 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(hour=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, dt_util.utcnow().replace(hour=0))
await hass.async_block_till_done()
assert 1 == len(calls)
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
fire_time_changed(self.hass, dt_util.utcnow().replace(hour=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
async_fire_time_changed(hass, dt_util.utcnow().replace(hour=0))
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_when_minute_matches(self):
async def test_if_fires_when_minute_matches(hass, calls):
"""Test for firing if minutes are matching."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -74,14 +66,15 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(minute=0))
async_fire_time_changed(hass, dt_util.utcnow().replace(minute=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_when_second_matches(self):
async def test_if_fires_when_second_matches(hass, calls):
"""Test for firing if seconds are matching."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -93,14 +86,15 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(second=0))
async_fire_time_changed(hass, dt_util.utcnow().replace(second=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_when_all_matches(self):
async def test_if_fires_when_all_matches(hass, calls):
"""Test for firing if everything matches."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -114,15 +108,16 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=1, minute=2, second=3))
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_periodic_seconds(self):
async def test_if_fires_periodic_seconds(hass, calls):
"""Test for firing periodically every second."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -134,15 +129,16 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=0, minute=0, second=2))
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_periodic_minutes(self):
async def test_if_fires_periodic_minutes(hass, calls):
"""Test for firing periodically every minute."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -154,15 +150,16 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=0, minute=2, second=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_periodic_hours(self):
async def test_if_fires_periodic_hours(hass, calls):
"""Test for firing periodically every hour."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -174,15 +171,16 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=2, minute=0, second=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
await hass.async_block_till_done()
assert 1 == len(calls)
def test_if_fires_using_at(self):
async def test_if_fires_using_at(hass, calls):
"""Test for firing at."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -198,17 +196,18 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=5, minute=0, second=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
assert 'time - 5' == self.calls[0].data['some']
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'time - 5' == calls[0].data['some']
def test_if_not_working_if_no_values_in_conf_provided(self):
async def test_if_not_working_if_no_values_in_conf_provided(hass, calls):
"""Test for failure if no configuration."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -219,19 +218,20 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=5, minute=0, second=0))
self.hass.block_till_done()
assert 0 == len(self.calls)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_not_fires_using_wrong_at(self):
async def test_if_not_fires_using_wrong_at(hass, calls):
"""YAML translates time values to total seconds.
This should break the before rule.
"""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
@ -244,15 +244,16 @@ class TestAutomationTime(unittest.TestCase):
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=1, minute=0, second=5))
self.hass.block_till_done()
assert 0 == len(self.calls)
await hass.async_block_till_done()
assert 0 == len(calls)
def test_if_action_before(self):
async def test_if_action_before(hass, calls):
"""Test for if action before."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -273,21 +274,22 @@ class TestAutomationTime(unittest.TestCase):
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=before_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=after_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_action_after(self):
async def test_if_action_after(hass, calls):
"""Test for if action after."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -308,21 +310,22 @@ class TestAutomationTime(unittest.TestCase):
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=before_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 0 == len(self.calls)
assert 0 == len(calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=after_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_action_one_weekday(self):
async def test_if_action_one_weekday(hass, calls):
"""Test for if action with one weekday."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -344,21 +347,22 @@ class TestAutomationTime(unittest.TestCase):
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=monday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=tuesday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_action_list_weekday(self):
async def test_if_action_list_weekday(hass, calls):
"""Test for action with a list of weekdays."""
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -381,21 +385,21 @@ class TestAutomationTime(unittest.TestCase):
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=monday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=tuesday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 2 == len(self.calls)
assert 2 == len(calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=wednesday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 2 == len(self.calls)
assert 2 == len(calls)

View file

@ -1,54 +1,44 @@
"""The tests for the location automation."""
import unittest
import pytest
from homeassistant.core import Context, callback
from homeassistant.setup import setup_component
from homeassistant.core import Context
from homeassistant.setup import async_setup_component
from homeassistant.components import automation, zone
from tests.common import get_test_home_assistant, mock_component
from tests.components.automation import common
from tests.common import async_mock_service, mock_component
# pylint: disable=invalid-name
class TestAutomationZone(unittest.TestCase):
"""Test the event automation."""
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
return async_mock_service(hass, 'test', 'automation')
def setUp(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'group')
assert setup_component(self.hass, zone.DOMAIN, {
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
mock_component(hass, 'group')
hass.loop.run_until_complete(async_setup_component(hass, zone.DOMAIN, {
'zone': {
'name': 'test',
'latitude': 32.880837,
'longitude': -117.237561,
'radius': 250,
}
})
}))
self.calls = []
@callback
def record_call(service):
"""Record calls."""
self.calls.append(service)
self.hass.services.register('test', 'automation', record_call)
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
def test_if_fires_on_zone_enter(self):
async def test_if_fires_on_zone_enter(hass, calls):
"""Test for firing on zone enter."""
context = Context()
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'zone',
@ -69,44 +59,45 @@ class TestAutomationZone(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
}, context=context)
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
assert 1 == len(calls)
assert calls[0].context is context
assert 'zone - test.entity - hello - hello - test' == \
self.calls[0].data['some']
calls[0].data['some']
# Set out of zone again so we can trigger call
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
common.turn_off(self.hass)
self.hass.block_till_done()
await common.async_turn_off(hass)
await hass.async_block_till_done()
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_not_fires_for_enter_on_zone_leave(self):
async def test_if_not_fires_for_enter_on_zone_leave(hass, calls):
"""Test for not firing on zone leave."""
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'zone',
@ -120,23 +111,24 @@ class TestAutomationZone(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 0 == len(self.calls)
assert 0 == len(calls)
def test_if_fires_on_zone_leave(self):
async def test_if_fires_on_zone_leave(hass, calls):
"""Test for firing on zone leave."""
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'zone',
@ -150,23 +142,24 @@ class TestAutomationZone(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 1 == len(self.calls)
assert 1 == len(calls)
def test_if_not_fires_for_leave_on_zone_enter(self):
async def test_if_not_fires_for_leave_on_zone_enter(hass, calls):
"""Test for not firing on zone enter."""
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'zone',
@ -180,23 +173,24 @@ class TestAutomationZone(unittest.TestCase):
}
})
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert 0 == len(self.calls)
assert 0 == len(calls)
def test_zone_condition(self):
async def test_zone_condition(hass, calls):
"""Test for zone condition."""
self.hass.states.set('test.entity', 'hello', {
hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
@ -213,6 +207,6 @@ class TestAutomationZone(unittest.TestCase):
}
})
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)