From 3461f3a1ed28014dc8d4fe8e3500507733ff38d6 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Fri, 20 Mar 2020 10:21:43 +0100 Subject: [PATCH] Tests improvements to the Brother integration (#32982) * Add tests for states of the sensors * Revert async_update method * Tests improvement * Fix icon name * Tests improvement * Simplify tests * Test improvement * Patch the library instead of the coordinator * Suggested change * Remove return_value --- homeassistant/components/brother/const.py | 2 +- homeassistant/components/brother/sensor.py | 4 + tests/components/brother/__init__.py | 29 ++- tests/components/brother/test_init.py | 110 ++------- tests/components/brother/test_sensor.py | 266 +++++++++++++++++++++ tests/fixtures/brother_printer_data.json | 58 ++++- 6 files changed, 375 insertions(+), 94 deletions(-) create mode 100644 tests/components/brother/test_sensor.py diff --git a/homeassistant/components/brother/const.py b/homeassistant/components/brother/const.py index 94d88162d76..d5bceaa2653 100644 --- a/homeassistant/components/brother/const.py +++ b/homeassistant/components/brother/const.py @@ -48,7 +48,7 @@ PRINTER_TYPES = ["laser", "ink"] SENSOR_TYPES = { ATTR_STATUS: { - ATTR_ICON: "icon:mdi:printer", + ATTR_ICON: "mdi:printer", ATTR_LABEL: ATTR_STATUS.title(), ATTR_UNIT: None, }, diff --git a/homeassistant/components/brother/sensor.py b/homeassistant/components/brother/sensor.py index aa108bf0ac7..b8142ac0c34 100644 --- a/homeassistant/components/brother/sensor.py +++ b/homeassistant/components/brother/sensor.py @@ -147,3 +147,7 @@ class BrotherPrinterSensor(Entity): async def async_will_remove_from_hass(self): """Disconnect from update signal.""" self.coordinator.async_remove_listener(self.async_write_ha_state) + + async def async_update(self): + """Update Brother entity.""" + await self.coordinator.async_request_refresh() diff --git a/tests/components/brother/__init__.py b/tests/components/brother/__init__.py index 91a7b7e92d4..d6c1fedd31d 100644 --- a/tests/components/brother/__init__.py +++ b/tests/components/brother/__init__.py @@ -1 +1,28 @@ -"""Tests for Brother Printer.""" +"""Tests for Brother Printer integration.""" +import json + +from asynctest import patch + +from homeassistant.components.brother.const import DOMAIN +from homeassistant.const import CONF_HOST, CONF_TYPE + +from tests.common import MockConfigEntry, load_fixture + + +async def init_integration(hass) -> MockConfigEntry: + """Set up the Brother integration in Home Assistant.""" + entry = MockConfigEntry( + domain=DOMAIN, + title="HL-L2340DW 0123456789", + unique_id="0123456789", + data={CONF_HOST: "localhost", CONF_TYPE: "laser"}, + ) + with patch( + "brother.Brother._get_data", + return_value=json.loads(load_fixture("brother_printer_data.json")), + ): + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + return entry diff --git a/tests/components/brother/test_init.py b/tests/components/brother/test_init.py index ea9a255f75d..13378e9dbb9 100644 --- a/tests/components/brother/test_init.py +++ b/tests/components/brother/test_init.py @@ -1,38 +1,26 @@ """Test init of Brother integration.""" -from datetime import timedelta -import json - from asynctest import patch -import pytest -import homeassistant.components.brother as brother from homeassistant.components.brother.const import DOMAIN +from homeassistant.config_entries import ( + ENTRY_STATE_LOADED, + ENTRY_STATE_NOT_LOADED, + ENTRY_STATE_SETUP_RETRY, +) from homeassistant.const import CONF_HOST, CONF_TYPE, STATE_UNAVAILABLE -from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.util.dt import utcnow -from tests.common import MockConfigEntry, async_fire_time_changed, load_fixture +from tests.common import MockConfigEntry +from tests.components.brother import init_integration async def test_async_setup_entry(hass): """Test a successful setup entry.""" - entry = MockConfigEntry( - domain=DOMAIN, - title="HL-L2340DW 0123456789", - data={CONF_HOST: "localhost", CONF_TYPE: "laser"}, - ) - with patch( - "brother.Brother._get_data", - return_value=json.loads(load_fixture("brother_printer_data.json")), - ): - entry.add_to_hass(hass) - assert await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() + await init_integration(hass) - state = hass.states.get("sensor.hl_l2340dw_status") - assert state is not None - assert state.state != STATE_UNAVAILABLE - assert state.state == "waiting" + state = hass.states.get("sensor.hl_l2340dw_status") + assert state is not None + assert state.state != STATE_UNAVAILABLE + assert state.state == "waiting" async def test_config_not_ready(hass): @@ -40,73 +28,25 @@ async def test_config_not_ready(hass): entry = MockConfigEntry( domain=DOMAIN, title="HL-L2340DW 0123456789", + unique_id="0123456789", data={CONF_HOST: "localhost", CONF_TYPE: "laser"}, ) - with patch( - "brother.Brother._get_data", side_effect=ConnectionError() - ), pytest.raises(ConfigEntryNotReady): - await brother.async_setup_entry(hass, entry) + + with 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 == ENTRY_STATE_SETUP_RETRY async def test_unload_entry(hass): """Test successful unload of entry.""" - entry = MockConfigEntry( - domain=DOMAIN, - title="HL-L2340DW 0123456789", - data={CONF_HOST: "localhost", CONF_TYPE: "laser"}, - ) - with patch( - "brother.Brother._get_data", - return_value=json.loads(load_fixture("brother_printer_data.json")), - ): - entry.add_to_hass(hass) - assert await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() + entry = await init_integration(hass) - assert hass.data[DOMAIN][entry.entry_id] + assert len(hass.config_entries.async_entries(DOMAIN)) == 1 + assert entry.state == ENTRY_STATE_LOADED - assert await hass.config_entries.async_unload(entry.entry_id) - assert not hass.data[DOMAIN] + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() - -async def test_availability(hass): - """Ensure that we mark the entities unavailable correctly when device is offline.""" - entry = MockConfigEntry( - domain=DOMAIN, - title="HL-L2340DW 0123456789", - data={CONF_HOST: "localhost", CONF_TYPE: "laser"}, - ) - with patch( - "brother.Brother._get_data", - return_value=json.loads(load_fixture("brother_printer_data.json")), - ): - entry.add_to_hass(hass) - assert await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - state = hass.states.get("sensor.hl_l2340dw_status") - assert state is not None - assert state.state != STATE_UNAVAILABLE - assert state.state == "waiting" - - future = utcnow() + timedelta(minutes=5) - with patch("brother.Brother._get_data", side_effect=ConnectionError()): - async_fire_time_changed(hass, future) - await hass.async_block_till_done() - - state = hass.states.get("sensor.hl_l2340dw_status") - assert state is not None - assert state.state == STATE_UNAVAILABLE - - future = utcnow() + timedelta(minutes=10) - with patch( - "brother.Brother._get_data", - return_value=json.loads(load_fixture("brother_printer_data.json")), - ): - async_fire_time_changed(hass, future) - await hass.async_block_till_done() - - state = hass.states.get("sensor.hl_l2340dw_status") - assert state is not None - assert state.state != STATE_UNAVAILABLE - assert state.state == "waiting" + assert entry.state == ENTRY_STATE_NOT_LOADED + assert not hass.data.get(DOMAIN) diff --git a/tests/components/brother/test_sensor.py b/tests/components/brother/test_sensor.py new file mode 100644 index 00000000000..e88c22f3f40 --- /dev/null +++ b/tests/components/brother/test_sensor.py @@ -0,0 +1,266 @@ +"""Test sensor of Brother integration.""" +from datetime import timedelta +import json + +from asynctest import patch + +from homeassistant.components.brother.const import UNIT_PAGES +from homeassistant.const import ( + ATTR_ENTITY_ID, + ATTR_ICON, + ATTR_UNIT_OF_MEASUREMENT, + STATE_UNAVAILABLE, + TIME_DAYS, + UNIT_PERCENTAGE, +) +from homeassistant.setup import async_setup_component +from homeassistant.util.dt import utcnow + +from tests.common import async_fire_time_changed, load_fixture +from tests.components.brother import init_integration + +ATTR_REMAINING_PAGES = "remaining_pages" +ATTR_COUNTER = "counter" + + +async def test_sensors(hass): + """Test states of the sensors.""" + await init_integration(hass) + registry = await hass.helpers.entity_registry.async_get_registry() + + state = hass.states.get("sensor.hl_l2340dw_status") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:printer" + assert state.state == "waiting" + + entry = registry.async_get("sensor.hl_l2340dw_status") + assert entry + assert entry.unique_id == "0123456789_status" + + state = hass.states.get("sensor.hl_l2340dw_black_toner_remaining") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "75" + + entry = registry.async_get("sensor.hl_l2340dw_black_toner_remaining") + assert entry + assert entry.unique_id == "0123456789_black_toner_remaining" + + state = hass.states.get("sensor.hl_l2340dw_cyan_toner_remaining") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "10" + + entry = registry.async_get("sensor.hl_l2340dw_cyan_toner_remaining") + assert entry + assert entry.unique_id == "0123456789_cyan_toner_remaining" + + state = hass.states.get("sensor.hl_l2340dw_magenta_toner_remaining") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "8" + + entry = registry.async_get("sensor.hl_l2340dw_magenta_toner_remaining") + assert entry + assert entry.unique_id == "0123456789_magenta_toner_remaining" + + state = hass.states.get("sensor.hl_l2340dw_yellow_toner_remaining") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "2" + + entry = registry.async_get("sensor.hl_l2340dw_yellow_toner_remaining") + assert entry + assert entry.unique_id == "0123456789_yellow_toner_remaining" + + state = hass.states.get("sensor.hl_l2340dw_drum_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:chart-donut" + assert state.attributes.get(ATTR_REMAINING_PAGES) == 11014 + assert state.attributes.get(ATTR_COUNTER) == 986 + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "92" + + entry = registry.async_get("sensor.hl_l2340dw_drum_remaining_life") + assert entry + assert entry.unique_id == "0123456789_drum_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_black_drum_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:chart-donut" + assert state.attributes.get(ATTR_REMAINING_PAGES) == 16389 + assert state.attributes.get(ATTR_COUNTER) == 1611 + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "92" + + entry = registry.async_get("sensor.hl_l2340dw_black_drum_remaining_life") + assert entry + assert entry.unique_id == "0123456789_black_drum_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_cyan_drum_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:chart-donut" + assert state.attributes.get(ATTR_REMAINING_PAGES) == 16389 + assert state.attributes.get(ATTR_COUNTER) == 1611 + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "92" + + entry = registry.async_get("sensor.hl_l2340dw_cyan_drum_remaining_life") + assert entry + assert entry.unique_id == "0123456789_cyan_drum_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_magenta_drum_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:chart-donut" + assert state.attributes.get(ATTR_REMAINING_PAGES) == 16389 + assert state.attributes.get(ATTR_COUNTER) == 1611 + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "92" + + entry = registry.async_get("sensor.hl_l2340dw_magenta_drum_remaining_life") + assert entry + assert entry.unique_id == "0123456789_magenta_drum_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_yellow_drum_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:chart-donut" + assert state.attributes.get(ATTR_REMAINING_PAGES) == 16389 + assert state.attributes.get(ATTR_COUNTER) == 1611 + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "92" + + entry = registry.async_get("sensor.hl_l2340dw_yellow_drum_remaining_life") + assert entry + assert entry.unique_id == "0123456789_yellow_drum_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_fuser_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:water-outline" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "97" + + entry = registry.async_get("sensor.hl_l2340dw_fuser_remaining_life") + assert entry + assert entry.unique_id == "0123456789_fuser_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_belt_unit_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:current-ac" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "97" + + entry = registry.async_get("sensor.hl_l2340dw_belt_unit_remaining_life") + assert entry + assert entry.unique_id == "0123456789_belt_unit_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_pf_kit_1_remaining_life") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE + assert state.state == "98" + + entry = registry.async_get("sensor.hl_l2340dw_pf_kit_1_remaining_life") + assert entry + assert entry.unique_id == "0123456789_pf_kit_1_remaining_life" + + state = hass.states.get("sensor.hl_l2340dw_page_counter") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES + assert state.state == "986" + + entry = registry.async_get("sensor.hl_l2340dw_page_counter") + assert entry + assert entry.unique_id == "0123456789_page_counter" + + state = hass.states.get("sensor.hl_l2340dw_duplex_unit_pages_counter") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES + assert state.state == "538" + + entry = registry.async_get("sensor.hl_l2340dw_duplex_unit_pages_counter") + assert entry + assert entry.unique_id == "0123456789_duplex_unit_pages_counter" + + state = hass.states.get("sensor.hl_l2340dw_b_w_counter") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES + assert state.state == "709" + + entry = registry.async_get("sensor.hl_l2340dw_b_w_counter") + assert entry + assert entry.unique_id == "0123456789_b/w_counter" + + state = hass.states.get("sensor.hl_l2340dw_color_counter") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES + assert state.state == "902" + + entry = registry.async_get("sensor.hl_l2340dw_color_counter") + assert entry + assert entry.unique_id == "0123456789_color_counter" + + state = hass.states.get("sensor.hl_l2340dw_uptime") + assert state + assert state.attributes.get(ATTR_ICON) == "mdi:timer" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TIME_DAYS + assert state.state == "48" + + entry = registry.async_get("sensor.hl_l2340dw_uptime") + assert entry + assert entry.unique_id == "0123456789_uptime" + + +async def test_availability(hass): + """Ensure that we mark the entities unavailable correctly when device is offline.""" + await init_integration(hass) + + state = hass.states.get("sensor.hl_l2340dw_status") + assert state + assert state.state != STATE_UNAVAILABLE + assert state.state == "waiting" + + future = utcnow() + timedelta(minutes=5) + with patch("brother.Brother._get_data", side_effect=ConnectionError()): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get("sensor.hl_l2340dw_status") + assert state + assert state.state == STATE_UNAVAILABLE + + future = utcnow() + timedelta(minutes=10) + with patch( + "brother.Brother._get_data", + return_value=json.loads(load_fixture("brother_printer_data.json")), + ): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get("sensor.hl_l2340dw_status") + assert state + assert state.state != STATE_UNAVAILABLE + assert state.state == "waiting" + + +async def test_manual_update_entity(hass): + """Test manual update entity via service homeasasistant/update_entity.""" + await init_integration(hass) + + await async_setup_component(hass, "homeassistant", {}) + with patch("homeassistant.components.brother.Brother.async_update") as mock_update: + await hass.services.async_call( + "homeassistant", + "update_entity", + {ATTR_ENTITY_ID: ["sensor.hl_l2340dw_status"]}, + blocking=True, + ) + + assert len(mock_update.mock_calls) == 1 diff --git a/tests/fixtures/brother_printer_data.json b/tests/fixtures/brother_printer_data.json index 70e7add3c10..f4c36d988b1 100644 --- a/tests/fixtures/brother_printer_data.json +++ b/tests/fixtures/brother_printer_data.json @@ -1,31 +1,75 @@ { - "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.10.0": ["000104000003da"], + "1.3.6.1.2.1.1.3.0": "413613515", + "1.3.6.1.2.1.43.10.2.1.4.1.1": "986", + "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.10.0": [ + "000104000003da", + "010104000002c5", + "02010400000386", + "0601040000021a", + "0701040000012d", + "080104000000ed" + ], "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.17.0": "1.17", "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8.0": [ - "63010400000001", "110104000003da", - "410104000023f0", "31010400000001", + "32010400000001", + "33010400000002", + "34010400000002", + "35010400000001", + "410104000023f0", + "54010400000001", + "55010400000001", + "63010400000001", + "68010400000001", + "690104000025e4", + "6a0104000025e4", + "6d010400002648", "6f010400001d4c", - "81010400000050", - "8601040000000a", - "7e01040000064b", + "700104000003e8", + "71010400000320", + "720104000000c8", "7301040000064b", "7401040000064b", "7501040000064b", + "76010400000001", + "77010400000001", + "78010400000001", "790104000023f0", "7a0104000023f0", "7b0104000023f0", - "800104000023f0" + "7e01040000064b", + "800104000023f0", + "81010400000050", + "8201040000000a", + "8301040000000a", + "8401040000000a", + "8601040000000a" ], "1.3.6.1.4.1.2435.2.3.9.1.1.7.0": "MFG:Brother;CMD:PJL,HBP,URF;MDL:HL-L2340DW series;CLS:PRINTER;CID:Brother Laser Type1;URF:W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ4,RS300-600,V1.3,DM1;", "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.11.0": [ + "7301040000bd05", + "7701040000be65", "82010400002b06", + "8801040000bd34", "a4010400004005", "a5010400004005", "a6010400004005", "a7010400004005" ], + "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.21.0": [ + "00002302000025", + "00020016010200", + "00210200022202", + "020000a1040000" + ], + "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.20.0": [ + "00a40100a50100", + "0100a301008801", + "01017301007701", + "870100a10100a2", + "a60100a70100a0" + ], "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.1.0": "0123456789", "1.3.6.1.4.1.2435.2.3.9.4.2.1.5.4.5.2.0": "WAITING " } \ No newline at end of file