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 @bind_hass
def turn_on(hass, entity_id=None): async def async_turn_on(hass, entity_id=None):
"""Turn on specified automation or all.""" """Turn on specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} 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 @bind_hass
def turn_off(hass, entity_id=None): async def async_turn_off(hass, entity_id=None):
"""Turn off specified automation or all.""" """Turn off specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} 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 @bind_hass
def toggle(hass, entity_id=None): async def async_toggle(hass, entity_id=None):
"""Toggle specified automation or all.""" """Toggle specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} 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 @bind_hass
def trigger(hass, entity_id=None): async def async_trigger(hass, entity_id=None):
"""Trigger specified automation or all.""" """Trigger specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} 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 @bind_hass
def reload(hass): async def async_reload(hass):
"""Reload the automation from config.""" """Reload the automation from config."""
hass.services.call(DOMAIN, SERVICE_RELOAD) await hass.services.async_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)

View file

@ -1,175 +1,172 @@
"""The tests for the Event automation.""" """The tests for the Event automation."""
import unittest import pytest
from homeassistant.core import Context, callback from homeassistant.core import Context
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.automation as automation 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.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name @pytest.fixture
class TestAutomationEvent(unittest.TestCase): def calls(hass):
"""Test the event automation.""" """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 @pytest.fixture(autouse=True)
def record_call(service): def setup_comp(hass):
"""Record the call.""" """Initialize components."""
self.calls.append(service) mock_component(hass, 'group')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self): async def test_if_fires_on_event(hass, calls):
"""Stop everything that was started.""" """Test the firing of events."""
self.hass.stop() context = Context()
def test_if_fires_on_event(self): assert await async_setup_component(hass, automation.DOMAIN, {
"""Test the firing of events.""" automation.DOMAIN: {
context = Context() 'trigger': {
'platform': 'event',
assert setup_component(self.hass, automation.DOMAIN, { 'event_type': 'test_event',
automation.DOMAIN: { },
'trigger': { 'action': {
'platform': 'event', 'service': 'test.automation',
'event_type': 'test_event',
},
'action': {
'service': 'test.automation',
}
} }
}) }
})
self.hass.bus.fire('test_event', context=context) hass.bus.async_fire('test_event', context=context)
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
assert self.calls[0].context is context assert calls[0].context is context
common.turn_off(self.hass) await common.async_turn_off(hass)
self.hass.block_till_done() await hass.async_block_till_done()
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_fires_on_event_extra_data(self):
"""Test the firing of events still matches with event data.""" async def test_if_fires_on_event_extra_data(hass, calls):
assert setup_component(self.hass, automation.DOMAIN, { """Test the firing of events still matches with event data."""
automation.DOMAIN: { assert await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
}, 'event_type': 'test_event',
'action': { },
'service': 'test.automation', 'action': {
} 'service': 'test.automation',
} }
}) }
})
self.hass.bus.fire('test_event', {'extra_key': 'extra_data'}) hass.bus.async_fire('test_event', {'extra_key': 'extra_data'})
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
common.turn_off(self.hass) await common.async_turn_off(hass)
self.hass.block_till_done() await hass.async_block_till_done()
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_fires_on_event_with_data(self):
"""Test the firing of events with data.""" async def test_if_fires_on_event_with_data(hass, calls):
assert setup_component(self.hass, automation.DOMAIN, { """Test the firing of events with data."""
automation.DOMAIN: { assert await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
'event_data': {'some_attr': 'some_value'} 'event_type': 'test_event',
}, 'event_data': {'some_attr': 'some_value'}
'action': { },
'service': 'test.automation', 'action': {
} 'service': 'test.automation',
} }
}) }
})
self.hass.bus.fire('test_event', {'some_attr': 'some_value', hass.bus.async_fire('test_event', {'some_attr': 'some_value',
'another': 'value'}) 'another': 'value'})
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_fires_on_event_with_empty_data_config(self):
"""Test the firing of events with empty data config.
The frontend automation editor can produce configurations with an async def test_if_fires_on_event_with_empty_data_config(hass, calls):
empty dict for event_data instead of no key. """Test the firing of events with empty data config.
"""
assert setup_component(self.hass, automation.DOMAIN, { The frontend automation editor can produce configurations with an
automation.DOMAIN: { empty dict for event_data instead of no key.
'trigger': { """
'platform': 'event', assert await async_setup_component(hass, automation.DOMAIN, {
'event_type': 'test_event', automation.DOMAIN: {
'event_data': {} 'trigger': {
}, 'platform': 'event',
'action': { 'event_type': 'test_event',
'service': 'test.automation', 'event_data': {}
} },
'action': {
'service': 'test.automation',
} }
}) }
})
self.hass.bus.fire('test_event', {'some_attr': 'some_value', hass.bus.async_fire('test_event', {'some_attr': 'some_value',
'another': 'value'}) 'another': 'value'})
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_fires_on_event_with_nested_data(self):
"""Test the firing of events with nested data.""" async def test_if_fires_on_event_with_nested_data(hass, calls):
assert setup_component(self.hass, automation.DOMAIN, { """Test the firing of events with nested data."""
automation.DOMAIN: { assert await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
'event_data': { 'event_type': 'test_event',
'parent_attr': { 'event_data': {
'some_attr': 'some_value' 'parent_attr': {
} 'some_attr': 'some_value'
} }
},
'action': {
'service': 'test.automation',
} }
},
'action': {
'service': 'test.automation',
} }
}) }
})
self.hass.bus.fire('test_event', { hass.bus.async_fire('test_event', {
'parent_attr': { 'parent_attr': {
'some_attr': 'some_value', 'some_attr': 'some_value',
'another': 'value' 'another': 'value'
}
})
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_not_fires_if_event_data_not_matches(hass, calls):
"""Test firing of event if no match."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event',
'event_data': {'some_attr': 'some_value'}
},
'action': {
'service': 'test.automation',
} }
}) }
self.hass.block_till_done() })
assert 1 == len(self.calls)
def test_if_not_fires_if_event_data_not_matches(self): hass.bus.async_fire('test_event', {'some_attr': 'some_other_value'})
"""Test firing of event if no match.""" await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { assert 0 == len(calls)
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event',
'event_data': {'some_attr': 'some_value'}
},
'action': {
'service': 'test.automation',
}
}
})
self.hass.bus.fire('test_event', {'some_attr': 'some_other_value'})
self.hass.block_till_done()
assert 0 == len(self.calls)

View file

