async def test_call_with_sync_func(hass, mock_entities): """Test invoking sync service calls.""" test_service_mock = Mock(return_value=None) await service.entity_service_call( hass, [Mock(entities=mock_entities)], test_service_mock, ha.ServiceCall("test_domain", "test_service", {"entity_id": "light.kitchen"}), ) assert test_service_mock.call_count == 1
async def test_call_with_omit_entity_id(hass, mock_handle_entity_call, mock_entities): """Check service call if we do not pass an entity ID.""" await service.entity_service_call( hass, [Mock(entities=mock_entities)], Mock(), ha.ServiceCall("test_domain", "test_service"), ) assert len(mock_handle_entity_call.mock_calls) == 0
def test_extract_entity_ids(self): """Test extract_entity_ids method.""" self.hass.states.set('light.Bowl', STATE_ON) self.hass.states.set('light.Ceiling', STATE_OFF) self.hass.states.set('light.Kitchen', STATE_OFF) loader.get_component('group').Group.create_group( self.hass, 'test', ['light.Ceiling', 'light.Kitchen']) call = ha.ServiceCall('light', 'turn_on', {ATTR_ENTITY_ID: 'light.Bowl'}) self.assertEqual(['light.bowl'], service.extract_entity_ids(self.hass, call)) call = ha.ServiceCall('light', 'turn_on', {ATTR_ENTITY_ID: 'group.test'}) self.assertEqual(['light.ceiling', 'light.kitchen'], service.extract_entity_ids(self.hass, call))
async def test_extract_from_service_area_id(hass, area_mock): """Test the extraction using area ID as reference.""" entities = [ MockEntity(name="in_area", entity_id="light.in_area"), MockEntity(name="no_area", entity_id="light.no_area"), MockEntity(name="diff_area", entity_id="light.diff_area"), ] call = ha.ServiceCall("light", "turn_on", {"area_id": "test-area"}) extracted = await service.async_extract_entities(hass, entities, call) assert len(extracted) == 1 assert extracted[0].entity_id == "light.in_area" call = ha.ServiceCall("light", "turn_on", {"area_id": ["test-area", "diff-area"]}) extracted = await service.async_extract_entities(hass, entities, call) assert len(extracted) == 2 assert sorted(ent.entity_id for ent in extracted) == [ "light.diff_area", "light.in_area", ]
def test_extract_from_service_returns_all_if_no_entity_id(self): component = EntityComponent(_LOGGER, DOMAIN, self.hass) component.add_entities([ EntityTest(name='test_1'), EntityTest(name='test_2'), ]) call = ha.ServiceCall('test', 'service') assert ['test_domain.test_1', 'test_domain.test_2'] == \ sorted(ent.entity_id for ent in component.extract_from_service(call))
async def test_current_entity_context(hass, mock_entities): """Test we set the current entity context var.""" async def mock_service(entity, call): assert entity.entity_id == service.async_get_current_entity() await service.entity_service_call( hass, [Mock(entities=mock_entities)], mock_service, ha.ServiceCall("test_domain", "test_service", {"entity_id": "light.kitchen"}), )
async def test_call_with_required_features(hass, mock_entities): """Test service calls invoked only if entity has required feautres.""" test_service_mock = Mock(return_value=mock_coro()) await service.entity_service_call(hass, [Mock(entities=mock_entities)], test_service_mock, ha.ServiceCall('test_domain', 'test_service', {'entity_id': 'all'}), required_features=1) assert len(mock_entities) == 2 # Called once because only one of the entities had the required features assert test_service_mock.call_count == 1
def test_extract_from_service_no_group_expand(hass): """Test not expanding a group.""" component = EntityComponent(_LOGGER, DOMAIN, hass) test_group = yield from group.Group.async_create_group( hass, 'test_group', ['light.Ceiling', 'light.Kitchen']) yield from component.async_add_entities([test_group]) call = ha.ServiceCall('test', 'service', {'entity_id': ['group.test_group']}) extracted = component.async_extract_from_service(call, expand_group=False) assert extracted == [test_group]
async def test_extract_from_service_no_group_expand(hass): """Test not expanding a group.""" component = EntityComponent(_LOGGER, DOMAIN, hass) test_group = await group.Group.async_create_group( hass, "test_group", ["light.Ceiling", "light.Kitchen"] ) await component.async_add_entities([test_group]) call = ha.ServiceCall("test", "service", {"entity_id": ["group.test_group"]}) extracted = await component.async_extract_from_service(call, expand_group=False) assert extracted == [test_group]
async def test_extract_from_service_fails_if_no_entity_id(hass): """Test the extraction of everything from service.""" component = EntityComponent(_LOGGER, DOMAIN, hass) await component.async_add_entities( [MockEntity(name="test_1"), MockEntity(name="test_2")]) call = ha.ServiceCall("test", "service") assert [] == sorted( ent.entity_id for ent in (await component.async_extract_from_service(call)))
async def test_extract_all_omit_entity_id(hass, caplog): """Test extract all with None and *.""" component = EntityComponent(_LOGGER, DOMAIN, hass) await component.async_add_entities( [MockEntity(name="test_1"), MockEntity(name="test_2")]) call = ha.ServiceCall("test", "service") assert [] == sorted( ent.entity_id for ent in await component.async_extract_from_service(call))
async def test_extract_from_service_empty_if_no_entity_id(hass): """Test the extraction from service without specifying entity.""" entities = [ MockEntity(name="test_1", entity_id="test_domain.test_1"), MockEntity(name="test_2", entity_id="test_domain.test_2"), ] call = ha.ServiceCall("test", "service") assert [] == [ ent.entity_id for ent in (await service.async_extract_entities(hass, entities, call)) ]
async def test_call_no_context_target_specific( hass, mock_service_platform_call, mock_entities): """Check we can target specified entities.""" await service.entity_service_call(hass, [ Mock(entities=mock_entities) ], Mock(), ha.ServiceCall('test_domain', 'test_service', { 'entity_id': ['light.kitchen', 'light.non-existing'] })) assert len(mock_service_platform_call.mock_calls) == 1 entities = mock_service_platform_call.mock_calls[0][1][2] assert entities == [mock_entities['light.kitchen']]
def test_extract_from_service_no_group_expand(self): """Test not expanding a group.""" component = EntityComponent(_LOGGER, DOMAIN, self.hass) test_group = group.Group.create_group( self.hass, 'test_group', ['light.Ceiling', 'light.Kitchen']) component.add_entities([test_group]) call = ha.ServiceCall('test', 'service', {'entity_id': ['group.test_group']}) extracted = component.extract_from_service(call, expand_group=False) self.assertEqual([test_group], extracted)
async def test_extract_entity_ids_from_devices(hass, area_mock): """Test extract_entity_ids method with devices.""" assert await service.async_extract_entity_ids( hass, ha.ServiceCall("light", "turn_on", {"device_id": "device-no-area-id"})) == { "light.no_area", } assert await service.async_extract_entity_ids( hass, ha.ServiceCall("light", "turn_on", {"device_id": "device-area-a-id"})) == { "light.in_area_a", "light.in_area_b", } assert (await service.async_extract_entity_ids( hass, ha.ServiceCall("light", "turn_on", {"device_id": "non-existing-id"})) == set())
async def test_call_with_required_features(hass, mock_entities): """Test service calls invoked only if entity has required feautres.""" test_service_mock = AsyncMock(return_value=None) await service.entity_service_call( hass, [Mock(entities=mock_entities)], test_service_mock, ha.ServiceCall("test_domain", "test_service", {"entity_id": "all"}), required_features=[1], ) assert len(mock_entities) == 2 # Called once because only one of the entities had the required features assert test_service_mock.call_count == 1
def test_extract_from_service_filter_out_non_existing_entities(self): component = EntityComponent(_LOGGER, DOMAIN, self.hass) component.add_entities([ EntityTest(name='test_1'), EntityTest(name='test_2'), ]) call = ha.ServiceCall( 'test', 'service', {'entity_id': ['test_domain.test_2', 'test_domain.non_exist']}) assert ['test_domain.test_2'] == \ [ent.entity_id for ent in component.extract_from_service(call)]
async def test_extract_entity_ids(hass): """Test extract_entity_ids method.""" hass.states.async_set("light.Bowl", STATE_ON) hass.states.async_set("light.Ceiling", STATE_OFF) hass.states.async_set("light.Kitchen", STATE_OFF) await hass.components.group.Group.async_create_group( hass, "test", ["light.Ceiling", "light.Kitchen"]) call = ha.ServiceCall("light", "turn_on", {ATTR_ENTITY_ID: "light.Bowl"}) assert {"light.bowl"} == await service.async_extract_entity_ids(hass, call) call = ha.ServiceCall("light", "turn_on", {ATTR_ENTITY_ID: "group.test"}) assert {"light.ceiling", "light.kitchen" } == await service.async_extract_entity_ids(hass, call) assert {"group.test" } == await service.async_extract_entity_ids(hass, call, expand_group=False)
async def test_call_with_omit_entity_id(hass, mock_service_platform_call, mock_entities, caplog): """Check we only target allowed entities if targetting all.""" await service.entity_service_call(hass, [ Mock(entities=mock_entities) ], Mock(), ha.ServiceCall('test_domain', 'test_service')) assert len(mock_service_platform_call.mock_calls) == 1 entities = mock_service_platform_call.mock_calls[0][1][2] assert entities == [ mock_entities['light.kitchen'], mock_entities['light.living_room']] assert ('Not passing an entity ID to a service to target ' 'all entities is deprecated') in caplog.text
async def test_extract_from_service_no_group_expand(hass): """Test not expanding a group.""" component = EntityComponent(_LOGGER, DOMAIN, hass) await component.async_add_entities( [MockEntity(entity_id="group.test_group")]) call = ha.ServiceCall("test", "service", {"entity_id": ["group.test_group"]}) extracted = await component.async_extract_from_service(call, expand_group=False) assert len(extracted) == 1 assert extracted[0].entity_id == "group.test_group"
async def test_extract_from_service_available_device(hass): """Test the extraction of entity from service and device is available.""" entities = [ MockEntity(name="test_1", entity_id="test_domain.test_1"), MockEntity(name="test_2", entity_id="test_domain.test_2", available=False), MockEntity(name="test_3", entity_id="test_domain.test_3"), MockEntity(name="test_4", entity_id="test_domain.test_4", available=False), ] call_1 = ha.ServiceCall("test", "service", data={"entity_id": ENTITY_MATCH_ALL}) assert ["test_domain.test_1", "test_domain.test_3"] == [ ent.entity_id for ent in (await service.async_extract_entities(hass, entities, call_1)) ] call_2 = ha.ServiceCall( "test", "service", data={"entity_id": ["test_domain.test_3", "test_domain.test_4"]}, ) assert ["test_domain.test_3"] == [ ent.entity_id for ent in (await service.async_extract_entities(hass, entities, call_2)) ] assert ( await service.async_extract_entities( hass, entities, ha.ServiceCall( "test", "service", data={"entity_id": ENTITY_MATCH_NONE}, ), ) == [] )
async def test_call_with_match_all(hass, mock_handle_entity_call, mock_entities, caplog): """Check we only target allowed entities if targeting all.""" await service.entity_service_call( hass, [Mock(entities=mock_entities)], Mock(), ha.ServiceCall("test_domain", "test_service", {"entity_id": "all"}), ) assert len(mock_handle_entity_call.mock_calls) == 4 assert [call[1][1] for call in mock_handle_entity_call.mock_calls ] == list(mock_entities.values())
def test_extract_from_service_returns_all_if_no_entity_id(hass): """Test the extraction of everything from service.""" component = EntityComponent(_LOGGER, DOMAIN, hass) yield from component.async_add_entities([ MockEntity(name='test_1'), MockEntity(name='test_2'), ]) call = ha.ServiceCall('test', 'service') assert ['test_domain.test_1', 'test_domain.test_2'] == \ sorted(ent.entity_id for ent in component.async_extract_from_service(call))
async def test_extract_entity_ids(hass): """Test extract_entity_ids method.""" hass.states.async_set('light.Bowl', STATE_ON) hass.states.async_set('light.Ceiling', STATE_OFF) hass.states.async_set('light.Kitchen', STATE_OFF) await loader.get_component(hass, 'group').Group.async_create_group( hass, 'test', ['light.Ceiling', 'light.Kitchen']) call = ha.ServiceCall('light', 'turn_on', {ATTR_ENTITY_ID: 'light.Bowl'}) assert {'light.bowl'} == \ await service.async_extract_entity_ids(hass, call) call = ha.ServiceCall('light', 'turn_on', {ATTR_ENTITY_ID: 'group.test'}) assert {'light.ceiling', 'light.kitchen'} == \ await service.async_extract_entity_ids(hass, call) assert {'group.test'} == await service.async_extract_entity_ids( hass, call, expand_group=False)
async def test_extract_from_service_fails_if_no_entity_id(hass): """Test the extraction of everything from service.""" component = EntityComponent(_LOGGER, DOMAIN, hass) await component.async_add_entities( [MockEntity(name="test_1"), MockEntity(name="test_2")] ) assert ( await component.async_extract_from_service(ha.ServiceCall("test", "service")) == [] ) assert ( await component.async_extract_from_service( ha.ServiceCall("test", "service", {"entity_id": ENTITY_MATCH_NONE}) ) == [] ) assert ( await component.async_extract_from_service( ha.ServiceCall("test", "service", {"area_id": ENTITY_MATCH_NONE}) ) == [] )
async def test_call_with_both_required_features(hass, mock_entities): """Test service calls invoked only if entity has both features.""" test_service_mock = AsyncMock(return_value=None) await service.entity_service_call( hass, [Mock(entities=mock_entities)], test_service_mock, ha.ServiceCall("test_domain", "test_service", {"entity_id": "all"}), required_features=[SUPPORT_A | SUPPORT_B], ) assert test_service_mock.call_count == 1 assert [call[0][0] for call in test_service_mock.call_args_list ] == [mock_entities["light.bedroom"]]
def test_extract_from_service_available_device(hass): """Test the extraction of entity from service and device is available.""" component = EntityComponent(_LOGGER, DOMAIN, hass) yield from component.async_add_entities([ MockEntity(name='test_1'), MockEntity(name='test_2', available=False), MockEntity(name='test_3'), MockEntity(name='test_4', available=False), ]) call_1 = ha.ServiceCall('test', 'service') assert ['test_domain.test_1', 'test_domain.test_3'] == \ sorted(ent.entity_id for ent in component.async_extract_from_service(call_1)) call_2 = ha.ServiceCall('test', 'service', data={ 'entity_id': ['test_domain.test_3', 'test_domain.test_4'], }) assert ['test_domain.test_3'] == \ sorted(ent.entity_id for ent in component.async_extract_from_service(call_2))
async def test_extract_all_use_match_all(hass, caplog): """Test extract all with None and *.""" component = EntityComponent(_LOGGER, DOMAIN, hass) await component.async_add_entities( [MockEntity(name="test_1"), MockEntity(name="test_2")]) call = ha.ServiceCall("test", "service", {"entity_id": "all"}) assert ["test_domain.test_1", "test_domain.test_2"] == sorted( ent.entity_id for ent in await component.async_extract_from_service(call)) assert ("Not passing an entity ID to a service to target all entities is " "deprecated") not in caplog.text
async def test_call_context_user_not_exist(hass): """Check we don't allow deleted users to do things.""" with pytest.raises(exceptions.UnknownUser) as err: await service.entity_service_call( hass, [], Mock(), ha.ServiceCall( "test_domain", "test_service", context=ha.Context(user_id="non-existing"), ), ) assert err.value.context.user_id == "non-existing"
async def test_call_no_context_target_all(hass, mock_handle_entity_call, mock_entities): """Check we target all if no user context given.""" await service.entity_service_call( hass, [Mock(entities=mock_entities)], Mock(), ha.ServiceCall("test_domain", "test_service", data={"entity_id": ENTITY_MATCH_ALL}), ) assert len(mock_handle_entity_call.mock_calls) == 4 assert [call[1][1] for call in mock_handle_entity_call.mock_calls ] == list(mock_entities.values())