def test_registry_respect_entity_namespace(hass): """Test that the registry respects entity namespace.""" mock_registry(hass) platform = MockEntityPlatform(hass, entity_namespace='ns') entity = MockEntity(unique_id='1234', name='Device Name') yield from platform.async_add_entities([entity]) assert entity.entity_id == 'test_domain.ns_device_name'
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_reset_cancels_retry_setup_when_not_started(hass): """Test that resetting a platform will cancel scheduled a setup retry when not yet started.""" hass.state = CoreState.starting async_setup_entry = Mock(side_effect=PlatformNotReady) initial_listeners = hass.bus.async_listeners()[EVENT_HOMEASSISTANT_STARTED] platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry() ent_platform = MockEntityPlatform( hass, platform_name=config_entry.domain, platform=platform ) assert not await ent_platform.async_setup_entry(config_entry) await hass.async_block_till_done() assert ( hass.bus.async_listeners()[EVENT_HOMEASSISTANT_STARTED] == initial_listeners + 1 ) assert ent_platform._async_cancel_retry_setup is not None await ent_platform.async_reset() await hass.async_block_till_done() assert hass.bus.async_listeners()[EVENT_HOMEASSISTANT_STARTED] == initial_listeners assert ent_platform._async_cancel_retry_setup is None
async def test_setup_entry_platform_not_ready_from_exception(hass, caplog): """Test when an entry is not ready yet that includes the causing exception string.""" original_exception = HomeAssistantError("The device dropped the connection") platform_exception = PlatformNotReady() platform_exception.__cause__ = original_exception async_setup_entry = Mock(side_effect=platform_exception) platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry() ent_platform = MockEntityPlatform( hass, platform_name=config_entry.domain, platform=platform ) with patch.object(entity_platform, "async_call_later") as mock_call_later: assert not await ent_platform.async_setup_entry(config_entry) full_name = f"{ent_platform.domain}.{config_entry.domain}" assert full_name not in hass.config.components assert len(async_setup_entry.mock_calls) == 1 assert "Platform test not ready yet" in caplog.text assert "The device dropped the connection" in caplog.text assert len(mock_call_later.mock_calls) == 1
async def test_setup_entry(opp): """Test we can setup an entry.""" registry = mock_registry(opp) async def async_setup_entry(opp, config_entry, async_add_entities): """Mock setup entry method.""" async_add_entities([MockEntity(name="test1", unique_id="unique")]) return True platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry(entry_id="super-mock-id") entity_platform = MockEntityPlatform(opp, platform_name=config_entry.domain, platform=platform) assert await entity_platform.async_setup_entry(config_entry) await opp.async_block_till_done() full_name = f"{entity_platform.domain}.{config_entry.domain}" assert full_name in opp.config.components assert len(opp.states.async_entity_ids()) == 1 assert len(registry.entities) == 1 assert registry.entities[ "test_domain.test1"].config_entry_id == "super-mock-id"
async def test_setup_entry(hass): """Test we can setup an entry.""" registry = mock_registry(hass) async def async_setup_entry(hass, config_entry, async_add_entities): """Mock setup entry method.""" async_add_entities([MockEntity(name='test1', unique_id='unique')]) return True platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry(entry_id='super-mock-id') entity_platform = MockEntityPlatform(hass, platform_name=config_entry.domain, platform=platform) assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() full_name = '{}.{}'.format(entity_platform.domain, config_entry.domain) assert full_name in hass.config.components assert len(hass.states.async_entity_ids()) == 1 assert len(registry.entities) == 1 assert registry.entities['test_domain.test1'].config_entry_id == \ 'super-mock-id'
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_id': 'test_domain.world', 'name': 'name of entity' } state = hass.states.get('test_domain.world') assert state.name == 'name of entity'
async def test_entity_disabled_by_device(hass: HomeAssistant): """Test entity disabled by device.""" connections = {(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")} entity_disabled = MockEntity( unique_id="disabled", device_info=DeviceInfo(connections=connections) ) async def async_setup_entry(hass, config_entry, async_add_entities): """Mock setup entry method.""" async_add_entities([entity_disabled]) return True platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry(entry_id="super-mock-id", domain=DOMAIN) entity_platform = MockEntityPlatform( hass, platform_name=config_entry.domain, platform=platform ) device_registry = dr.async_get(hass) device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, connections=connections, disabled_by=dr.DeviceEntryDisabler.USER, ) assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() assert entity_disabled.hass is None assert entity_disabled.platform is None registry = er.async_get(hass) entry_disabled = registry.async_get_or_create(DOMAIN, DOMAIN, "disabled") assert entry_disabled.disabled_by is er.RegistryEntryDisabler.DEVICE
async def test_reset_cancels_retry_setup(hass): """Test that resetting a platform will cancel scheduled a setup retry.""" async_setup_entry = Mock(side_effect=PlatformNotReady) platform = MockPlatform( async_setup_entry=async_setup_entry ) config_entry = MockConfigEntry() ent_platform = MockEntityPlatform( hass, platform_name=config_entry.domain, platform=platform ) with patch.object(entity_platform, 'async_call_later') as mock_call_later: assert not await ent_platform.async_setup_entry(config_entry) assert len(mock_call_later.mock_calls) == 1 assert len(mock_call_later.return_value.mock_calls) == 0 assert ent_platform._async_cancel_retry_setup is not None await ent_platform.async_reset() assert len(mock_call_later.return_value.mock_calls) == 1 assert ent_platform._async_cancel_retry_setup is None
async def test_entity_source_admin(hass, websocket_client, hass_admin_user): """Check that we fetch sources correctly.""" platform = MockEntityPlatform(hass) await platform.async_add_entities( [MockEntity(name="Entity 1"), MockEntity(name="Entity 2")] ) # Fetch all await websocket_client.send_json({"id": 6, "type": "entity/source"}) msg = await websocket_client.receive_json() assert msg["id"] == 6 assert msg["type"] == const.TYPE_RESULT assert msg["success"] assert msg["result"] == { "test_domain.entity_1": { "source": entity.SOURCE_PLATFORM_CONFIG, "domain": "test_platform", }, "test_domain.entity_2": { "source": entity.SOURCE_PLATFORM_CONFIG, "domain": "test_platform", }, } # Fetch one await websocket_client.send_json( {"id": 7, "type": "entity/source", "entity_id": ["test_domain.entity_2"]} ) msg = await websocket_client.receive_json() assert msg["id"] == 7 assert msg["type"] == const.TYPE_RESULT assert msg["success"] assert msg["result"] == { "test_domain.entity_2": { "source": entity.SOURCE_PLATFORM_CONFIG, "domain": "test_platform", }, } # Fetch two await websocket_client.send_json( { "id": 8, "type": "entity/source", "entity_id": ["test_domain.entity_2", "test_domain.entity_1"], } ) msg = await websocket_client.receive_json() assert msg["id"] == 8 assert msg["type"] == const.TYPE_RESULT assert msg["success"] assert msg["result"] == { "test_domain.entity_1": { "source": entity.SOURCE_PLATFORM_CONFIG, "domain": "test_platform", }, "test_domain.entity_2": { "source": entity.SOURCE_PLATFORM_CONFIG, "domain": "test_platform", }, } # Fetch non existing await websocket_client.send_json( { "id": 9, "type": "entity/source", "entity_id": ["test_domain.entity_2", "test_domain.non_existing"], } ) msg = await websocket_client.receive_json() assert msg["id"] == 9 assert msg["type"] == const.TYPE_RESULT assert not msg["success"] assert msg["error"]["code"] == const.ERR_NOT_FOUND # Mock policy hass_admin_user.groups = [] hass_admin_user.mock_policy( {"entities": {"entity_ids": {"test_domain.entity_2": True}}} ) # Fetch all await websocket_client.send_json({"id": 10, "type": "entity/source"}) msg = await websocket_client.receive_json() assert msg["id"] == 10 assert msg["type"] == const.TYPE_RESULT assert msg["success"] assert msg["result"] == { "test_domain.entity_2": { "source": entity.SOURCE_PLATFORM_CONFIG, "domain": "test_platform", }, } # Fetch unauthorized await websocket_client.send_json( {"id": 11, "type": "entity/source", "entity_id": ["test_domain.entity_1"]} ) msg = await websocket_client.receive_json() assert msg["id"] == 11 assert msg["type"] == const.TYPE_RESULT assert not msg["success"] assert msg["error"]["code"] == const.ERR_UNAUTHORIZED
async def test_device_info_called(hass): """Test device info is forwarded correctly.""" registry = dr.async_get(hass) via = registry.async_get_or_create( config_entry_id="123", connections=set(), identifiers={("hue", "via-id")}, manufacturer="manufacturer", model="via", ) 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", "hw_version": "test-hw", "suggested_area": "Heliport", "entry_type": dr.DeviceEntryType.SERVICE, "via_device": ("hue", "via-id"), }, ), ] ) return True platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry(entry_id="super-mock-id") entity_platform = MockEntityPlatform( hass, platform_name=config_entry.domain, platform=platform ) assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() assert len(hass.states.async_entity_ids()) == 2 device = registry.async_get_device({("hue", "1234")}) assert device is not None assert device.identifiers == {("hue", "1234")} assert device.configuration_url == "http://192.168.0.100/config" assert device.connections == {(dr.CONNECTION_NETWORK_MAC, "abcd")} assert device.entry_type is dr.DeviceEntryType.SERVICE assert device.manufacturer == "test-manuf" assert device.model == "test-model" assert device.name == "test-name" assert device.suggested_area == "Heliport" assert device.sw_version == "test-sw" assert device.hw_version == "test-hw" assert device.via_device_id == via.id
async def test_update_entity(hass, client): """Test updating entity.""" registry = 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="before update", icon="icon:before update", ) }, ) 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 == "before update" assert state.attributes[ATTR_ICON] == "icon:before update" # UPDATE NAME & ICON & AREA await client.send_json( { "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "name": "after update", "icon": "icon:after update", "area_id": "mock-area-id", } ) msg = await client.receive_json() assert msg["result"] == { "entity_entry": { "config_entry_id": None, "device_id": None, "area_id": "mock-area-id", "disabled_by": None, "platform": "test_platform", "entity_id": "test_domain.world", "name": "after update", "icon": "icon:after update", "original_name": None, "original_icon": None, "capabilities": None, "unique_id": "1234", } } state = hass.states.get("test_domain.world") assert state.name == "after update" assert state.attributes[ATTR_ICON] == "icon:after update" # UPDATE DISABLED_BY TO USER await client.send_json( { "id": 7, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "disabled_by": DISABLED_USER, } ) msg = await client.receive_json() assert hass.states.get("test_domain.world") is None assert registry.entities["test_domain.world"].disabled_by == DISABLED_USER # 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": None, "device_id": None, "area_id": "mock-area-id", "disabled_by": None, "platform": "test_platform", "entity_id": "test_domain.world", "name": "after update", "icon": "icon:after update", "original_name": None, "original_icon": None, "capabilities": None, "unique_id": "1234", }, "reload_delay": 30, }
async def test_update_entity(hass, client): """Test updating entity.""" registry = 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="before update", ) }, ) 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 == "before update" # UPDATE NAME await client.send_json( { "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "name": "after update", } ) msg = await client.receive_json() assert msg["result"] == { "config_entry_id": None, "device_id": None, "disabled_by": None, "platform": "test_platform", "entity_id": "test_domain.world", "name": "after update", } state = hass.states.get("test_domain.world") assert state.name == "after update" # UPDATE DISABLED_BY TO USER await client.send_json( { "id": 7, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "disabled_by": "user", } ) msg = await client.receive_json() assert hass.states.get("test_domain.world") is None assert registry.entities["test_domain.world"].disabled_by == "user" # 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"] == { "config_entry_id": None, "device_id": None, "disabled_by": None, "platform": "test_platform", "entity_id": "test_domain.world", "name": "after update", }
async def test_connected_device_registered(hass): """Test dispatch on connected device being registered.""" registry = mock_registry(hass) dispatches = [] @callback def _save_dispatch(msg): dispatches.append(msg) unsub = async_dispatcher_connect(hass, ce.CONNECTED_DEVICE_REGISTERED, _save_dispatch) class MockScannerEntity(ce.ScannerEntity): """Mock a scanner entity.""" @property def ip_address(self) -> str: return "5.4.3.2" @property def unique_id(self) -> str: return self.mac_address class MockDisconnectedScannerEntity(MockScannerEntity): """Mock a disconnected scanner entity.""" @property def mac_address(self) -> str: return "aa:bb:cc:dd:ee:ff" @property def is_connected(self) -> bool: return True @property def hostname(self) -> str: return "connected" class MockConnectedScannerEntity(MockScannerEntity): """Mock a disconnected scanner entity.""" @property def mac_address(self) -> str: return "aa:bb:cc:dd:ee:00" @property def is_connected(self) -> bool: return False @property def hostname(self) -> str: return "disconnected" async def async_setup_entry(hass, config_entry, async_add_entities): """Mock setup entry method.""" async_add_entities( [MockConnectedScannerEntity(), MockDisconnectedScannerEntity()]) return True platform = MockPlatform(async_setup_entry=async_setup_entry) config_entry = MockConfigEntry(entry_id="super-mock-id") entity_platform = MockEntityPlatform(hass, platform_name=config_entry.domain, platform=platform) assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() full_name = f"{entity_platform.domain}.{config_entry.domain}" assert full_name in hass.config.components assert len(hass.states.async_entity_ids()) == 0 # should be disabled assert len(registry.entities) == 2 assert (registry.entities["test_domain.test_aa_bb_cc_dd_ee_ff"]. config_entry_id == "super-mock-id") unsub() assert dispatches == [{ "ip": "5.4.3.2", "mac": "aa:bb:cc:dd:ee:ff", "host_name": "connected" }]
async def test_update_entity(hass, client): """Test updating entity.""" registry = 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="before update", icon="icon:before update", ) }, ) 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 == "before update" assert state.attributes[ATTR_ICON] == "icon:before update" # UPDATE AREA, DEVICE_CLASS, HIDDEN_BY, ICON AND NAME await client.send_json( { "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "area_id": "mock-area-id", "device_class": "custom_device_class", "hidden_by": "user", # We exchange strings over the WS API, not enums "icon": "icon:after update", "name": "after update", } ) msg = await client.receive_json() assert msg["result"] == { "entity_entry": { "area_id": "mock-area-id", "capabilities": None, "config_entry_id": None, "device_class": "custom_device_class", "device_id": None, "disabled_by": None, "entity_category": None, "entity_id": "test_domain.world", "hidden_by": "user", # We exchange strings over the WS API, not enums "icon": "icon:after update", "name": "after update", "options": {}, "original_device_class": None, "original_icon": None, "original_name": None, "platform": "test_platform", "unique_id": "1234", } } state = hass.states.get("test_domain.world") assert state.name == "after update" assert state.attributes[ATTR_ICON] == "icon:after update" # UPDATE HIDDEN_BY TO ILLEGAL VALUE await client.send_json( { "id": 7, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "hidden_by": "ivy", } ) msg = await client.receive_json() assert not msg["success"] assert registry.entities["test_domain.world"].hidden_by is RegistryEntryHider.USER # UPDATE DISABLED_BY TO USER await client.send_json( { "id": 8, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "disabled_by": "user", # We exchange strings over the WS API, not enums } ) msg = await client.receive_json() assert msg["success"] assert hass.states.get("test_domain.world") is None assert ( registry.entities["test_domain.world"].disabled_by is RegistryEntryDisabler.USER ) # UPDATE DISABLED_BY TO NONE await client.send_json( { "id": 9, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "disabled_by": None, } ) msg = await client.receive_json() assert msg["result"] == { "entity_entry": { "area_id": "mock-area-id", "capabilities": None, "config_entry_id": None, "device_class": "custom_device_class", "device_id": None, "disabled_by": None, "entity_category": None, "entity_id": "test_domain.world", "hidden_by": "user", # We exchange strings over the WS API, not enums "icon": "icon:after update", "name": "after update", "options": {}, "original_device_class": None, "original_icon": None, "original_name": None, "platform": "test_platform", "unique_id": "1234", }, "reload_delay": 30, } # UPDATE ENTITY OPTION await client.send_json( { "id": 10, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "options_domain": "sensor", "options": {"unit_of_measurement": "beard_second"}, } ) msg = await client.receive_json() assert msg["result"] == { "entity_entry": { "area_id": "mock-area-id", "capabilities": None, "config_entry_id": None, "device_class": "custom_device_class", "device_id": None, "disabled_by": None, "entity_category": None, "entity_id": "test_domain.world", "hidden_by": "user", # We exchange strings over the WS API, not enums "icon": "icon:after update", "name": "after update", "options": {"sensor": {"unit_of_measurement": "beard_second"}}, "original_device_class": None, "original_icon": None, "original_name": None, "platform": "test_platform", "unique_id": "1234", }, }
async def test_update(hass: HomeAssistant) -> None: """Test getting data from the mocked update entity.""" update = MockUpdateEntity() update.hass = hass update._attr_installed_version = "1.0.0" update._attr_latest_version = "1.0.1" update._attr_release_summary = "Summary" update._attr_release_url = "https://example.com" update._attr_title = "Title" assert update.entity_category is EntityCategory.DIAGNOSTIC assert update.entity_picture is None assert update.installed_version == "1.0.0" assert update.latest_version == "1.0.1" assert update.release_summary == "Summary" assert update.release_url == "https://example.com" assert update.title == "Title" assert update.in_progress is False assert update.state == STATE_ON assert update.state_attributes == { ATTR_AUTO_UPDATE: False, ATTR_INSTALLED_VERSION: "1.0.0", ATTR_IN_PROGRESS: False, ATTR_LATEST_VERSION: "1.0.1", ATTR_RELEASE_SUMMARY: "Summary", ATTR_RELEASE_URL: "https://example.com", ATTR_SKIPPED_VERSION: None, ATTR_TITLE: "Title", } # Test with platform update.platform = MockEntityPlatform(hass) assert ( update.entity_picture == "https://brands.home-assistant.io/_/test_platform/icon.png" ) # Test no update available update._attr_installed_version = "1.0.0" update._attr_latest_version = "1.0.0" assert update.state is STATE_OFF # Test state becomes unknown if installed version is unknown update._attr_installed_version = None update._attr_latest_version = "1.0.0" assert update.state is None # Test state becomes unknown if latest version is unknown update._attr_installed_version = "1.0.0" update._attr_latest_version = None assert update.state is None # Test no update if new version is not an update update._attr_installed_version = "1.0.0" update._attr_latest_version = "0.9.0" assert update.state is STATE_OFF # Test update if new version is not considered a valid version update._attr_installed_version = "1.0.0" update._attr_latest_version = "awesome_update" assert update.state is STATE_ON # Test entity category becomes config when its possible to install update._attr_supported_features = UpdateEntityFeature.INSTALL assert update.entity_category is EntityCategory.CONFIG # UpdateEntityDescription was set update._attr_supported_features = 0 update.entity_description = UpdateEntityDescription(key="F5 - Its very refreshing") assert update.device_class is None assert update.entity_category is EntityCategory.CONFIG update.entity_description = UpdateEntityDescription( key="F5 - Its very refreshing", device_class=UpdateDeviceClass.FIRMWARE, entity_category=None, ) assert update.device_class is UpdateDeviceClass.FIRMWARE assert update.entity_category is None # Device class via attribute (override entity description) update._attr_device_class = None assert update.device_class is None update._attr_device_class = UpdateDeviceClass.FIRMWARE assert update.device_class is UpdateDeviceClass.FIRMWARE # Entity Attribute via attribute (override entity description) update._attr_entity_category = None assert update.entity_category is None update._attr_entity_category = EntityCategory.DIAGNOSTIC assert update.entity_category is EntityCategory.DIAGNOSTIC with pytest.raises(NotImplementedError): await update.async_install(version=None, backup=True) with pytest.raises(NotImplementedError): update.install(version=None, backup=False) update.install = MagicMock() await update.async_install(version="1.0.1", backup=True) assert update.install.called assert update.install.call_args[0][0] == "1.0.1" assert update.install.call_args[0][1] is True
async def test_passive_bluetooth_entity_with_entity_platform( hass, mock_bleak_scanner_start ): """Test with a mock entity platform.""" await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) entity_platform = MockEntityPlatform(hass) @callback def _mock_update_method( service_info: BluetoothServiceInfo, ) -> dict[str, str]: return {"test": "data"} @callback def _async_generate_mock_data( data: dict[str, str], ) -> PassiveBluetoothDataUpdate: """Generate mock data.""" return NO_DEVICES_PASSIVE_BLUETOOTH_DATA_UPDATE coordinator = PassiveBluetoothProcessorCoordinator( hass, _LOGGER, "aa:bb:cc:dd:ee:ff", BluetoothScanningMode.ACTIVE, _mock_update_method, ) assert coordinator.available is False # no data yet saved_callback = None def _async_register_callback(_hass, _callback, _matcher, _mode): nonlocal saved_callback saved_callback = _callback return lambda: None processor = PassiveBluetoothDataProcessor(_async_generate_mock_data) with patch( "homeassistant.components.bluetooth.update_coordinator.async_register_callback", _async_register_callback, ): coordinator.async_register_processor(processor) cancel_coordinator = coordinator.async_start() processor.async_add_entities_listener( PassiveBluetoothProcessorEntity, lambda entities: hass.async_create_task( entity_platform.async_add_entities(entities) ), ) saved_callback(NO_DEVICES_BLUETOOTH_SERVICE_INFO, BluetoothChange.ADVERTISEMENT) await hass.async_block_till_done() saved_callback(NO_DEVICES_BLUETOOTH_SERVICE_INFO, BluetoothChange.ADVERTISEMENT) await hass.async_block_till_done() assert ( hass.states.get("test_domain.test_platform_aa_bb_cc_dd_ee_ff_temperature") is not None ) assert ( hass.states.get("test_domain.test_platform_aa_bb_cc_dd_ee_ff_pressure") is not None ) cancel_coordinator()