async def test_update_state_adds_entities_with_update_before_add_false(hass):
    """Test if not call update before add to state machine."""
    component = EntityComponent(_LOGGER, DOMAIN, hass)

    ent = MockEntity()
    ent.update = Mock(spec_set=True)

    await component.async_add_entities([ent], False)
    await hass.async_block_till_done()

    assert len(hass.states.async_entity_ids()) == 1
    assert not ent.update.called
    def test_update_state_adds_entities_with_update_before_add_false(self):
        """Test if not call update before add to state machine."""
        component = EntityComponent(_LOGGER, DOMAIN, self.hass)

        ent = MockEntity()
        ent.update = Mock(spec_set=True)

        component.add_entities([ent], False)
        self.hass.block_till_done()

        assert 1 == len(self.hass.states.entity_ids())
        assert not ent.update.called
async def test_entity_disabled_by_integration(hass):
    """Test entity disabled by integration."""
    component = EntityComponent(_LOGGER, DOMAIN, hass, timedelta(seconds=20))

    entity_default = MockEntity(unique_id="default")
    entity_disabled = MockEntity(unique_id="disabled",
                                 entity_registry_enabled_default=False)

    await component.async_add_entities([entity_default, entity_disabled])

    assert entity_default.hass is not None
    assert entity_default.platform is not None
    assert entity_disabled.hass is None
    assert entity_disabled.platform is None

    registry = await hass.helpers.entity_registry.async_get_registry()

    entry_default = registry.async_get_or_create(DOMAIN, DOMAIN, "default")
    assert entry_default.disabled_by is None
    entry_disabled = registry.async_get_or_create(DOMAIN, DOMAIN, "disabled")
    assert entry_disabled.disabled_by == "integration"
 async def async_setup_entry(hass, config_entry, async_add_entities):
     """Mock setup entry method."""
     async_add_entities([
         # Invalid device info
         MockEntity(unique_id="abcd", device_info={}),
         # Valid device info
         MockEntity(
             unique_id="qwer",
             device_info={
                 "identifiers": {("hue", "1234")},
                 "connections": {("mac", "abcd")},
                 "manufacturer": "test-manuf",
                 "model": "test-model",
                 "name": "test-name",
                 "sw_version": "test-sw",
                 "entry_type": "service",
                 "via_device": ("hue", "via-id"),
             },
         ),
     ])
     return True
Example #5
0
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",
    ]
async def test_update_entity_require_restart(hass, client):
    """Test updating entity."""
    config_entry = MockConfigEntry(domain="test_platform")
    config_entry.add_to_hass(hass)
    mock_registry(
        hass,
        {
            "test_domain.world": RegistryEntry(
                config_entry_id=config_entry.entry_id,
                entity_id="test_domain.world",
                unique_id="1234",
                # Using component.async_add_entities is equal to platform "domain"
                platform="test_platform",
            )
        },
    )
    platform = MockEntityPlatform(hass)
    entity = MockEntity(unique_id="1234")
    await platform.async_add_entities([entity])

    state = hass.states.get("test_domain.world")
    assert state is not None

    # UPDATE DISABLED_BY TO NONE
    await client.send_json(
        {
            "id": 8,
            "type": "config/entity_registry/update",
            "entity_id": "test_domain.world",
            "disabled_by": None,
        }
    )

    msg = await client.receive_json()

    assert msg["result"] == {
        "entity_entry": {
            "config_entry_id": config_entry.entry_id,
            "device_id": None,
            "area_id": None,
            "disabled_by": None,
            "platform": "test_platform",
            "entity_id": "test_domain.world",
            "name": None,
            "icon": None,
            "original_name": None,
            "original_icon": None,
            "capabilities": None,
            "unique_id": "1234",
        },
        "require_restart": True,
    }
async def test_update_entity_no_changes(hass, client):
    """Test update entity with no changes."""
    mock_registry(
        hass,
        {
            "test_domain.world": RegistryEntry(
                entity_id="test_domain.world",
                unique_id="1234",
                # Using component.async_add_entities is equal to platform "domain"
                platform="test_platform",
                name="name of entity",
            )
        },
    )
    platform = MockEntityPlatform(hass)
    entity = MockEntity(unique_id="1234")
    await platform.async_add_entities([entity])

    state = hass.states.get("test_domain.world")
    assert state is not None
    assert state.name == "name of entity"

    await client.send_json(
        {
            "id": 6,
            "type": "config/entity_registry/update",
            "entity_id": "test_domain.world",
            "name": "name of entity",
        }
    )

    msg = await client.receive_json()

    assert msg["result"] == {
        "entity_entry": {
            "config_entry_id": None,
            "device_id": None,
            "area_id": None,
            "disabled_by": None,
            "platform": "test_platform",
            "entity_id": "test_domain.world",
            "name": "name of entity",
            "icon": None,
            "original_name": None,
            "original_icon": None,
            "capabilities": None,
            "unique_id": "1234",
        }
    }

    state = hass.states.get("test_domain.world")
    assert state.name == "name of entity"
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"
Example #9
0
 async def async_setup_entry(hass, config_entry, async_add_entities):
     """Mock setup entry method."""
     async_add_entities([
         # Valid device info, with homeassistant url
         MockEntity(
             unique_id="qwer",
             device_info={
                 "identifiers": {("mqtt", "1234")},
                 "configuration_url": None,
             },
         ),
     ])
     return True
Example #10
0
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},
            ),
        )
        == []
    )
Example #11
0
def test_name_which_conflict_with_registered(hass):
    """Test not generating conflicting entity ID based on name."""
    component = EntityComponent(_LOGGER, DOMAIN, hass)
    registry = mock_registry(hass)

    # Register test_domain.world
    registry.async_get_or_create(
        DOMAIN, 'test', '1234', suggested_object_id='world')

    yield from component.async_add_entities([
        MockEntity(name='world')])

    assert 'test_domain.world_2' in hass.states.async_entity_ids()
Example #12
0
def test_using_prescribed_entity_id_which_is_registered(hass):
    """Test not allowing predefined entity ID that already registered."""
    component = EntityComponent(_LOGGER, DOMAIN, hass)
    registry = mock_registry(hass)
    # Register test_domain.world
    registry.async_get_or_create(
        DOMAIN, 'test', '1234', suggested_object_id='world')

    # This entity_id will be rewritten
    yield from component.async_add_entities([
        MockEntity(entity_id='test_domain.world')])

    assert 'test_domain.world_2' in hass.states.async_entity_ids()
Example #13
0
 async def async_setup_entry(hass, config_entry, async_add_entities):
     """Mock setup entry method."""
     async_add_entities([
         # Valid device info, but invalid url
         MockEntity(
             unique_id="qwer",
             device_info={
                 "identifiers": {("hue", "1234")},
                 "configuration_url": "foo://192.168.0.100/config",
             },
         ),
     ])
     return True
async def test_extract_from_service_fails_if_no_entity_id(opp):
    """Test the extraction of everything from service."""
    component = EntityComponent(_LOGGER, DOMAIN, opp)
    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})
        )
        == []
    )
Example #15
0
 async def async_setup_entry(hass, config_entry, async_add_entities):
     """Mock setup entry method."""
     async_add_entities([
         # Invalid device info
         MockEntity(unique_id="abcd", device_info={}),
         # Valid device info
         MockEntity(
             unique_id="qwer",
             device_info={
                 "identifiers": {("hue", "1234")},
                 "configuration_url": "http://192.168.0.100/config",
                 "connections": {(dr.CONNECTION_NETWORK_MAC, "abcd")},
                 "manufacturer": "test-manuf",
                 "model": "test-model",
                 "name": "test-name",
                 "sw_version": "test-sw",
                 "suggested_area": "Heliport",
                 "entry_type": "service",
                 "via_device": ("hue", "via-id"),
             },
         ),
     ])
     return True
async def test_update_entity(hass):
    """Test that we can update an entity with the helper."""
    component = EntityComponent(_LOGGER, DOMAIN, hass)
    entity = MockEntity()
    entity.async_update_ha_state = Mock(return_value=mock_coro())
    await component.async_add_entities([entity])

    # Called as part of async_add_entities
    assert len(entity.async_update_ha_state.mock_calls) == 1

    await hass.helpers.entity_component.async_update_entity(entity.entity_id)

    assert len(entity.async_update_ha_state.mock_calls) == 2
    assert entity.async_update_ha_state.mock_calls[-1][1][0] is True
Example #17
0
 async def async_setup_entry(hass, config_entry, async_add_entities):
     """Mock setup entry method."""
     async_add_entities([
         MockEntity(
             unique_id="qwer",
             device_info={
                 "connections": {("mac", "abcd")},
                 "default_name": "default name 1",
                 "default_model": "default model 1",
                 "default_manufacturer": "default manufacturer 1",
             },
         )
     ])
     return True
Example #18
0
async def test_name_which_conflict_with_registered(hass):
    """Test not generating conflicting entity ID based on name."""
    component = EntityComponent(_LOGGER, DOMAIN, hass)
    registry = mock_registry(hass)

    # Register test_domain.world
    registry.async_get_or_create(DOMAIN,
                                 "test",
                                 "1234",
                                 suggested_object_id="world")

    await component.async_add_entities([MockEntity(name="world")])

    assert "test_domain.world_2" in hass.states.async_entity_ids()
Example #19
0
async def test_raise_error_on_update(hass):
    """Test the add entity if they raise an error on update."""
    updates = []
    component = EntityComponent(_LOGGER, DOMAIN, hass)
    entity1 = MockEntity(name="test_1")
    entity2 = MockEntity(name="test_2")

    def _raise():
        """Raise an exception."""
        raise AssertionError

    entity1.update = _raise
    entity2.update = lambda: updates.append(1)

    await component.async_add_entities([entity1, entity2], True)

    assert len(updates) == 1
    assert 1 in updates

    assert entity1.hass is None
    assert entity1.platform is None
    assert entity2.hass is not None
    assert entity2.platform is not None
Example #20
0
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))
Example #21
0
async def test_using_prescribed_entity_id_which_is_registered(hass):
    """Test not allowing predefined entity ID that already registered."""
    component = EntityComponent(_LOGGER, DOMAIN, hass)
    registry = mock_registry(hass)
    # Register test_domain.world
    registry.async_get_or_create(DOMAIN,
                                 "test",
                                 "1234",
                                 suggested_object_id="world")

    # This entity_id will be rewritten
    await component.async_add_entities(
        [MockEntity(entity_id="test_domain.world")])

    assert "test_domain.world_2" in hass.states.async_entity_ids()
Example #22
0
    def test_polling_updates_entities_with_exception(self):
        """Test the updated entities that not break with an exception."""
        component = EntityComponent(_LOGGER, DOMAIN, self.hass,
                                    timedelta(seconds=20))

        update_ok = []
        update_err = []

        def update_mock():
            """Mock normal update."""
            update_ok.append(None)

        def update_mock_err():
            """Mock error update."""
            update_err.append(None)
            raise AssertionError("Fake error update")

        ent1 = MockEntity(should_poll=True)
        ent1.update = update_mock_err
        ent2 = MockEntity(should_poll=True)
        ent2.update = update_mock
        ent3 = MockEntity(should_poll=True)
        ent3.update = update_mock
        ent4 = MockEntity(should_poll=True)
        ent4.update = update_mock

        component.add_entities([ent1, ent2, ent3, ent4])

        update_ok.clear()
        update_err.clear()

        fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=20))
        self.hass.block_till_done()

        assert len(update_ok) == 3
        assert len(update_err) == 1
Example #23
0
 async def async_setup_entry(hass, config_entry, async_add_entities):
     """Mock setup entry method."""
     async_add_entities([
         MockEntity(
             unique_id="qwer",
             device_info={
                 "identifiers": {("hue", "1234")},
                 "connections": {(dr.CONNECTION_NETWORK_MAC, "abcd")},
                 "name": "Device Bla",
             },
             has_entity_name=has_entity_name,
             name=entity_name,
         ),
     ])
     return True
async def test_update_entity(opp):
    """Test that we can update an entity with the helper."""
    component = EntityComponent(_LOGGER, DOMAIN, opp)
    entity = MockEntity()
    entity.async_write_op_state = Mock()
    entity.async_update_op_state = AsyncMock(return_value=None)
    await component.async_add_entities([entity])

    # Called as part of async_add_entities
    assert len(entity.async_write_op_state.mock_calls) == 1

    await opp.helpers.entity_component.async_update_entity(entity.entity_id)

    assert len(entity.async_update_op_state.mock_calls) == 1
    assert entity.async_update_op_state.mock_calls[-1][1][0] is True
async def test_register_entity_service(opp):
    """Test not expanding a group."""
    entity = MockEntity(entity_id=f"{DOMAIN}.entity")
    calls = []

    @ha.callback
    def appender(**kwargs):
        calls.append(kwargs)

    entity.async_called_by_service = appender

    component = EntityComponent(_LOGGER, DOMAIN, opp)
    await component.async_add_entities([entity])

    component.async_register_entity_service(
        "hello", {"some": str}, "async_called_by_service"
    )

    with pytest.raises(vol.Invalid):
        await opp.services.async_call(
            DOMAIN,
            "hello",
            {"entity_id": entity.entity_id, "invalid": "data"},
            blocking=True,
        )
        assert len(calls) == 0

    await opp.services.async_call(
        DOMAIN, "hello", {"entity_id": entity.entity_id, "some": "data"}, blocking=True
    )
    assert len(calls) == 1
    assert calls[0] == {"some": "data"}

    await opp.services.async_call(
        DOMAIN, "hello", {"entity_id": ENTITY_MATCH_ALL, "some": "data"}, blocking=True
    )
    assert len(calls) == 2
    assert calls[1] == {"some": "data"}

    await opp.services.async_call(
        DOMAIN, "hello", {"entity_id": ENTITY_MATCH_NONE, "some": "data"}, blocking=True
    )
    assert len(calls) == 2

    await opp.services.async_call(
        DOMAIN, "hello", {"area_id": ENTITY_MATCH_NONE, "some": "data"}, blocking=True
    )
    assert len(calls) == 2
async def test_update_entity_id(opp, client):
    """Test update entity id."""
    mock_registry(
        opp,
        {
            "test_domain.world":
            RegistryEntry(
                entity_id="test_domain.world",
                unique_id="1234",
                # Using component.async_add_entities is equal to platform "domain"
                platform="test_platform",
            )
        },
    )
    platform = MockEntityPlatform(opp)
    entity = MockEntity(unique_id="1234")
    await platform.async_add_entities([entity])

    assert opp.states.get("test_domain.world") is not None

    await client.send_json({
        "id": 6,
        "type": "config/entity_registry/update",
        "entity_id": "test_domain.world",
        "new_entity_id": "test_domain.planet",
    })

    msg = await client.receive_json()

    assert msg["result"] == {
        "entity_entry": {
            "config_entry_id": None,
            "device_id": None,
            "area_id": None,
            "disabled_by": None,
            "platform": "test_platform",
            "entity_id": "test_domain.planet",
            "name": None,
            "icon": None,
            "original_name": None,
            "original_icon": None,
            "capabilities": None,
            "unique_id": "1234",
        }
    }

    assert opp.states.get("test_domain.world") is None
    assert opp.states.get("test_domain.planet") is not None
Example #27
0
async def test_entity_registry_updates_invalid_entity_id(hass):
    """Test that we can't update to an invalid entity id."""
    registry = mock_registry(
        hass,
        {
            "test_domain.world": er.RegistryEntry(
                entity_id="test_domain.world",
                unique_id="1234",
                # Using component.async_add_entities is equal to platform "domain"
                platform="test_platform",
                name="Some name",
            ),
            "test_domain.existing": er.RegistryEntry(
                entity_id="test_domain.existing",
                unique_id="5678",
                platform="test_platform",
            ),
        },
    )
    platform = MockEntityPlatform(hass)
    entity = MockEntity(unique_id="1234")
    await platform.async_add_entities([entity])

    state = hass.states.get("test_domain.world")
    assert state is not None
    assert state.name == "Some name"

    with pytest.raises(ValueError):
        registry.async_update_entity(
            "test_domain.world", new_entity_id="test_domain.existing"
        )

    with pytest.raises(ValueError):
        registry.async_update_entity(
            "test_domain.world", new_entity_id="invalid_entity_id"
        )

    with pytest.raises(ValueError):
        registry.async_update_entity(
            "test_domain.world", new_entity_id="diff_domain.world"
        )

    await hass.async_block_till_done()
    await hass.async_block_till_done()

    assert hass.states.get("test_domain.world") is not None
    assert hass.states.get("invalid_entity_id") is None
    assert hass.states.get("diff_domain.world") is None
Example #28
0
async def test_update_entity_require_restart(hass, client):
    """Test updating entity."""
    entity_id = "test_domain.test_platform_1234"
    config_entry = MockConfigEntry(domain="test_platform")
    config_entry.add_to_hass(hass)
    platform = MockEntityPlatform(hass)
    platform.config_entry = config_entry
    entity = MockEntity(unique_id="1234")
    await platform.async_add_entities([entity])

    state = hass.states.get(entity_id)
    assert state is not None

    # UPDATE DISABLED_BY TO NONE
    await client.send_json(
        {
            "id": 8,
            "type": "config/entity_registry/update",
            "entity_id": entity_id,
            "disabled_by": None,
        }
    )

    msg = await client.receive_json()

    assert msg["result"] == {
        "entity_entry": {
            "area_id": None,
            "capabilities": None,
            "config_entry_id": config_entry.entry_id,
            "device_class": None,
            "device_id": None,
            "disabled_by": None,
            "entity_category": None,
            "entity_id": entity_id,
            "icon": None,
            "hidden_by": None,
            "has_entity_name": False,
            "name": None,
            "options": {},
            "original_device_class": None,
            "original_icon": None,
            "original_name": None,
            "platform": "test_platform",
            "unique_id": "1234",
        },
        "require_restart": True,
    }
def test_registry_respect_entity_disabled(hass):
    """Test that the registry respects entity disabled."""
    mock_registry(hass, {
        'test_domain.world': entity_registry.RegistryEntry(
            entity_id='test_domain.world',
            unique_id='1234',
            # Using component.async_add_entities is equal to platform "domain"
            platform='test_platform',
            disabled_by=entity_registry.DISABLED_USER
        )
    })
    platform = MockEntityPlatform(hass)
    entity = MockEntity(unique_id='1234')
    yield from platform.async_add_entities([entity])
    assert entity.entity_id is None
    assert hass.states.async_entity_ids() == []
async def test_enable_entity_disabled_device(hass, client, device_registry):
    """Test enabling entity of disabled device."""
    config_entry = MockConfigEntry(domain="test_platform")
    config_entry.add_to_hass(hass)

    device = device_registry.async_get_or_create(
        config_entry_id="1234",
        connections={("ethernet", "12:34:56:78:90:AB:CD:EF")},
        identifiers={("bridgeid", "0123")},
        manufacturer="manufacturer",
        model="model",
        disabled_by=DISABLED_USER,
    )

    mock_registry(
        hass,
        {
            "test_domain.world": RegistryEntry(
                config_entry_id=config_entry.entry_id,
                entity_id="test_domain.world",
                unique_id="1234",
                # Using component.async_add_entities is equal to platform "domain"
                platform="test_platform",
                device_id=device.id,
            )
        },
    )
    platform = MockEntityPlatform(hass)
    entity = MockEntity(unique_id="1234")
    await platform.async_add_entities([entity])

    state = hass.states.get("test_domain.world")
    assert state is not None

    # UPDATE DISABLED_BY TO NONE
    await client.send_json(
        {
            "id": 8,
            "type": "config/entity_registry/update",
            "entity_id": "test_domain.world",
            "disabled_by": None,
        }
    )

    msg = await client.receive_json()

    assert not msg["success"]