Refactor IPP tests (#94097)

refactor ipp tests
This commit is contained in:
Chris Talkington 2023-07-09 17:37:32 -05:00 committed by GitHub
parent ac594e6bce
commit 7390e3a997
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 290 additions and 242 deletions

View file

@ -1,20 +1,8 @@
"""Tests for the IPP integration."""
import aiohttp
from pyipp import IPPConnectionUpgradeRequired, IPPError
from homeassistant.components import zeroconf
from homeassistant.components.ipp.const import CONF_BASE_PATH, DOMAIN
from homeassistant.const import (
CONF_HOST,
CONF_PORT,
CONF_SSL,
CONF_UUID,
CONF_VERIFY_SSL,
)
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, get_fixture_path
from tests.test_util.aiohttp import AiohttpClientMocker
from homeassistant.components.ipp.const import CONF_BASE_PATH
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SSL, CONF_VERIFY_SSL
ATTR_HOSTNAME = "hostname"
ATTR_PROPERTIES = "properties"
@ -59,99 +47,3 @@ MOCK_ZEROCONF_IPPS_SERVICE_INFO = zeroconf.ZeroconfServiceInfo(
port=ZEROCONF_PORT,
properties={"rp": ZEROCONF_RP},
)
def load_fixture_binary(filename):
"""Load a binary fixture."""
return get_fixture_path(filename, "ipp").read_bytes()
def mock_connection(
aioclient_mock: AiohttpClientMocker,
host: str = HOST,
port: int = PORT,
ssl: bool = False,
base_path: str = BASE_PATH,
conn_error: bool = False,
conn_upgrade_error: bool = False,
ipp_error: bool = False,
no_unique_id: bool = False,
parse_error: bool = False,
version_not_supported: bool = False,
):
"""Mock the IPP connection."""
scheme = "https" if ssl else "http"
ipp_url = f"{scheme}://{host}:{port}"
if ipp_error:
aioclient_mock.post(f"{ipp_url}{base_path}", exc=IPPError)
return
if conn_error:
aioclient_mock.post(f"{ipp_url}{base_path}", exc=aiohttp.ClientError)
return
if conn_upgrade_error:
aioclient_mock.post(f"{ipp_url}{base_path}", exc=IPPConnectionUpgradeRequired)
return
fixture = "get-printer-attributes.bin"
if no_unique_id:
fixture = "get-printer-attributes-success-nodata.bin"
elif version_not_supported:
fixture = "get-printer-attributes-error-0x0503.bin"
if parse_error:
content = "BAD"
else:
content = load_fixture_binary(fixture)
aioclient_mock.post(
f"{ipp_url}{base_path}",
content=content,
headers={"Content-Type": "application/ipp"},
)
async def init_integration(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
skip_setup: bool = False,
host: str = HOST,
port: int = PORT,
ssl: bool = False,
base_path: str = BASE_PATH,
uuid: str = "cfe92100-67c4-11d4-a45f-f8d027761251",
unique_id: str = "cfe92100-67c4-11d4-a45f-f8d027761251",
conn_error: bool = False,
) -> MockConfigEntry:
"""Set up the IPP integration in Home Assistant."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=unique_id,
data={
CONF_HOST: host,
CONF_PORT: port,
CONF_SSL: ssl,
CONF_VERIFY_SSL: True,
CONF_BASE_PATH: base_path,
CONF_UUID: uuid,
},
)
entry.add_to_hass(hass)
mock_connection(
aioclient_mock,
host=host,
port=port,
ssl=ssl,
base_path=base_path,
conn_error=conn_error,
)
if not skip_setup:
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return entry

View file

@ -0,0 +1,99 @@
"""Fixtures for IPP integration tests."""
from collections.abc import Generator
import json
from unittest.mock import AsyncMock, MagicMock, patch
from pyipp import Printer
import pytest
from homeassistant.components.ipp.const import CONF_BASE_PATH, DOMAIN
from homeassistant.const import (
CONF_HOST,
CONF_PORT,
CONF_SSL,
CONF_UUID,
CONF_VERIFY_SSL,
)
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, load_fixture
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Return the default mocked config entry."""
return MockConfigEntry(
title="IPP Printer",
domain=DOMAIN,
data={
CONF_HOST: "192.168.1.31",
CONF_PORT: 631,
CONF_SSL: False,
CONF_VERIFY_SSL: True,
CONF_BASE_PATH: "/ipp/print",
CONF_UUID: "cfe92100-67c4-11d4-a45f-f8d027761251",
},
unique_id="cfe92100-67c4-11d4-a45f-f8d027761251",
)
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
"""Mock setting up a config entry."""
with patch(
"homeassistant.components.ipp.async_setup_entry", return_value=True
) as mock_setup_entry:
yield mock_setup_entry
@pytest.fixture
async def mock_printer(
request: pytest.FixtureRequest,
) -> Printer:
"""Return the mocked printer."""
fixture: str = "ipp/printer.json"
if hasattr(request, "param") and request.param:
fixture = request.param
return Printer.from_dict(json.loads(load_fixture(fixture)))
@pytest.fixture
def mock_ipp_config_flow(
mock_printer: Printer,
) -> Generator[None, MagicMock, None]:
"""Return a mocked IPP client."""
with patch(
"homeassistant.components.ipp.config_flow.IPP", autospec=True
) as ipp_mock:
client = ipp_mock.return_value
client.printer.return_value = mock_printer
yield client
@pytest.fixture
def mock_ipp(
request: pytest.FixtureRequest, mock_printer: Printer
) -> Generator[None, MagicMock, None]:
"""Return a mocked IPP client."""
with patch(
"homeassistant.components.ipp.coordinator.IPP", autospec=True
) as ipp_mock:
client = ipp_mock.return_value
client.printer.return_value = mock_printer
yield client
@pytest.fixture
async def init_integration(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_ipp: MagicMock
) -> MockConfigEntry:
"""Set up the IPP integration for testing."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
return mock_config_entry

View file

@ -0,0 +1,36 @@
{
"printer-uuid": "urn:uuid:cfe92100-67c4-11d4-a45f-f8d027761251",
"printer-state": "idle",
"printer-name": "Test Printer",
"printer-location": null,
"printer-make-and-model": "Test HA-1000 Series",
"printer-device-id": "MFG:TEST;CMD:ESCPL2,BDC,D4,D4PX,ESCPR7,END4,GENEP,URF;MDL:HA-1000 Series;CLS:PRINTER;DES:TEST HA-1000 Series;CID:EpsonRGB;FID:FXN,DPA,WFA,ETN,AFN,DAN,WRA;RID:20;DDS:022500;ELG:1000;SN:555534593035345555;URF:CP1,PQ4-5,OB9,OFU0,RS360,SRGB24,W8,DM3,IS1-7-6,V1.4,MT1-3-7-8-10-11-12;",
"printer-uri-supported": [
"ipps://192.168.1.31:631/ipp/print",
"ipp://192.168.1.31:631/ipp/print"
],
"uri-authentication-supported": ["none", "none"],
"uri-security-supported": ["tls", "none"],
"printer-info": "Test HA-1000 Series",
"printer-up-time": 30,
"printer-firmware-string-version": "20.23.06HA",
"printer-more-info": "http://192.168.1.31:80/PRESENTATION/BONJOUR",
"marker-names": [
"Black ink",
"Photo black ink",
"Cyan ink",
"Yellow ink",
"Magenta ink"
],
"marker-types": [
"ink-cartridge",
"ink-cartridge",
"ink-cartridge",
"ink-cartridge",
"ink-cartridge"
],
"marker-colors": ["#000000", "#000000", "#00FFFF", "#FFFF00", "#FF00FF"],
"marker-levels": [58, 98, 91, 95, 73],
"marker-low-levels": [10, 10, 10, 10, 10],
"marker-high-levels": [100, 100, 100, 100, 100]
}

View file

@ -1,6 +1,15 @@
"""Tests for the IPP config flow."""
import dataclasses
from unittest.mock import patch
from unittest.mock import MagicMock
from pyipp import (
IPPConnectionError,
IPPConnectionUpgradeRequired,
IPPError,
IPPParseError,
IPPVersionNotSupportedError,
)
import pytest
from homeassistant.components.ipp.const import CONF_BASE_PATH, DOMAIN
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
@ -12,11 +21,11 @@ from . import (
MOCK_USER_INPUT,
MOCK_ZEROCONF_IPP_SERVICE_INFO,
MOCK_ZEROCONF_IPPS_SERVICE_INFO,
init_integration,
mock_connection,
)
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.common import MockConfigEntry
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
async def test_show_user_form(hass: HomeAssistant) -> None:
@ -31,11 +40,10 @@ async def test_show_user_form(hass: HomeAssistant) -> None:
async def test_show_zeroconf_form(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test that the zeroconf confirmation form is served."""
mock_connection(aioclient_mock)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -49,10 +57,11 @@ async def test_show_zeroconf_form(
async def test_connection_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we show user form on IPP connection error."""
mock_connection(aioclient_mock, conn_error=True)
mock_ipp_config_flow.printer.side_effect = IPPConnectionError
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -67,10 +76,11 @@ async def test_connection_error(
async def test_zeroconf_connection_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow on IPP connection error."""
mock_connection(aioclient_mock, conn_error=True)
mock_ipp_config_flow.printer.side_effect = IPPConnectionError
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -84,10 +94,11 @@ async def test_zeroconf_connection_error(
async def test_zeroconf_confirm_connection_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow on IPP connection error."""
mock_connection(aioclient_mock, conn_error=True)
mock_ipp_config_flow.printer.side_effect = IPPConnectionError
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -99,10 +110,11 @@ async def test_zeroconf_confirm_connection_error(
async def test_user_connection_upgrade_required(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we show the user form if connection upgrade required by server."""
mock_connection(aioclient_mock, conn_upgrade_error=True)
mock_ipp_config_flow.printer.side_effect = IPPConnectionUpgradeRequired
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -117,10 +129,11 @@ async def test_user_connection_upgrade_required(
async def test_zeroconf_connection_upgrade_required(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow on IPP connection error."""
mock_connection(aioclient_mock, conn_upgrade_error=True)
mock_ipp_config_flow.printer.side_effect = IPPConnectionUpgradeRequired
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -134,10 +147,11 @@ async def test_zeroconf_connection_upgrade_required(
async def test_user_parse_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort user flow on IPP parse error."""
mock_connection(aioclient_mock, parse_error=True)
mock_ipp_config_flow.printer.side_effect = IPPParseError
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -151,10 +165,11 @@ async def test_user_parse_error(
async def test_zeroconf_parse_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow on IPP parse error."""
mock_connection(aioclient_mock, parse_error=True)
mock_ipp_config_flow.printer.side_effect = IPPParseError
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -168,10 +183,11 @@ async def test_zeroconf_parse_error(
async def test_user_ipp_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort the user flow on IPP error."""
mock_connection(aioclient_mock, ipp_error=True)
mock_ipp_config_flow.printer.side_effect = IPPError
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -185,10 +201,11 @@ async def test_user_ipp_error(
async def test_zeroconf_ipp_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow on IPP error."""
mock_connection(aioclient_mock, ipp_error=True)
mock_ipp_config_flow.printer.side_effect = IPPError
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -202,10 +219,11 @@ async def test_zeroconf_ipp_error(
async def test_user_ipp_version_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort user flow on IPP version not supported error."""
mock_connection(aioclient_mock, version_not_supported=True)
mock_ipp_config_flow.printer.side_effect = IPPVersionNotSupportedError
user_input = {**MOCK_USER_INPUT}
result = await hass.config_entries.flow.async_init(
@ -219,10 +237,11 @@ async def test_user_ipp_version_error(
async def test_zeroconf_ipp_version_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow on IPP version not supported error."""
mock_connection(aioclient_mock, version_not_supported=True)
mock_ipp_config_flow.printer.side_effect = IPPVersionNotSupportedError
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -236,10 +255,12 @@ async def test_zeroconf_ipp_version_error(
async def test_user_device_exists_abort(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort user flow if printer already configured."""
await init_integration(hass, aioclient_mock, skip_setup=True)
mock_config_entry.add_to_hass(hass)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
@ -253,10 +274,12 @@ async def test_user_device_exists_abort(
async def test_zeroconf_device_exists_abort(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow if printer already configured."""
await init_integration(hass, aioclient_mock, skip_setup=True)
mock_config_entry.add_to_hass(hass)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -270,10 +293,12 @@ async def test_zeroconf_device_exists_abort(
async def test_zeroconf_with_uuid_device_exists_abort(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow if printer already configured."""
await init_integration(hass, aioclient_mock, skip_setup=True)
mock_config_entry.add_to_hass(hass)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
discovery_info.properties = {
@ -292,10 +317,12 @@ async def test_zeroconf_with_uuid_device_exists_abort(
async def test_zeroconf_empty_unique_id(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test zeroconf flow if printer lacks (empty) unique identification."""
mock_connection(aioclient_mock, no_unique_id=True)
printer = mock_ipp_config_flow.printer.return_value
printer.unique_id = None
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
discovery_info.properties = {
@ -312,10 +339,12 @@ async def test_zeroconf_empty_unique_id(
async def test_zeroconf_no_unique_id(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test zeroconf flow if printer lacks unique identification."""
mock_connection(aioclient_mock, no_unique_id=True)
printer = mock_ipp_config_flow.printer.return_value
printer.unique_id = None
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
@ -328,11 +357,10 @@ async def test_zeroconf_no_unique_id(
async def test_full_user_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test the full manual user flow from start to finish."""
mock_connection(aioclient_mock)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
@ -341,11 +369,10 @@ async def test_full_user_flow_implementation(
assert result["step_id"] == "user"
assert result["type"] == FlowResultType.FORM
with patch("homeassistant.components.ipp.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_HOST: "192.168.1.31", CONF_BASE_PATH: "/ipp/print"},
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_HOST: "192.168.1.31", CONF_BASE_PATH: "/ipp/print"},
)
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == "192.168.1.31"
@ -359,11 +386,10 @@ async def test_full_user_flow_implementation(
async def test_full_zeroconf_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test the full manual user flow from start to finish."""
mock_connection(aioclient_mock)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPP_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -374,10 +400,9 @@ async def test_full_zeroconf_flow_implementation(
assert result["step_id"] == "zeroconf_confirm"
assert result["type"] == FlowResultType.FORM
with patch("homeassistant.components.ipp.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == "EPSON XP-6000 Series"
@ -393,11 +418,10 @@ async def test_full_zeroconf_flow_implementation(
async def test_full_zeroconf_tls_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_ipp_config_flow: MagicMock,
) -> None:
"""Test the full manual user flow from start to finish."""
mock_connection(aioclient_mock, ssl=True)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_IPPS_SERVICE_INFO)
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -409,10 +433,9 @@ async def test_full_zeroconf_tls_flow_implementation(
assert result["type"] == FlowResultType.FORM
assert result["description_placeholders"] == {CONF_NAME: "EPSON XP-6000 Series"}
with patch("homeassistant.components.ipp.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == "EPSON XP-6000 Series"

View file

@ -1,33 +1,45 @@
"""Tests for the IPP integration."""
from unittest.mock import AsyncMock, MagicMock, patch
from pyipp import IPPConnectionError
from homeassistant.components.ipp.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from . import init_integration
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.common import MockConfigEntry
@patch(
"homeassistant.components.ipp.coordinator.IPP._request",
side_effect=IPPConnectionError,
)
async def test_config_entry_not_ready(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
mock_request: MagicMock, hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test the IPP configuration entry not ready."""
entry = await init_integration(hass, aioclient_mock, conn_error=True)
assert entry.state is ConfigEntryState.SETUP_RETRY
async def test_unload_config_entry(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test the IPP configuration entry unloading."""
entry = await init_integration(hass, aioclient_mock)
assert hass.data[DOMAIN]
assert entry.entry_id in hass.data[DOMAIN]
assert entry.state is ConfigEntryState.LOADED
await hass.config_entries.async_unload(entry.entry_id)
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert entry.entry_id not in hass.data[DOMAIN]
assert entry.state is ConfigEntryState.NOT_LOADED
assert mock_request.call_count == 1
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_load_unload_config_entry(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ipp: AsyncMock,
) -> None:
"""Test the IPP configuration entry loading/unloading."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.entry_id in hass.data[DOMAIN]
assert mock_config_entry.state is ConfigEntryState.LOADED
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.entry_id not in hass.data[DOMAIN]
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED

View file

@ -1,119 +1,105 @@
"""Tests for the IPP sensor platform."""
from datetime import datetime
from unittest.mock import patch
from unittest.mock import AsyncMock
from homeassistant.components.ipp.const import DOMAIN
from homeassistant.components.sensor import (
ATTR_OPTIONS as SENSOR_ATTR_OPTIONS,
DOMAIN as SENSOR_DOMAIN,
)
import pytest
from homeassistant.components.sensor import ATTR_OPTIONS
from homeassistant.const import ATTR_ICON, ATTR_UNIT_OF_MEASUREMENT, PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from . import init_integration, mock_connection
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.common import MockConfigEntry
@pytest.mark.freeze_time("2019-11-11 09:10:32+00:00")
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensors(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
init_integration: MockConfigEntry,
) -> None:
"""Test the creation and values of the IPP sensors."""
mock_connection(aioclient_mock)
entry = await init_integration(hass, aioclient_mock, skip_setup=True)
registry = er.async_get(hass)
# Pre-create registry entries for disabled by default sensors
registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
"cfe92100-67c4-11d4-a45f-f8d027761251_uptime",
suggested_object_id="epson_xp_6000_series_uptime",
disabled_by=None,
)
test_time = datetime(2019, 11, 11, 9, 10, 32, tzinfo=dt_util.UTC)
with patch("homeassistant.components.ipp.sensor.utcnow", return_value=test_time):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get("sensor.epson_xp_6000_series")
state = hass.states.get("sensor.test_ha_1000_series")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:printer"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
assert state.attributes.get(SENSOR_ATTR_OPTIONS) == ["idle", "printing", "stopped"]
assert state.attributes.get(ATTR_OPTIONS) == ["idle", "printing", "stopped"]
entry = registry.async_get("sensor.epson_xp_6000_series")
entry = entity_registry.async_get("sensor.test_ha_1000_series")
assert entry
assert entry.translation_key == "printer"
state = hass.states.get("sensor.epson_xp_6000_series_black_ink")
state = hass.states.get("sensor.test_ha_1000_series_black_ink")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:water"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is PERCENTAGE
assert state.state == "58"
state = hass.states.get("sensor.epson_xp_6000_series_photo_black_ink")
state = hass.states.get("sensor.test_ha_1000_series_photo_black_ink")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:water"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is PERCENTAGE
assert state.state == "98"
state = hass.states.get("sensor.epson_xp_6000_series_cyan_ink")
state = hass.states.get("sensor.test_ha_1000_series_cyan_ink")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:water"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is PERCENTAGE
assert state.state == "91"
state = hass.states.get("sensor.epson_xp_6000_series_yellow_ink")
state = hass.states.get("sensor.test_ha_1000_series_yellow_ink")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:water"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is PERCENTAGE
assert state.state == "95"
state = hass.states.get("sensor.epson_xp_6000_series_magenta_ink")
state = hass.states.get("sensor.test_ha_1000_series_magenta_ink")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:water"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is PERCENTAGE
assert state.state == "73"
state = hass.states.get("sensor.epson_xp_6000_series_uptime")
state = hass.states.get("sensor.test_ha_1000_series_uptime")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:clock-outline"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
assert state.state == "2019-10-26T15:37:00+00:00"
assert state.state == "2019-11-11T09:10:02+00:00"
entry = registry.async_get("sensor.epson_xp_6000_series_uptime")
entry = entity_registry.async_get("sensor.test_ha_1000_series_uptime")
assert entry
assert entry.unique_id == "cfe92100-67c4-11d4-a45f-f8d027761251_uptime"
async def test_disabled_by_default_sensors(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
init_integration: MockConfigEntry,
) -> None:
"""Test the disabled by default IPP sensors."""
await init_integration(hass, aioclient_mock)
registry = er.async_get(hass)
state = hass.states.get("sensor.epson_xp_6000_series_uptime")
state = hass.states.get("sensor.test_ha_1000_series_uptime")
assert state is None
entry = registry.async_get("sensor.epson_xp_6000_series_uptime")
entry = registry.async_get("sensor.test_ha_1000_series_uptime")
assert entry
assert entry.disabled
assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION
async def test_missing_entry_unique_id(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ipp: AsyncMock,
) -> None:
"""Test the unique_id of IPP sensor when printer is missing identifiers."""
entry = await init_integration(hass, aioclient_mock, uuid=None, unique_id=None)
mock_config_entry.unique_id = None
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
registry = er.async_get(hass)
entity = registry.async_get("sensor.epson_xp_6000_series")
entity = registry.async_get("sensor.test_ha_1000_series")
assert entity
assert entity.unique_id == f"{entry.entry_id}_printer"
assert entity.unique_id == f"{mock_config_entry.entry_id}_printer"