@ -1,268 +1,265 @@
"""The tests for the geo location trigger.""" """The tests for the geo location trigger."""
import unittest import pytest
from homeassistant.components import automation, zone from homeassistant.components import automation, zone
from homeassistant.core import callback, Context from homeassistant.core import Context
from homeassistant.setup import setup_component 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.components.automation import common
from tests.common import async_mock_service
class TestAutomationGeoLocation(unittest.TestCase): @pytest.fixture
"""Test the geo location trigger.""" 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.""" @pytest.fixture(autouse=True)
self.hass = get_test_home_assistant() def setup_comp(hass):
mock_component(self.hass, 'group') """Initialize components."""
assert setup_component(self.hass, zone.DOMAIN, { mock_component(hass, 'group')
hass.loop.run_until_complete(async_setup_component(hass, zone.DOMAIN, {
'zone': { 'zone': {
'name': 'test', 'name': 'test',
'latitude': 32.880837, 'latitude': 32.880837,
'longitude': -117.237561, 'longitude': -117.237561,
'radius': 250, 'radius': 250,
} }
}) }))
self.calls = []
@callback async def test_if_fires_on_zone_enter(hass, calls):
def record_call(service): """Test for firing on zone enter."""
"""Record calls.""" context = Context()
self.calls.append(service) hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
await hass.async_block_till_done()
self.hass.services.register('test', 'automation', record_call) assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
def tearDown(self): 'trigger': {
"""Stop everything that was started.""" 'platform': 'geo_location',
self.hass.stop() 'source': 'test_source',
'zone': 'zone.test',
def test_if_fires_on_zone_enter(self): 'event': 'enter',
"""Test for firing on zone enter.""" },
context = Context() 'action': {
self.hass.states.set('geo_location.entity', 'hello', { 'service': 'test.automation',
'latitude': 32.881011, 'data_template': {
'longitude': -117.234758, 'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'source': 'test_source' 'platform', 'entity_id',
}) 'from_state.state', 'to_state.state',
self.hass.block_till_done() 'zone.name'))
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'enter',
}, },
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id',
'from_state.state', 'to_state.state',
'zone.name'))
},
}
} }
}) }
})
self.hass.states.set('geo_location.entity', 'hello', { hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586, 'latitude': 32.880586,
'longitude': -117.237564 'longitude': -117.237564
}, context=context) }, context=context)
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
assert self.calls[0].context is context assert calls[0].context is context
assert 'geo_location - geo_location.entity - hello - hello - test' == \ 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 # 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, 'latitude': 32.881011,
'longitude': -117.234758 'longitude': -117.234758
}) })
self.hass.block_till_done() await hass.async_block_till_done()
common.turn_off(self.hass) await common.async_turn_off(hass)
self.hass.block_till_done() 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, 'latitude': 32.880586,
'longitude': -117.237564 '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):
"""Test for not firing on zone leave."""
self.hass.states.set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { async def test_if_not_fires_for_enter_on_zone_leave(hass, calls):
automation.DOMAIN: { """Test for not firing on zone leave."""
'trigger': { hass.states.async_set('geo_location.entity', 'hello', {
'platform': 'geo_location', 'latitude': 32.880586,
'source': 'test_source', 'longitude': -117.237564,
'zone': 'zone.test', 'source': 'test_source'
'event': 'enter', })
await hass.async_block_till_done()
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'enter',
},
'action': {
'service': 'test.automation',
}
}
})
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
await hass.async_block_till_done()
assert 0 == len(calls)
async def test_if_fires_on_zone_leave(hass, calls):
"""Test for firing on zone leave."""
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
await hass.async_block_till_done()
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
}
}
})
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_not_fires_for_leave_on_zone_enter(hass, calls):
"""Test for not firing on zone enter."""
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
await hass.async_block_till_done()
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
}
}
})
hass.states.async_set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
await hass.async_block_till_done()
assert 0 == len(calls)
async def test_if_fires_on_zone_appear(hass, calls):
"""Test for firing if entity appears in zone."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'enter',
},
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id',
'from_state.state', 'to_state.state',
'zone.name'))
}, },
'action': {
'service': 'test.automation',
}
} }
}) }
})
self.hass.states.set('geo_location.entity', 'hello', { # Entity appears in zone without previously existing outside the zone.
'latitude': 32.881011, context = Context()
'longitude': -117.234758 hass.states.async_set('geo_location.entity', 'hello', {
}) 'latitude': 32.880586,
self.hass.block_till_done() 'longitude': -117.237564,
'source': 'test_source'
}, context=context)
await hass.async_block_till_done()
assert 0 == len(self.calls) assert 1 == len(calls)
assert calls[0].context is context
assert 'geo_location - geo_location.entity - - hello - test' == \
calls[0].data['some']
def test_if_fires_on_zone_leave(self):
"""Test for firing on zone leave."""
self.hass.states.set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { async def test_if_fires_on_zone_disappear(hass, calls):
automation.DOMAIN: { """Test for firing if entity disappears from zone."""
'trigger': { hass.states.async_set('geo_location.entity', 'hello', {
'platform': 'geo_location', 'latitude': 32.880586,
'source': 'test_source', 'longitude': -117.237564,
'zone': 'zone.test', 'source': 'test_source'
'event': 'leave', })
await hass.async_block_till_done()
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id',
'from_state.state', 'to_state.state',
'zone.name'))
}, },
'action': {
'service': 'test.automation',
}
} }
}) }
})
self.hass.states.set('geo_location.entity', 'hello', { # Entity disappears from zone without new coordinates outside the zone.
'latitude': 32.881011, hass.states.async_remove('geo_location.entity')
'longitude': -117.234758, await hass.async_block_till_done()
'source': 'test_source'
})
self.hass.block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
assert 'geo_location - geo_location.entity - hello - - test' == \
def test_if_not_fires_for_leave_on_zone_enter(self): calls[0].data['some']
"""Test for not firing on zone enter."""
self.hass.states.set('geo_location.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758,
'source': 'test_source'
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
}
}
})
self.hass.states.set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_fires_on_zone_appear(self):
"""Test for firing if entity appears in zone."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'enter',
},
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id',
'from_state.state', 'to_state.state',
'zone.name'))
},
}
}
})
# Entity appears in zone without previously existing outside the zone.
context = Context()
self.hass.states.set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
}, context=context)
self.hass.block_till_done()
assert 1 == len(self.calls)
assert self.calls[0].context is context
assert 'geo_location - geo_location.entity - - hello - test' == \
self.calls[0].data['some']
def test_if_fires_on_zone_disappear(self):
"""Test for firing if entity disappears from zone."""
self.hass.states.set('geo_location.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564,
'source': 'test_source'
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'geo_location',
'source': 'test_source',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id',
'from_state.state', 'to_state.state',
'zone.name'))
},
}
}
})
# Entity disappears from zone without new coordinates outside the zone.
self.hass.states.async_remove('geo_location.entity')
self.hass.block_till_done()
assert 1 == len(self.calls)
assert 'geo_location - geo_location.entity - hello - - test' == \
self.calls[0].data['some']

File diff suppressed because it is too large Load diff

View file

@ -1,102 +1,94 @@
"""The tests for the MQTT automation.""" """The tests for the MQTT automation."""
import unittest import pytest
from homeassistant.core import callback from homeassistant.setup import async_setup_component
from homeassistant.setup import setup_component
import homeassistant.components.automation as automation import homeassistant.components.automation as automation
from tests.common import ( from tests.common import (
mock_mqtt_component, fire_mqtt_message, get_test_home_assistant, async_fire_mqtt_message,
mock_component) mock_component, async_mock_service, async_mock_mqtt_component)
from tests.components.automation import common from tests.components.automation import common
# pylint: disable=invalid-name @pytest.fixture
class TestAutomationMQTT(unittest.TestCase): def calls(hass):
"""Test the event automation.""" """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 @pytest.fixture(autouse=True)
def record_call(service): def setup_comp(hass):
"""Record calls.""" """Initialize components."""
self.calls.append(service) 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): async def test_if_fires_on_topic_match(hass, calls):
"""Stop everything that was started.""" """Test if message is fired on topic match."""
self.hass.stop() assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
def test_if_fires_on_topic_match(self): 'trigger': {
"""Test if message is fired on topic match.""" 'platform': 'mqtt',
assert setup_component(self.hass, automation.DOMAIN, { 'topic': 'test-topic'
automation.DOMAIN: { },
'trigger': { 'action': {
'platform': 'mqtt', 'service': 'test.automation',
'topic': 'test-topic' 'data_template': {
'some': '{{ trigger.platform }} - {{ trigger.topic }}'
' - {{ trigger.payload }} - '
'{{ trigger.payload_json.hello }}'
}, },
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.platform }} - {{ trigger.topic }}'
' - {{ trigger.payload }} - '
'{{ trigger.payload_json.hello }}'
},
}
} }
}) }
})
fire_mqtt_message(self.hass, 'test-topic', '{ "hello": "world" }') async_fire_mqtt_message(hass, 'test-topic', '{ "hello": "world" }')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
assert 'mqtt - test-topic - { "hello": "world" } - world' == \ assert 'mqtt - test-topic - { "hello": "world" } - world' == \
self.calls[0].data['some'] calls[0].data['some']
common.turn_off(self.hass) await common.async_turn_off(hass)
self.hass.block_till_done() await hass.async_block_till_done()
fire_mqtt_message(self.hass, 'test-topic', 'test_payload') async_fire_mqtt_message(hass, 'test-topic', 'test_payload')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_fires_on_topic_and_payload_match(self):
"""Test if message is fired on topic and payload match.""" async def test_if_fires_on_topic_and_payload_match(hass, calls):
assert setup_component(self.hass, automation.DOMAIN, { """Test if message is fired on topic and payload match."""
automation.DOMAIN: { assert await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'mqtt', 'trigger': {
'topic': 'test-topic', 'platform': 'mqtt',
'payload': 'hello' 'topic': 'test-topic',
}, 'payload': 'hello'
'action': { },
'service': 'test.automation' 'action': {
} 'service': 'test.automation'
} }
}) }
})
fire_mqtt_message(self.hass, 'test-topic', 'hello') async_fire_mqtt_message(hass, 'test-topic', 'hello')
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_on_topic_but_no_payload_match(self):
"""Test if message is not fired on topic but no payload.""" async def test_if_not_fires_on_topic_but_no_payload_match(hass, calls):
assert setup_component(self.hass, automation.DOMAIN, { """Test if message is not fired on topic but no payload."""
automation.DOMAIN: { assert await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'mqtt', 'trigger': {
'topic': 'test-topic', 'platform': 'mqtt',
'payload': 'hello' 'topic': 'test-topic',
}, 'payload': 'hello'
'action': { },
'service': 'test.automation' 'action': {
} 'service': 'test.automation'
} }
}) }
})
fire_mqtt_message(self.hass, 'test-topic', 'no-hello') async_fire_mqtt_message(hass, 'test-topic', 'no-hello')
self.hass.block_till_done() await hass.async_block_till_done()
assert 0 == len(self.calls) assert 0 == len(calls)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,322 +1,319 @@
"""The tests for the sun automation.""" """The tests for the sun automation."""
from datetime import datetime from datetime import datetime
import unittest import pytest
from unittest.mock import patch from unittest.mock import patch
from homeassistant.core import callback from homeassistant.setup import async_setup_component
from homeassistant.setup import setup_component
from homeassistant.components import sun from homeassistant.components import sun
import homeassistant.components.automation as automation import homeassistant.components.automation as automation
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import ( 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 from tests.components.automation import common
# pylint: disable=invalid-name @pytest.fixture
class TestAutomationSun(unittest.TestCase): def calls(hass):
"""Test the sun automation.""" """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) 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)
def tearDown(self): with patch('homeassistant.util.dt.utcnow',
"""Stop everything that was started.""" return_value=now):
self.hass.stop() await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
'event': 'sunset',
},
'action': {
'service': 'test.automation',
}
}
})
def test_sunset_trigger(self): await common.async_turn_off(hass)
"""Test the sunset trigger.""" await hass.async_block_till_done()
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', async_fire_time_changed(hass, trigger_time)
return_value=now): await hass.async_block_till_done()
setup_component(self.hass, automation.DOMAIN, { assert 0 == len(calls)
automation.DOMAIN: {
'trigger': { with patch('homeassistant.util.dt.utcnow',
'platform': 'sun', return_value=now):
'event': 'sunset', await common.async_turn_on(hass)
await hass.async_block_till_done()
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 1 == len(calls)
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):
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
'event': 'sunrise',
},
'action': {
'service': 'test.automation',
}
}
})
async_fire_time_changed(hass, trigger_time)
await hass.async_block_till_done()
assert 1 == len(calls)
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):
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
'event': 'sunset',
'offset': '0:30:00'
},
'action': {
'service': 'test.automation',
'data_template': {
'some':
'{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'event', 'offset'))
}, },
'action': {
'service': 'test.automation',
}
}
})
common.turn_off(self.hass)
self.hass.block_till_done()
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 0 == len(self.calls)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
common.turn_on(self.hass)
self.hass.block_till_done()
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_sunrise_trigger(self):
"""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, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
'event': 'sunrise',
},
'action': {
'service': 'test.automation',
}
}
})
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_sunset_trigger_with_offset(self):
"""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, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
'event': 'sunset',
'offset': '0:30:00'
},
'action': {
'service': 'test.automation',
'data_template': {
'some':
'{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'event', 'offset'))
},
}
}
})
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']
def test_sunrise_trigger_with_offset(self):
"""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, {
automation.DOMAIN: {
'trigger': {
'platform': 'sun',
'event': 'sunrise',
'offset': '-0:30:00'
},
'action': {
'service': 'test.automation',
}
}
})
fire_time_changed(self.hass, trigger_time)
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_action_before(self):
"""Test if action was before."""
setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event',
},
'condition': {
'condition': 'sun',
'before': 'sunrise',
},
'action': {
'service': 'test.automation'
} }
} }
}) })
now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC) async_fire_time_changed(hass, trigger_time)
with patch('homeassistant.util.dt.utcnow', await hass.async_block_till_done()
return_value=now): assert 1 == len(calls)
self.hass.bus.fire('test_event') assert 'sun - sunset - 0:30:00' == calls[0].data['some']
self.hass.block_till_done()
assert 0 == len(self.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)
def test_if_action_after(self): async def test_sunrise_trigger_with_offset(hass, calls):
"""Test if action was after.""" """Test the sunrise trigger with offset."""
setup_component(self.hass, automation.DOMAIN, { 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):
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: { automation.DOMAIN: {
'trigger': { 'trigger': {
'platform': 'event', 'platform': 'sun',
'event_type': 'test_event', 'event': 'sunrise',
}, 'offset': '-0:30:00'
'condition': {
'condition': 'sun',
'after': 'sunrise',
}, },
'action': { 'action': {
'service': 'test.automation' 'service': 'test.automation',
} }
} }
}) })
now = datetime(2015, 9, 16, 13, tzinfo=dt_util.UTC) async_fire_time_changed(hass, trigger_time)
with patch('homeassistant.util.dt.utcnow', await hass.async_block_till_done()
return_value=now): assert 1 == len(calls)
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.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)
def test_if_action_before_with_offset(self): async def test_if_action_before(hass, calls):
"""Test if action was before offset.""" """Test if action was before."""
setup_component(self.hass, automation.DOMAIN, { await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: { automation.DOMAIN: {
'trigger': { 'trigger': {
'platform': 'event', 'platform': 'event',
'event_type': 'test_event', 'event_type': 'test_event',
}, },
'condition': { 'condition': {
'condition': 'sun', 'condition': 'sun',
'before': 'sunrise', 'before': 'sunrise',
'before_offset': '+1:00:00' },
}, 'action': {
'action': { 'service': 'test.automation'
'service': 'test.automation'
}
} }
}) }
})
now = datetime(2015, 9, 16, 14, 32, 44, tzinfo=dt_util.UTC) now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', with patch('homeassistant.util.dt.utcnow',
return_value=now): return_value=now):
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 0 == len(self.calls) assert 0 == len(calls)
now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC) now = datetime(2015, 9, 16, 10, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', with patch('homeassistant.util.dt.utcnow',
return_value=now): return_value=now):
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_action_after_with_offset(self):
"""Test if action was after offset.""" async def test_if_action_after(hass, calls):
setup_component(self.hass, automation.DOMAIN, { """Test if action was after."""
automation.DOMAIN: { await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
}, 'event_type': 'test_event',
'condition': { },
'condition': 'sun', 'condition': {
'after': 'sunrise', 'condition': 'sun',
'after_offset': '+1:00:00' 'after': 'sunrise',
}, },
'action': { 'action': {
'service': 'test.automation' 'service': 'test.automation'
}
} }
}) }
})
now = datetime(2015, 9, 16, 14, 32, 42, tzinfo=dt_util.UTC) now = datetime(2015, 9, 16, 13, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', with patch('homeassistant.util.dt.utcnow',
return_value=now): return_value=now):
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 0 == len(self.calls) assert 0 == len(calls)
now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC) now = datetime(2015, 9, 16, 15, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', with patch('homeassistant.util.dt.utcnow',
return_value=now): return_value=now):
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
def test_if_action_before_and_after_during(self):
"""Test if action was before and after during.""" async def test_if_action_before_with_offset(hass, calls):
setup_component(self.hass, automation.DOMAIN, { """Test if action was before offset."""
automation.DOMAIN: { await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
}, 'event_type': 'test_event',
'condition': { },
'condition': 'sun', 'condition': {
'after': 'sunrise', 'condition': 'sun',
'before': 'sunset' 'before': 'sunrise',
}, 'before_offset': '+1:00:00'
'action': { },
'service': 'test.automation' 'action': {
} 'service': 'test.automation'
} }
}) }
})
now = datetime(2015, 9, 16, 13, 8, 51, tzinfo=dt_util.UTC) now = datetime(2015, 9, 16, 14, 32, 44, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', with patch('homeassistant.util.dt.utcnow',
return_value=now): return_value=now):
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 0 == len(self.calls) assert 0 == len(calls)
now = datetime(2015, 9, 17, 2, 25, 18, tzinfo=dt_util.UTC) now = datetime(2015, 9, 16, 14, 32, 43, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', with patch('homeassistant.util.dt.utcnow',
return_value=now): return_value=now):
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 0 == len(self.calls) assert 1 == len(calls)
now = datetime(2015, 9, 16, 16, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', async def test_if_action_after_with_offset(hass, calls):
return_value=now): """Test if action was after offset."""
self.hass.bus.fire('test_event') await async_setup_component(hass, automation.DOMAIN, {
self.hass.block_till_done() automation.DOMAIN: {
assert 1 == len(self.calls) 'trigger': {
'platform': 'event',
'event_type': 'test_event',
},
'condition': {
'condition': 'sun',
'after': 'sunrise',
'after_offset': '+1:00:00'
},
'action': {
'service': 'test.automation'
}
}
})
now = datetime(2015, 9, 16, 14, 32, 42, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
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):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_action_before_and_after_during(hass, calls):
"""Test if action was before and after during."""
await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event',
},
'condition': {
'condition': 'sun',
'after': 'sunrise',
'before': 'sunset'
},
'action': {
'service': 'test.automation'
}
}
})
now = datetime(2015, 9, 16, 13, 8, 51, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow',
return_value=now):
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):
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):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)

View file

@ -1,44 +1,380 @@
"""The tests for the Template automation.""" """The tests for the Template automation."""
import unittest import pytest
from homeassistant.core import Context, callback from homeassistant.core import Context
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.automation as automation import homeassistant.components.automation as automation
from tests.common import ( from tests.common import (assert_setup_component, mock_component)
get_test_home_assistant, assert_setup_component, mock_component)
from tests.components.automation import common from tests.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name @pytest.fixture
class TestAutomationTemplate(unittest.TestCase): def calls(hass):
"""Test the event automation.""" """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 @pytest.fixture(autouse=True)
def record_call(service): def setup_comp(hass):
"""Record calls.""" """Initialize components."""
self.calls.append(service) mock_component(hass, 'group')
hass.states.async_set('test.entity', 'hello')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self): async def test_if_fires_on_change_bool(hass, calls):
"""Stop everything that was started.""" """Test for firing on boolean change."""
self.hass.stop() assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ true }}',
},
'action': {
'service': 'test.automation'
}
}
})
def test_if_fires_on_change_bool(self): hass.states.async_set('test.entity', 'world')
"""Test for firing on boolean change.""" await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { assert 1 == len(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)
async def test_if_fires_on_change_str(hass, calls):
"""Test for firing on change."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'true',
},
'action': {
'service': 'test.automation'
}
}
})
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_on_change_str_crazy(hass, calls):
"""Test for firing on change."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'TrUE',
},
'action': {
'service': 'test.automation'
}
}
})
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_not_fires_on_change_bool(hass, calls):
"""Test for not firing on boolean change."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ false }}',
},
'action': {
'service': 'test.automation'
}
}
})
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
async def test_if_not_fires_on_change_str(hass, calls):
"""Test for not firing on string change."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'False',
},
'action': {
'service': 'test.automation'
}
}
})
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
async def test_if_not_fires_on_change_str_crazy(hass, calls):
"""Test for not firing on string change."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'Anything other than "true" is false.',
},
'action': {
'service': 'test.automation'
}
}
})
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
async def test_if_fires_on_no_change(hass, calls):
"""Test for firing on no change."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ true }}',
},
'action': {
'service': 'test.automation'
}
}
})
await hass.async_block_till_done()
cur_len = len(calls)
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert cur_len == len(calls)
async def test_if_fires_on_two_change(hass, calls):
"""Test for firing on two changes."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ true }}',
},
'action': {
'service': 'test.automation'
}
}
})
# Trigger once
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
# Trigger again
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_on_change_with_template(hass, calls):
"""Test for firing on change with template."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ is_state("test.entity", "world") }}',
},
'action': {
'service': 'test.automation'
}
}
})
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_not_fires_on_change_with_template(hass, calls):
"""Test for not firing on change with template."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ is_state("test.entity", "hello") }}',
},
'action': {
'service': 'test.automation'
}
}
})
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert len(calls) == 0
async def test_if_fires_on_change_with_template_advanced(hass, calls):
"""Test for firing on change with template advanced."""
context = Context()
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ is_state("test.entity", "world") }}'
},
'action': {
'service': 'test.automation',
'data_template': {
'some':
'{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id', 'from_state.state',
'to_state.state'))
},
}
}
})
await hass.async_block_till_done()
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' == \
calls[0].data['some']
async def test_if_fires_on_no_change_with_template_advanced(hass, calls):
"""Test for firing on no change with template advanced."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '''{%- if is_state("test.entity", "world") -%}
true
{%- else -%}
false
{%- endif -%}''',
},
'action': {
'service': 'test.automation'
}
}
})
# Different state
hass.states.async_set('test.entity', 'worldz')
await hass.async_block_till_done()
assert 0 == len(calls)
# Different state
hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
assert 0 == len(calls)
async def test_if_fires_on_change_with_template_2(hass, calls):
"""Test for firing on change with template."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template':
'{{ not is_state("test.entity", "world") }}',
},
'action': {
'service': 'test.automation'
}
}
})
await hass.async_block_till_done()
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert len(calls) == 0
hass.states.async_set('test.entity', 'home')
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set('test.entity', 'work')
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set('test.entity', 'not_home')
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert len(calls) == 1
hass.states.async_set('test.entity', 'home')
await hass.async_block_till_done()
assert len(calls) == 2
async def test_if_action(hass, calls):
"""Test for firing if action."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event',
},
'condition': [{
'condition': 'template',
'value_template': '{{ is_state("test.entity", "world") }}'
}],
'action': {
'service': 'test.automation'
}
}
})
# Condition is not true yet
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
hass.states.async_set('test.entity', 'world')
await hass.async_block_till_done()
assert 0 == len(calls)
# Condition is true and event is triggered
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 1 == len(calls)
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 await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: { automation.DOMAIN: {
'trigger': { 'trigger': {
'platform': 'template', 'platform': 'template',
'value_template': '{{ true }}', 'value_template': '{{ ',
}, },
'action': { 'action': {
'service': 'test.automation' 'service': 'test.automation'
@ -46,388 +382,55 @@ class TestAutomationTemplate(unittest.TestCase):
} }
}) })
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
common.turn_off(self.hass) async def test_if_fires_on_change_with_bad_template_2(hass, calls):
self.hass.block_till_done() """Test for firing on change with bad template."""
assert await async_setup_component(hass, automation.DOMAIN, {
self.hass.states.set('test.entity', 'planet') automation.DOMAIN: {
self.hass.block_till_done() 'trigger': {
assert 1 == len(self.calls) 'platform': 'template',
'value_template': '{{ xyz | round(0) }}',
def test_if_fires_on_change_str(self): },
"""Test for firing on change.""" 'action': {
assert setup_component(self.hass, automation.DOMAIN, { 'service': 'test.automation'
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'true',
},
'action': {
'service': 'test.automation'
}
} }
}) }
})
self.hass.states.set('test.entity', 'world') hass.states.async_set('test.entity', 'world')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 0 == len(calls)
def test_if_fires_on_change_str_crazy(self):
"""Test for firing on change."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'TrUE',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.states.set('test.entity', 'world') async def test_wait_template_with_trigger(hass, calls):
self.hass.block_till_done() """Test using wait template with 'trigger.entity_id'."""
assert 1 == len(self.calls) assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template':
"{{ states.test.entity.state == 'world' }}",
},
'action': [
{'wait_template':
"{{ is_state(trigger.entity_id, 'hello') }}"},
{'service': 'test.automation',
'data_template': {
'some':
'{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id', 'from_state.state',
'to_state.state'))
}}
],
}
})
def test_if_not_fires_on_change_bool(self): await hass.async_block_till_done()
"""Test for not firing on boolean change."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ false }}',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.states.set('test.entity', 'world') hass.states.async_set('test.entity', 'world')
self.hass.block_till_done() await hass.async_block_till_done()
assert 0 == len(self.calls) hass.states.async_set('test.entity', 'hello')
await hass.async_block_till_done()
def test_if_not_fires_on_change_str(self): assert 1 == len(calls)
"""Test for not firing on string change.""" assert 'template - test.entity - hello - world' == \
assert setup_component(self.hass, automation.DOMAIN, { calls[0].data['some']
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'False',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_not_fires_on_change_str_crazy(self):
"""Test for not firing on string change."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': 'Anything other than "true" is false.',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_fires_on_no_change(self):
"""Test for firing on no change."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ true }}',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.block_till_done()
self.calls = []
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_fires_on_two_change(self):
"""Test for firing on two changes."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ true }}',
},
'action': {
'service': 'test.automation'
}
}
})
# Trigger once
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
# Trigger again
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_fires_on_change_with_template(self):
"""Test for firing on change with template."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ is_state("test.entity", "world") }}',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_not_fires_on_change_with_template(self):
"""Test for not firing on change with template."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ is_state("test.entity", "hello") }}',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.block_till_done()
self.calls = []
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert len(self.calls) == 0
def test_if_fires_on_change_with_template_advanced(self):
"""Test for firing on change with template advanced."""
context = Context()
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ is_state("test.entity", "world") }}'
},
'action': {
'service': 'test.automation',
'data_template': {
'some':
'{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id', 'from_state.state',
'to_state.state'))
},
}
}
})
self.hass.block_till_done()
self.calls = []
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
assert 'template - test.entity - hello - world' == \
self.calls[0].data['some']
def test_if_fires_on_no_change_with_template_advanced(self):
"""Test for firing on no change with template advanced."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '''{%- if is_state("test.entity", "world") -%}
true
{%- else -%}
false
{%- endif -%}''',
},
'action': {
'service': 'test.automation'
}
}
})
# Different state
self.hass.states.set('test.entity', 'worldz')
self.hass.block_till_done()
assert 0 == len(self.calls)
# Different state
self.hass.states.set('test.entity', 'hello')
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_fires_on_change_with_template_2(self):
"""Test for firing on change with template."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template':
'{{ not is_state("test.entity", "world") }}',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.block_till_done()
self.calls = []
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert len(self.calls) == 0
self.hass.states.set('test.entity', 'home')
self.hass.block_till_done()
assert len(self.calls) == 1
self.hass.states.set('test.entity', 'work')
self.hass.block_till_done()
assert len(self.calls) == 1
self.hass.states.set('test.entity', 'not_home')
self.hass.block_till_done()
assert len(self.calls) == 1
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert len(self.calls) == 1
self.hass.states.set('test.entity', 'home')
self.hass.block_till_done()
assert len(self.calls) == 2
def test_if_action(self):
"""Test for firing if action."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event',
},
'condition': [{
'condition': 'template',
'value_template': '{{ is_state("test.entity", "world") }}'
}],
'action': {
'service': 'test.automation'
}
}
})
# Condition is not true yet
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.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)
# Condition is true and event is triggered
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_fires_on_change_with_bad_template(self):
"""Test for firing on change with bad template."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ ',
},
'action': {
'service': 'test.automation'
}
}
})
def test_if_fires_on_change_with_bad_template_2(self):
"""Test for firing on change with bad template."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template': '{{ xyz | round(0) }}',
},
'action': {
'service': 'test.automation'
}
}
})
self.hass.states.set('test.entity', 'world')
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_wait_template_with_trigger(self):
"""Test using wait template with 'trigger.entity_id'."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'template',
'value_template':
"{{ states.test.entity.state == 'world' }}",
},
'action': [
{'wait_template':
"{{ is_state(trigger.entity_id, 'hello') }}"},
{'service': 'test.automation',
'data_template': {
'some':
'{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id', 'from_state.state',
'to_state.state'))
}}
],
}
})
self.hass.block_till_done()
self.calls = []
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)
assert 'template - test.entity - hello - world' == \
self.calls[0].data['some']

