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:
parent
3c6c673a20
commit
721fddc016
13 changed files with 182 additions and 62 deletions
|
@ -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):
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")),
|
||||
):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")),
|
||||
):
|
||||
|
|
|
@ -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")),
|
||||
):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue