Add automation config validation
* Add automation config validation * Remove unnecessary dict validator * Downgrade voluptuous to 0.8.9 * Fix linting * Address issues
This commit is contained in:
parent
cbe9a7d2a3
commit
8ef542927f
24 changed files with 570 additions and 443 deletions
|
@ -3,9 +3,9 @@ import unittest
|
|||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.components.automation as automation
|
||||
import homeassistant.components.automation.state as state
|
||||
|
||||
from tests.common import fire_time_changed, get_test_home_assistant
|
||||
|
||||
|
@ -16,6 +16,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.hass.config.components.append('group')
|
||||
self.hass.states.set('test.entity', 'hello')
|
||||
self.calls = []
|
||||
|
||||
|
@ -30,7 +31,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fires_on_entity_change(self):
|
||||
"""Test for firing on entity change."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -40,7 +41,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -48,7 +49,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fires_on_entity_change_with_from_filter(self):
|
||||
"""Test for firing on entity change with filter."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -59,7 +60,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -67,7 +68,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fires_on_entity_change_with_to_filter(self):
|
||||
"""Test for firing on entity change with no filter."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -78,7 +79,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -86,7 +87,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fires_on_entity_change_with_state_filter(self):
|
||||
"""Test for firing on entity change with state filter."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -97,7 +98,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -105,7 +106,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fires_on_entity_change_with_both_filters(self):
|
||||
"""Test for firing if both filters are a non match."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -117,7 +118,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -125,7 +126,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_not_fires_if_to_filter_not_match(self):
|
||||
"""Test for not firing if to filter is not a match."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -137,7 +138,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'moon')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -147,7 +148,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
"""Test for not firing if from filter is not a match."""
|
||||
self.hass.states.set('test.entity', 'bye')
|
||||
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -159,7 +160,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -167,7 +168,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_not_fires_if_entity_not_match(self):
|
||||
"""Test for not firing if entity is not matching."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -177,7 +178,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -187,7 +188,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
"""Test for to action."""
|
||||
entity_id = 'domain.test_entity'
|
||||
test_state = 'new_state'
|
||||
automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'event',
|
||||
|
@ -218,48 +219,68 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fails_setup_if_to_boolean_value(self):
|
||||
"""Test for setup failure for boolean to."""
|
||||
self.assertFalse(state.trigger(
|
||||
self.hass, {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'to': True,
|
||||
}, lambda x: x))
|
||||
assert not _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'to': True,
|
||||
},
|
||||
'action': {
|
||||
'service': 'homeassistant.turn_on',
|
||||
}
|
||||
}})
|
||||
|
||||
def test_if_fails_setup_if_from_boolean_value(self):
|
||||
"""Test for setup failure for boolean from."""
|
||||
self.assertFalse(state.trigger(
|
||||
self.hass, {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'from': True,
|
||||
}, lambda x: x))
|
||||
assert not _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'from': True,
|
||||
},
|
||||
'action': {
|
||||
'service': 'homeassistant.turn_on',
|
||||
}
|
||||
}})
|
||||
|
||||
def test_if_fails_setup_bad_for(self):
|
||||
"""Test for setup failure for bad for."""
|
||||
self.assertFalse(state.trigger(
|
||||
self.hass, {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'to': 'world',
|
||||
'for': {
|
||||
'invalid': 5
|
||||
assert not _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'to': 'world',
|
||||
'for': {
|
||||
'invalid': 5
|
||||
},
|
||||
},
|
||||
}, lambda x: x))
|
||||
'action': {
|
||||
'service': 'homeassistant.turn_on',
|
||||
}
|
||||
}})
|
||||
|
||||
def test_if_fails_setup_for_without_to(self):
|
||||
"""Test for setup failures for missing to."""
|
||||
self.assertFalse(state.trigger(
|
||||
self.hass, {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'for': {
|
||||
'seconds': 5
|
||||
assert not _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'for': {
|
||||
'seconds': 5
|
||||
},
|
||||
},
|
||||
}, lambda x: x))
|
||||
'action': {
|
||||
'service': 'homeassistant.turn_on',
|
||||
}
|
||||
}})
|
||||
|
||||
def test_if_not_fires_on_entity_change_with_for(self):
|
||||
"""Test for not firing on entity change with for."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -273,7 +294,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -285,7 +306,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fires_on_entity_change_with_for(self):
|
||||
"""Test for firing on entity change with for."""
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'state',
|
||||
|
@ -299,7 +320,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
'service': 'test.automation'
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
self.hass.states.set('test.entity', 'world')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -314,7 +335,7 @@ class TestAutomationState(unittest.TestCase):
|
|||
with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow:
|
||||
mock_utcnow.return_value = point1
|
||||
self.hass.states.set('test.entity', 'on')
|
||||
self.assertTrue(automation.setup(self.hass, {
|
||||
assert _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'event',
|
||||
|
@ -328,12 +349,9 @@ class TestAutomationState(unittest.TestCase):
|
|||
'seconds': 5
|
||||
},
|
||||
},
|
||||
|
||||
'action': {
|
||||
'service': 'test.automation'
|
||||
}
|
||||
'action': {'service': 'test.automation'},
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
# not enough time has passed
|
||||
self.hass.bus.fire('test_event')
|
||||
|
@ -348,21 +366,32 @@ class TestAutomationState(unittest.TestCase):
|
|||
|
||||
def test_if_fails_setup_for_without_time(self):
|
||||
"""Test for setup failure if no time is provided."""
|
||||
self.assertIsNone(state.if_action(
|
||||
self.hass, {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'state': 'on',
|
||||
'for': {},
|
||||
}))
|
||||
assert not _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {
|
||||
'platform': 'event',
|
||||
'event_type': 'bla'
|
||||
},
|
||||
'condition': {
|
||||
'platform': 'state',
|
||||
'entity_id': 'test.entity',
|
||||
'state': 'on',
|
||||
'for': {},
|
||||
},
|
||||
'action': {'service': 'test.automation'},
|
||||
}})
|
||||
|
||||
def test_if_fails_setup_for_without_entity(self):
|
||||
"""Test for setup failure if no entity is provided."""
|
||||
self.assertIsNone(state.if_action(
|
||||
self.hass, {
|
||||
'platform': 'state',
|
||||
'state': 'on',
|
||||
'for': {
|
||||
'seconds': 5
|
||||
assert not _setup_component(self.hass, automation.DOMAIN, {
|
||||
automation.DOMAIN: {
|
||||
'trigger': {'event_type': 'bla'},
|
||||
'condition': {
|
||||
'platform': 'state',
|
||||
'state': 'on',
|
||||
'for': {
|
||||
'seconds': 5
|
||||
},
|
||||
},
|
||||
}))
|
||||
'action': {'service': 'test.automation'},
|
||||
}})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue