Bump brother backend library (#78072)

* Update integration for a new library

* Update tests

* Add unique_id migration

* Update integration and tests for lib 2.0.0

* Improve test coverage

* Improve typing in tests
This commit is contained in:
Maciej Bieniek 2022-09-18 23:28:17 +02:00 committed by GitHub
parent 3c6c673a20
commit 721fddc016
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 182 additions and 62 deletions

View file

@ -5,12 +5,12 @@ from datetime import timedelta
import logging
import async_timeout
from brother import Brother, DictToObj, SnmpError, UnsupportedModel
import pysnmp.hlapi.asyncio as SnmpEngine
from brother import Brother, BrotherSensors, SnmpError, UnsupportedModel
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_TYPE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DATA_CONFIG_ENTRY, DOMAIN, SNMP
@ -26,13 +26,17 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Brother from a config entry."""
host = entry.data[CONF_HOST]
kind = entry.data[CONF_TYPE]
printer_type = entry.data[CONF_TYPE]
snmp_engine = get_snmp_engine(hass)
try:
brother = await Brother.create(
host, printer_type=printer_type, snmp_engine=snmp_engine
)
except (ConnectionError, SnmpError) as error:
raise ConfigEntryNotReady from error
coordinator = BrotherDataUpdateCoordinator(
hass, host=host, kind=kind, snmp_engine=snmp_engine
)
coordinator = BrotherDataUpdateCoordinator(hass, brother)
await coordinator.async_config_entry_first_refresh()
hass.data.setdefault(DOMAIN, {})
@ -61,11 +65,9 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
class BrotherDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching Brother data from the printer."""
def __init__(
self, hass: HomeAssistant, host: str, kind: str, snmp_engine: SnmpEngine
) -> None:
def __init__(self, hass: HomeAssistant, brother: Brother) -> None:
"""Initialize."""
self.brother = Brother(host, kind=kind, snmp_engine=snmp_engine)
self.brother = brother
super().__init__(
hass,
@ -74,7 +76,7 @@ class BrotherDataUpdateCoordinator(DataUpdateCoordinator):
update_interval=SCAN_INTERVAL,
)
async def _async_update_data(self) -> DictToObj:
async def _async_update_data(self) -> BrotherSensors:
"""Update data via library."""
try:
async with async_timeout.timeout(20):

View file

@ -46,7 +46,9 @@ class BrotherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
snmp_engine = get_snmp_engine(self.hass)
brother = Brother(user_input[CONF_HOST], snmp_engine=snmp_engine)
brother = await Brother.create(
user_input[CONF_HOST], snmp_engine=snmp_engine
)
await brother.async_update()
await self.async_set_unique_id(brother.serial.lower())
@ -80,7 +82,9 @@ class BrotherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
model = discovery_info.properties.get("product")
try:
self.brother = Brother(self.host, snmp_engine=snmp_engine, model=model)
self.brother = await Brother.create(
self.host, snmp_engine=snmp_engine, model=model
)
await self.brother.async_update()
except UnsupportedModel:
return self.async_abort(reason="unsupported_model")

View file

@ -1,6 +1,8 @@
"""Diagnostics support for Brother."""
from __future__ import annotations
from dataclasses import asdict
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@ -18,7 +20,7 @@ async def async_get_config_entry_diagnostics(
diagnostics_data = {
"info": dict(config_entry.data),
"data": coordinator.data,
"data": asdict(coordinator.data),
}
return diagnostics_data

View file

@ -3,7 +3,7 @@
"name": "Brother Printer",
"documentation": "https://www.home-assistant.io/integrations/brother",
"codeowners": ["@bieniu"],
"requirements": ["brother==1.2.3"],
"requirements": ["brother==2.0.0"],
"zeroconf": [
{
"type": "_printer._tcp.local.",

View file

@ -3,9 +3,11 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
import logging
from typing import Any, cast
from homeassistant.components.sensor import (
DOMAIN as PLATFORM,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
@ -14,6 +16,7 @@ from homeassistant.components.sensor import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
@ -28,7 +31,7 @@ ATTR_BLACK_DRUM_REMAINING_LIFE = "black_drum_remaining_life"
ATTR_BLACK_DRUM_REMAINING_PAGES = "black_drum_remaining_pages"
ATTR_BLACK_INK_REMAINING = "black_ink_remaining"
ATTR_BLACK_TONER_REMAINING = "black_toner_remaining"
ATTR_BW_COUNTER = "b/w_counter"
ATTR_BW_COUNTER = "bw_counter"
ATTR_COLOR_COUNTER = "color_counter"
ATTR_COUNTER = "counter"
ATTR_CYAN_DRUM_COUNTER = "cyan_drum_counter"
@ -82,6 +85,8 @@ ATTRS_MAP: dict[str, tuple[str, str]] = {
),
}
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
@ -89,6 +94,22 @@ async def async_setup_entry(
"""Add Brother entities from a config_entry."""
coordinator = hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id]
# Due to the change of the attribute name of one sensor, it is necessary to migrate
# the unique_id to the new one.
entity_registry = er.async_get(hass)
old_unique_id = f"{coordinator.data.serial.lower()}_b/w_counter"
if entity_id := entity_registry.async_get_entity_id(
PLATFORM, DOMAIN, old_unique_id
):
new_unique_id = f"{coordinator.data.serial.lower()}_bw_counter"
_LOGGER.debug(
"Migrating entity %s from old unique ID '%s' to new unique ID '%s'",
entity_id,
old_unique_id,
new_unique_id,
)
entity_registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
sensors = []
device_info = DeviceInfo(
@ -97,11 +118,11 @@ async def async_setup_entry(
manufacturer=ATTR_MANUFACTURER,
model=coordinator.data.model,
name=coordinator.data.model,
sw_version=getattr(coordinator.data, "firmware", None),
sw_version=coordinator.data.firmware,
)
for description in SENSOR_TYPES:
if description.key in coordinator.data:
if getattr(coordinator.data, description.key) is not None:
sensors.append(
description.entity_class(coordinator, description, device_info)
)

View file

@ -449,7 +449,7 @@ boto3==1.20.24
broadlink==0.18.2
# homeassistant.components.brother
brother==1.2.3
brother==2.0.0
# homeassistant.components.brottsplatskartan
brottsplatskartan==0.0.1

View file

@ -356,7 +356,7 @@ boschshcpy==0.2.30
broadlink==0.18.2
# homeassistant.components.brother
brother==1.2.3
brother==2.0.0
# homeassistant.components.brunt
brunt==1.2.0

View file

@ -4,11 +4,14 @@ from unittest.mock import patch
from homeassistant.components.brother.const import DOMAIN
from homeassistant.const import CONF_HOST, CONF_TYPE
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, load_fixture
async def init_integration(hass, skip_setup=False) -> MockConfigEntry:
async def init_integration(
hass: HomeAssistant, skip_setup: bool = False
) -> MockConfigEntry:
"""Set up the Brother integration in Home Assistant."""
entry = MockConfigEntry(
domain=DOMAIN,
@ -20,7 +23,7 @@ async def init_integration(hass, skip_setup=False) -> MockConfigEntry:
entry.add_to_hass(hass)
if not skip_setup:
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):

View file

@ -1,5 +1,10 @@
{
"b/w_counter": 709,
"black_counter": null,
"black_ink": null,
"black_ink_remaining": null,
"black_ink_status": null,
"cyan_counter": null,
"bw_counter": 709,
"belt_unit_remaining_life": 97,
"belt_unit_remaining_pages": 48436,
"black_drum_counter": 1611,
@ -12,6 +17,9 @@
"cyan_drum_counter": 1611,
"cyan_drum_remaining_life": 92,
"cyan_drum_remaining_pages": 16389,
"cyan_ink": null,
"cyan_ink_remaining": null,
"cyan_ink_status": null,
"cyan_toner": 10,
"cyan_toner_remaining": 10,
"cyan_toner_status": 1,
@ -22,10 +30,17 @@
"duplex_unit_pages_counter": 538,
"firmware": "1.17",
"fuser_remaining_life": 97,
"fuser_unit_remaining_pages": null,
"image_counter": null,
"laser_remaining_life": null,
"laser_unit_remaining_pages": 48389,
"magenta_counter": null,
"magenta_drum_counter": 1611,
"magenta_drum_remaining_life": 92,
"magenta_drum_remaining_pages": 16389,
"magenta_ink": null,
"magenta_ink_remaining": null,
"magenta_ink_status": null,
"magenta_toner": 10,
"magenta_toner_remaining": 8,
"magenta_toner_status": 2,
@ -33,12 +48,18 @@
"page_counter": 986,
"pf_kit_1_remaining_life": 98,
"pf_kit_1_remaining_pages": 48741,
"pf_kit_mp_remaining_life": null,
"pf_kit_mp_remaining_pages": null,
"serial": "0123456789",
"status": "waiting",
"uptime": "2019-09-24T12:14:56+00:00",
"yellow_counter": null,
"yellow_drum_counter": 1611,
"yellow_drum_remaining_life": 92,
"yellow_drum_remaining_pages": 16389,
"yellow_ink": null,
"yellow_ink_remaining": null,
"yellow_ink_status": null,
"yellow_toner": 10,
"yellow_toner_remaining": 2,
"yellow_toner_status": 2

View file

@ -9,13 +9,14 @@ from homeassistant.components import zeroconf
from homeassistant.components.brother.const import DOMAIN
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
from homeassistant.const import CONF_HOST, CONF_TYPE
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, load_fixture
CONFIG = {CONF_HOST: "127.0.0.1", CONF_TYPE: "laser"}
async def test_show_form(hass):
async def test_show_form(hass: HomeAssistant) -> None:
"""Test that the form is served with no input."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
@ -25,9 +26,9 @@ async def test_show_form(hass):
assert result["step_id"] == SOURCE_USER
async def test_create_entry_with_hostname(hass):
async def test_create_entry_with_hostname(hass: HomeAssistant) -> None:
"""Test that the user step works with printer hostname."""
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -43,9 +44,9 @@ async def test_create_entry_with_hostname(hass):
assert result["data"][CONF_TYPE] == "laser"
async def test_create_entry_with_ipv4_address(hass):
async def test_create_entry_with_ipv4_address(hass: HomeAssistant) -> None:
"""Test that the user step works with printer IPv4 address."""
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -59,9 +60,9 @@ async def test_create_entry_with_ipv4_address(hass):
assert result["data"][CONF_TYPE] == "laser"
async def test_create_entry_with_ipv6_address(hass):
async def test_create_entry_with_ipv6_address(hass: HomeAssistant) -> None:
"""Test that the user step works with printer IPv6 address."""
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -77,7 +78,7 @@ async def test_create_entry_with_ipv6_address(hass):
assert result["data"][CONF_TYPE] == "laser"
async def test_invalid_hostname(hass):
async def test_invalid_hostname(hass: HomeAssistant) -> None:
"""Test invalid hostname in user_input."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -88,9 +89,11 @@ async def test_invalid_hostname(hass):
assert result["errors"] == {CONF_HOST: "wrong_host"}
async def test_connection_error(hass):
async def test_connection_error(hass: HomeAssistant) -> None:
"""Test connection to host error."""
with patch("brother.Brother._get_data", side_effect=ConnectionError()):
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data", side_effect=ConnectionError()
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)
@ -98,9 +101,11 @@ async def test_connection_error(hass):
assert result["errors"] == {"base": "cannot_connect"}
async def test_snmp_error(hass):
async def test_snmp_error(hass: HomeAssistant) -> None:
"""Test SNMP error."""
with patch("brother.Brother._get_data", side_effect=SnmpError("error")):
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data", side_effect=SnmpError("error")
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)
@ -108,9 +113,11 @@ async def test_snmp_error(hass):
assert result["errors"] == {"base": "snmp_error"}
async def test_unsupported_model_error(hass):
async def test_unsupported_model_error(hass: HomeAssistant) -> None:
"""Test unsupported printer model error."""
with patch("brother.Brother._get_data", side_effect=UnsupportedModel("error")):
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data", side_effect=UnsupportedModel("error")
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
@ -120,9 +127,9 @@ async def test_unsupported_model_error(hass):
assert result["reason"] == "unsupported_model"
async def test_device_exists_abort(hass):
async def test_device_exists_abort(hass: HomeAssistant) -> None:
"""Test we abort config flow if Brother printer already configured."""
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -137,9 +144,11 @@ async def test_device_exists_abort(hass):
assert result["reason"] == "already_configured"
async def test_zeroconf_snmp_error(hass):
async def test_zeroconf_snmp_error(hass: HomeAssistant) -> None:
"""Test we abort zeroconf flow on SNMP error."""
with patch("brother.Brother._get_data", side_effect=SnmpError("error")):
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data", side_effect=SnmpError("error")
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -159,9 +168,11 @@ async def test_zeroconf_snmp_error(hass):
assert result["reason"] == "cannot_connect"
async def test_zeroconf_unsupported_model(hass):
async def test_zeroconf_unsupported_model(hass: HomeAssistant) -> None:
"""Test unsupported printer model error."""
with patch("brother.Brother._get_data") as mock_get_data:
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data"
) as mock_get_data:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
@ -181,9 +192,9 @@ async def test_zeroconf_unsupported_model(hass):
assert len(mock_get_data.mock_calls) == 0
async def test_zeroconf_device_exists_abort(hass):
async def test_zeroconf_device_exists_abort(hass: HomeAssistant) -> None:
"""Test we abort zeroconf flow if Brother printer already configured."""
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -215,11 +226,13 @@ async def test_zeroconf_device_exists_abort(hass):
assert entry.data["host"] == "127.0.0.1"
async def test_zeroconf_no_probe_existing_device(hass):
async def test_zeroconf_no_probe_existing_device(hass: HomeAssistant) -> None:
"""Test we do not probe the device is the host is already configured."""
entry = MockConfigEntry(domain=DOMAIN, unique_id="0123456789", data=CONFIG)
entry.add_to_hass(hass)
with patch("brother.Brother._get_data") as mock_get_data:
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data"
) as mock_get_data:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
@ -240,9 +253,9 @@ async def test_zeroconf_no_probe_existing_device(hass):
assert len(mock_get_data.mock_calls) == 0
async def test_zeroconf_confirm_create_entry(hass):
async def test_zeroconf_confirm_create_entry(hass: HomeAssistant) -> None:
"""Test zeroconf confirmation and create config entry."""
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):

View file

@ -1,8 +1,12 @@
"""Test Brother diagnostics."""
from collections.abc import Awaitable, Callable
from datetime import datetime
import json
from unittest.mock import Mock, patch
from aiohttp import ClientSession
from homeassistant.core import HomeAssistant
from homeassistant.util.dt import UTC
from tests.common import load_fixture
@ -10,13 +14,17 @@ from tests.components.brother import init_integration
from tests.components.diagnostics import get_diagnostics_for_config_entry
async def test_entry_diagnostics(hass, hass_client):
async def test_entry_diagnostics(
hass: HomeAssistant, hass_client: Callable[..., Awaitable[ClientSession]]
) -> None:
"""Test config entry diagnostics."""
entry = await init_integration(hass, skip_setup=True)
diagnostics_data = json.loads(load_fixture("diagnostics_data.json", "brother"))
test_time = datetime(2019, 11, 11, 9, 10, 32, tzinfo=UTC)
with patch("brother.datetime", utcnow=Mock(return_value=test_time)), patch(
with patch("brother.Brother.initialize"), patch(
"brother.datetime", utcnow=Mock(return_value=test_time)
), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):

View file

@ -1,15 +1,19 @@
"""Test init of Brother integration."""
from unittest.mock import patch
from brother import SnmpError
import pytest
from homeassistant.components.brother.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_HOST, CONF_TYPE, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
from tests.components.brother import init_integration
async def test_async_setup_entry(hass):
async def test_async_setup_entry(hass: HomeAssistant) -> None:
"""Test a successful setup entry."""
await init_integration(hass)
@ -19,7 +23,7 @@ async def test_async_setup_entry(hass):
assert state.state == "waiting"
async def test_config_not_ready(hass):
async def test_config_not_ready(hass: HomeAssistant) -> None:
"""Test for setup failure if connection to broker is missing."""
entry = MockConfigEntry(
domain=DOMAIN,
@ -28,13 +32,31 @@ async def test_config_not_ready(hass):
data={CONF_HOST: "localhost", CONF_TYPE: "laser"},
)
with patch("brother.Brother._get_data", side_effect=ConnectionError()):
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data", side_effect=ConnectionError()
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
assert entry.state is ConfigEntryState.SETUP_RETRY
async def test_unload_entry(hass):
@pytest.mark.parametrize("exc", [(SnmpError("SNMP Error")), (ConnectionError)])
async def test_error_on_init(hass: HomeAssistant, exc: Exception) -> None:
"""Test for error on init."""
entry = MockConfigEntry(
domain=DOMAIN,
title="HL-L2340DW 0123456789",
unique_id="0123456789",
data={CONF_HOST: "localhost", CONF_TYPE: "laser"},
)
with patch("brother.Brother.initialize", side_effect=exc):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
assert entry.state is ConfigEntryState.SETUP_RETRY
async def test_unload_entry(hass: HomeAssistant) -> None:
"""Test successful unload of entry."""
entry = await init_integration(hass)

View file

@ -19,6 +19,7 @@ from homeassistant.const import (
PERCENTAGE,
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import UTC, utcnow
@ -30,7 +31,7 @@ ATTR_REMAINING_PAGES = "remaining_pages"
ATTR_COUNTER = "counter"
async def test_sensors(hass):
async def test_sensors(hass: HomeAssistant) -> None:
"""Test states of the sensors."""
entry = await init_integration(hass, skip_setup=True)
@ -45,7 +46,9 @@ async def test_sensors(hass):
disabled_by=None,
)
test_time = datetime(2019, 11, 11, 9, 10, 32, tzinfo=UTC)
with patch("brother.datetime", utcnow=Mock(return_value=test_time)), patch(
with patch("brother.Brother.initialize"), patch(
"brother.datetime", utcnow=Mock(return_value=test_time)
), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -235,7 +238,7 @@ async def test_sensors(hass):
entry = registry.async_get("sensor.hl_l2340dw_b_w_counter")
assert entry
assert entry.unique_id == "0123456789_b/w_counter"
assert entry.unique_id == "0123456789_bw_counter"
state = hass.states.get("sensor.hl_l2340dw_color_counter")
assert state
@ -276,7 +279,7 @@ async def test_disabled_by_default_sensors(hass):
assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION
async def test_availability(hass):
async def test_availability(hass: HomeAssistant) -> None:
"""Ensure that we mark the entities unavailable correctly when device is offline."""
await init_integration(hass)
@ -286,7 +289,9 @@ async def test_availability(hass):
assert state.state == "waiting"
future = utcnow() + timedelta(minutes=5)
with patch("brother.Brother._get_data", side_effect=ConnectionError()):
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data", side_effect=ConnectionError()
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@ -295,7 +300,7 @@ async def test_availability(hass):
assert state.state == STATE_UNAVAILABLE
future = utcnow() + timedelta(minutes=10)
with patch(
with patch("brother.Brother.initialize"), patch(
"brother.Brother._get_data",
return_value=json.loads(load_fixture("printer_data.json", "brother")),
):
@ -308,7 +313,7 @@ async def test_availability(hass):
assert state.state == "waiting"
async def test_manual_update_entity(hass):
async def test_manual_update_entity(hass: HomeAssistant) -> None:
"""Test manual update entity via service homeassistant/update_entity."""
await init_integration(hass)
@ -326,3 +331,22 @@ async def test_manual_update_entity(hass):
)
assert len(mock_update.mock_calls) == 1
async def test_unique_id_migration(hass: HomeAssistant) -> None:
"""Test states of the unique_id migration."""
registry = er.async_get(hass)
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"0123456789_b/w_counter",
suggested_object_id="hl_l2340dw_b_w_counter",
disabled_by=None,
)
await init_integration(hass)
entry = registry.async_get("sensor.hl_l2340dw_b_w_counter")
assert entry
assert entry.unique_id == "0123456789_bw_counter"