View file

@ -1,47 +1,216 @@
"""The tests for the time automation.""" """The tests for the time automation."""
from datetime import timedelta from datetime import timedelta
import unittest
from unittest.mock import patch from unittest.mock import patch
from homeassistant.core import callback import pytest
from homeassistant.setup import setup_component
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
import homeassistant.components.automation as automation import homeassistant.components.automation as automation
from tests.common import ( from tests.common import (
fire_time_changed, get_test_home_assistant, assert_setup_component, async_fire_time_changed, assert_setup_component, mock_component)
mock_component)
from tests.components.automation import common from tests.components.automation import common
from tests.common import async_mock_service
# pylint: disable=invalid-name @pytest.fixture
class TestAutomationTime(unittest.TestCase): def calls(hass):
"""Test the event automation.""" """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 @pytest.fixture(autouse=True)
def record_call(service): def setup_comp(hass):
"""Record calls.""" """Initialize components."""
self.calls.append(service) mock_component(hass, 'group')
self.hass.services.register('test', 'automation', record_call)
def tearDown(self): async def test_if_fires_when_hour_matches(hass, calls):
"""Stop everything that was started.""" """Test for firing if hour is matching."""
self.hass.stop() assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'hours': 0,
},
'action': {
'service': 'test.automation'
}
}
})
def test_if_fires_when_hour_matches(self): async_fire_time_changed(hass, dt_util.utcnow().replace(hour=0))
"""Test for firing if hour is matching.""" await hass.async_block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { assert 1 == len(calls)
await common.async_turn_off(hass)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow().replace(hour=0))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_when_minute_matches(hass, calls):
"""Test for firing if minutes are matching."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'minutes': 0,
},
'action': {
'service': 'test.automation'
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(minute=0))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_when_second_matches(hass, calls):
"""Test for firing if seconds are matching."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'seconds': 0,
},
'action': {
'service': 'test.automation'
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(second=0))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_when_all_matches(hass, calls):
"""Test for firing if everything matches."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'hours': 1,
'minutes': 2,
'seconds': 3,
},
'action': {
'service': 'test.automation'
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=1, minute=2, second=3))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_periodic_seconds(hass, calls):
"""Test for firing periodically every second."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'seconds': "/2",
},
'action': {
'service': 'test.automation'
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=0, minute=0, second=2))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_periodic_minutes(hass, calls):
"""Test for firing periodically every minute."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'minutes': "/2",
},
'action': {
'service': 'test.automation'
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=0, minute=2, second=0))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_periodic_hours(hass, calls):
"""Test for firing periodically every hour."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'hours': "/2",
},
'action': {
'service': 'test.automation'
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=2, minute=0, second=0))
await hass.async_block_till_done()
assert 1 == len(calls)
async def test_if_fires_using_at(hass, calls):
"""Test for firing at."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'at': '5:00:00',
},
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.platform }} - '
'{{ trigger.now.hour }}'
},
}
}
})
async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=5, minute=0, second=0))
await hass.async_block_till_done()
assert 1 == len(calls)
assert 'time - 5' == calls[0].data['some']
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 await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: { automation.DOMAIN: {
'trigger': { 'trigger': {
'platform': 'time', 'platform': 'time',
'hours': 0,
}, },
'action': { 'action': {
'service': 'test.automation' 'service': 'test.automation'
@ -49,24 +218,25 @@ class TestAutomationTime(unittest.TestCase):
} }
}) })
fire_time_changed(self.hass, dt_util.utcnow().replace(hour=0)) async_fire_time_changed(hass, dt_util.utcnow().replace(
self.hass.block_till_done() hour=5, minute=0, second=0))
assert 1 == len(self.calls)
common.turn_off(self.hass) await hass.async_block_till_done()
self.hass.block_till_done() assert 0 == len(calls)
fire_time_changed(self.hass, dt_util.utcnow().replace(hour=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_fires_when_minute_matches(self): async def test_if_not_fires_using_wrong_at(hass, calls):
"""Test for firing if minutes are matching.""" """YAML translates time values to total seconds.
assert setup_component(self.hass, automation.DOMAIN, {
This should break the before rule.
"""
with assert_setup_component(0):
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: { automation.DOMAIN: {
'trigger': { 'trigger': {
'platform': 'time', 'platform': 'time',
'minutes': 0, 'at': 3605,
# Total seconds. Hour = 3600 second
}, },
'action': { 'action': {
'service': 'test.automation' 'service': 'test.automation'
@ -74,328 +244,162 @@ class TestAutomationTime(unittest.TestCase):
} }
}) })
fire_time_changed(self.hass, dt_util.utcnow().replace(minute=0)) async_fire_time_changed(hass, dt_util.utcnow().replace(
hour=1, minute=0, second=5))
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 0 == len(calls)
def test_if_fires_when_second_matches(self):
"""Test for firing if seconds are matching.""" async def test_if_action_before(hass, calls):
assert setup_component(self.hass, automation.DOMAIN, { """Test for if action before."""
automation.DOMAIN: { assert await async_setup_component(hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'time', 'trigger': {
'seconds': 0, 'platform': 'event',
}, 'event_type': 'test_event'
'action': { },
'service': 'test.automation' 'condition': {
} 'condition': 'time',
'before': '10:00',
},
'action': {
'service': 'test.automation'
} }
}) }
})
fire_time_changed(self.hass, dt_util.utcnow().replace(second=0)) before_10 = dt_util.now().replace(hour=8)
after_10 = dt_util.now().replace(hour=14)
self.hass.block_till_done() with patch('homeassistant.helpers.condition.dt_util.now',
assert 1 == len(self.calls) return_value=before_10):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
def test_if_fires_when_all_matches(self): assert 1 == len(calls)
"""Test for firing if everything matches."""
assert setup_component(self.hass, automation.DOMAIN, { with patch('homeassistant.helpers.condition.dt_util.now',
automation.DOMAIN: { return_value=after_10):
'trigger': { hass.bus.async_fire('test_event')
'platform': 'time', await hass.async_block_till_done()
'hours': 1,
'minutes': 2, assert 1 == len(calls)
'seconds': 3,
},
'action': { async def test_if_action_after(hass, calls):
'service': 'test.automation' """Test for if action after."""
} assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'after': '10:00',
},
'action': {
'service': 'test.automation'
} }
}) }
})
fire_time_changed(self.hass, dt_util.utcnow().replace( before_10 = dt_util.now().replace(hour=8)
hour=1, minute=2, second=3)) after_10 = dt_util.now().replace(hour=14)
self.hass.block_till_done() with patch('homeassistant.helpers.condition.dt_util.now',
assert 1 == len(self.calls) return_value=before_10):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
def test_if_fires_periodic_seconds(self): assert 0 == len(calls)
"""Test for firing periodically every second."""
assert setup_component(self.hass, automation.DOMAIN, { with patch('homeassistant.helpers.condition.dt_util.now',
automation.DOMAIN: { return_value=after_10):
'trigger': { hass.bus.async_fire('test_event')
'platform': 'time', await hass.async_block_till_done()
'seconds': "/2",
}, assert 1 == len(calls)
'action': {
'service': 'test.automation'
} async def test_if_action_one_weekday(hass, calls):
"""Test for if action with one weekday."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'weekday': 'mon',
},
'action': {
'service': 'test.automation'
} }
}) }
})
fire_time_changed(self.hass, dt_util.utcnow().replace( days_past_monday = dt_util.now().weekday()
hour=0, minute=0, second=2)) monday = dt_util.now() - timedelta(days=days_past_monday)
tuesday = monday + timedelta(days=1)
self.hass.block_till_done() with patch('homeassistant.helpers.condition.dt_util.now',
assert 1 == len(self.calls) return_value=monday):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
def test_if_fires_periodic_minutes(self): assert 1 == len(calls)
"""Test for firing periodically every minute."""
assert setup_component(self.hass, automation.DOMAIN, { with patch('homeassistant.helpers.condition.dt_util.now',
automation.DOMAIN: { return_value=tuesday):
'trigger': { hass.bus.async_fire('test_event')
'platform': 'time', await hass.async_block_till_done()
'minutes': "/2",
}, assert 1 == len(calls)
'action': {
'service': 'test.automation'
} async def test_if_action_list_weekday(hass, calls):
"""Test for action with a list of weekdays."""
assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'weekday': ['mon', 'tue'],
},
'action': {
'service': 'test.automation'
} }
}) }
})
fire_time_changed(self.hass, dt_util.utcnow().replace( days_past_monday = dt_util.now().weekday()
hour=0, minute=2, second=0)) monday = dt_util.now() - timedelta(days=days_past_monday)
tuesday = monday + timedelta(days=1)
wednesday = tuesday + timedelta(days=1)
self.hass.block_till_done() with patch('homeassistant.helpers.condition.dt_util.now',
assert 1 == len(self.calls) return_value=monday):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
def test_if_fires_periodic_hours(self): assert 1 == len(calls)
"""Test for firing periodically every hour."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'hours': "/2",
},
'action': {
'service': 'test.automation'
}
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace( with patch('homeassistant.helpers.condition.dt_util.now',
hour=2, minute=0, second=0)) return_value=tuesday):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
self.hass.block_till_done() assert 2 == len(calls)
assert 1 == len(self.calls)
def test_if_fires_using_at(self): with patch('homeassistant.helpers.condition.dt_util.now',
"""Test for firing at.""" return_value=wednesday):
assert setup_component(self.hass, automation.DOMAIN, { hass.bus.async_fire('test_event')
automation.DOMAIN: { await hass.async_block_till_done()
'trigger': {
'platform': 'time',
'at': '5:00:00',
},
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.platform }} - '
'{{ trigger.now.hour }}'
},
}
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace( assert 2 == len(calls)
hour=5, minute=0, second=0))
self.hass.block_till_done()
assert 1 == len(self.calls)
assert 'time - 5' == self.calls[0].data['some']
def test_if_not_working_if_no_values_in_conf_provided(self):
"""Test for failure if no configuration."""
with assert_setup_component(0):
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
},
'action': {
'service': 'test.automation'
}
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
hour=5, minute=0, second=0))
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_not_fires_using_wrong_at(self):
"""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, {
automation.DOMAIN: {
'trigger': {
'platform': 'time',
'at': 3605,
# Total seconds. Hour = 3600 second
},
'action': {
'service': 'test.automation'
}
}
})
fire_time_changed(self.hass, dt_util.utcnow().replace(
hour=1, minute=0, second=5))
self.hass.block_till_done()
assert 0 == len(self.calls)
def test_if_action_before(self):
"""Test for if action before."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'before': '10:00',
},
'action': {
'service': 'test.automation'
}
}
})
before_10 = dt_util.now().replace(hour=8)
after_10 = dt_util.now().replace(hour=14)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=before_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=after_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_action_after(self):
"""Test for if action after."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'after': '10:00',
},
'action': {
'service': 'test.automation'
}
}
})
before_10 = dt_util.now().replace(hour=8)
after_10 = dt_util.now().replace(hour=14)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=before_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 0 == len(self.calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=after_10):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_action_one_weekday(self):
"""Test for if action with one weekday."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'weekday': 'mon',
},
'action': {
'service': 'test.automation'
}
}
})
days_past_monday = dt_util.now().weekday()
monday = dt_util.now() - timedelta(days=days_past_monday)
tuesday = monday + timedelta(days=1)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=monday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=tuesday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
def test_if_action_list_weekday(self):
"""Test for action with a list of weekdays."""
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'event',
'event_type': 'test_event'
},
'condition': {
'condition': 'time',
'weekday': ['mon', 'tue'],
},
'action': {
'service': 'test.automation'
}
}
})
days_past_monday = dt_util.now().weekday()
monday = dt_util.now() - timedelta(days=days_past_monday)
tuesday = monday + timedelta(days=1)
wednesday = tuesday + timedelta(days=1)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=monday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 1 == len(self.calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=tuesday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 2 == len(self.calls)
with patch('homeassistant.helpers.condition.dt_util.now',
return_value=wednesday):
self.hass.bus.fire('test_event')
self.hass.block_till_done()
assert 2 == len(self.calls)

View file

@ -1,218 +1,212 @@
"""The tests for the location automation.""" """The tests for the location automation."""
import unittest import pytest
from homeassistant.core import Context, callback from homeassistant.core import Context
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
from homeassistant.components import automation, zone from homeassistant.components import automation, zone
from tests.common import get_test_home_assistant, mock_component
from tests.components.automation import common from tests.components.automation import common
from tests.common import async_mock_service, mock_component
# pylint: disable=invalid-name @pytest.fixture
class TestAutomationZone(unittest.TestCase): def calls(hass):
"""Test the event automation.""" """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.""" @pytest.fixture(autouse=True)
self.hass = get_test_home_assistant() def setup_comp(hass):
mock_component(self.hass, 'group') """Initialize components."""
assert setup_component(self.hass, zone.DOMAIN, { mock_component(hass, 'group')
hass.loop.run_until_complete(async_setup_component(hass, zone.DOMAIN, {
'zone': { 'zone': {
'name': 'test', 'name': 'test',
'latitude': 32.880837, 'latitude': 32.880837,
'longitude': -117.237561, 'longitude': -117.237561,
'radius': 250, 'radius': 250,
} }
}) }))
self.calls = []
@callback async def test_if_fires_on_zone_enter(hass, calls):
def record_call(service): """Test for firing on zone enter."""
"""Record calls.""" context = Context()
self.calls.append(service) hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
await hass.async_block_till_done()
self.hass.services.register('test', 'automation', record_call) assert await async_setup_component(hass, automation.DOMAIN, {
automation.DOMAIN: {
def tearDown(self): 'trigger': {
"""Stop everything that was started.""" 'platform': 'zone',
self.hass.stop() 'entity_id': 'test.entity',
'zone': 'zone.test',
def test_if_fires_on_zone_enter(self): 'event': 'enter',
"""Test for firing on zone enter.""" },
context = Context() 'action': {
self.hass.states.set('test.entity', 'hello', { 'service': 'test.automation',
'latitude': 32.881011, 'data_template': {
'longitude': -117.234758 'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
}) 'platform', 'entity_id',
self.hass.block_till_done() 'from_state.state', 'to_state.state',
'zone.name'))
assert setup_component(self.hass, automation.DOMAIN, {
automation.DOMAIN: {
'trigger': {
'platform': 'zone',
'entity_id': 'test.entity',
'zone': 'zone.test',
'event': 'enter',
}, },
'action': {
'service': 'test.automation',
'data_template': {
'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join((
'platform', 'entity_id',
'from_state.state', 'to_state.state',
'zone.name'))
},
}
} }
}) }
})
self.hass.states.set('test.entity', 'hello', { hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586, 'latitude': 32.880586,
'longitude': -117.237564 'longitude': -117.237564
}, context=context) }, context=context)
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)
assert self.calls[0].context is context assert calls[0].context is context
assert 'zone - test.entity - hello - hello - test' == \ 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 # 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, 'latitude': 32.881011,
'longitude': -117.234758 'longitude': -117.234758
}) })
self.hass.block_till_done() await hass.async_block_till_done()
common.turn_off(self.hass) await common.async_turn_off(hass)
self.hass.block_till_done() await hass.async_block_till_done()
self.hass.states.set('test.entity', 'hello', { hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586, 'latitude': 32.880586,
'longitude': -117.237564 '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):
"""Test for not firing on zone leave."""
self.hass.states.set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { async def test_if_not_fires_for_enter_on_zone_leave(hass, calls):
automation.DOMAIN: { """Test for not firing on zone leave."""
'trigger': { hass.states.async_set('test.entity', 'hello', {
'platform': 'zone', 'latitude': 32.880586,
'entity_id': 'test.entity', 'longitude': -117.237564
'zone': 'zone.test', })
'event': 'enter', await hass.async_block_till_done()
},
'action': { assert await async_setup_component(hass, automation.DOMAIN, {
'service': 'test.automation', automation.DOMAIN: {
} 'trigger': {
'platform': 'zone',
'entity_id': 'test.entity',
'zone': 'zone.test',
'event': 'enter',
},
'action': {
'service': 'test.automation',
} }
}) }
})
self.hass.states.set('test.entity', 'hello', { hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011, 'latitude': 32.881011,
'longitude': -117.234758 '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):
"""Test for firing on zone leave."""
self.hass.states.set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { async def test_if_fires_on_zone_leave(hass, calls):
automation.DOMAIN: { """Test for firing on zone leave."""
'trigger': { hass.states.async_set('test.entity', 'hello', {
'platform': 'zone', 'latitude': 32.880586,
'entity_id': 'test.entity', 'longitude': -117.237564
'zone': 'zone.test', })
'event': 'leave', await hass.async_block_till_done()
},
'action': { assert await async_setup_component(hass, automation.DOMAIN, {
'service': 'test.automation', automation.DOMAIN: {
} 'trigger': {
'platform': 'zone',
'entity_id': 'test.entity',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
} }
}) }
})
self.hass.states.set('test.entity', 'hello', { hass.states.async_set('test.entity', 'hello', {
'latitude': 32.881011, 'latitude': 32.881011,
'longitude': -117.234758 '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):
"""Test for not firing on zone enter."""
self.hass.states.set('test.entity', 'hello', {
'latitude': 32.881011,
'longitude': -117.234758
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { async def test_if_not_fires_for_leave_on_zone_enter(hass, calls):
automation.DOMAIN: { """Test for not firing on zone enter."""
'trigger': { hass.states.async_set('test.entity', 'hello', {
'platform': 'zone', 'latitude': 32.881011,
'entity_id': 'test.entity', 'longitude': -117.234758
'zone': 'zone.test', })
'event': 'leave', await hass.async_block_till_done()
},
'action': { assert await async_setup_component(hass, automation.DOMAIN, {
'service': 'test.automation', automation.DOMAIN: {
} 'trigger': {
'platform': 'zone',
'entity_id': 'test.entity',
'zone': 'zone.test',
'event': 'leave',
},
'action': {
'service': 'test.automation',
} }
}) }
})
self.hass.states.set('test.entity', 'hello', { hass.states.async_set('test.entity', 'hello', {
'latitude': 32.880586, 'latitude': 32.880586,
'longitude': -117.237564 '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):
"""Test for zone condition."""
self.hass.states.set('test.entity', 'hello', {
'latitude': 32.880586,
'longitude': -117.237564
})
self.hass.block_till_done()
assert setup_component(self.hass, automation.DOMAIN, { async def test_zone_condition(hass, calls):
automation.DOMAIN: { """Test for zone condition."""
'trigger': { hass.states.async_set('test.entity', 'hello', {
'platform': 'event', 'latitude': 32.880586,
'event_type': 'test_event' 'longitude': -117.237564
}, })
'condition': { await hass.async_block_till_done()
'condition': 'zone',
'entity_id': 'test.entity', assert await async_setup_component(hass, automation.DOMAIN, {
'zone': 'zone.test', automation.DOMAIN: {
}, 'trigger': {
'action': { 'platform': 'event',
'service': 'test.automation', 'event_type': 'test_event'
} },
'condition': {
'condition': 'zone',
'entity_id': 'test.entity',
'zone': 'zone.test',
},
'action': {
'service': 'test.automation',
} }
}) }
})
self.hass.bus.fire('test_event') hass.bus.async_fire('test_event')
self.hass.block_till_done() await hass.async_block_till_done()
assert 1 == len(self.calls) assert 1 == len(calls)