Refactor bond unit tests to reduce boilerplate (#38177)

* Refactor bond unit tests to reduce boilerplate

* Refactor bond unit tests to reduce boilerplate (PR feedback)

* Refactor bond unit tests to reduce boilerplate (PR feedback, nullcontext)
This commit is contained in:
Eugene Prystupa 2020-07-26 13:15:21 -04:00 committed by GitHub
parent 34ac4e78af
commit 2d6eb5c05d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 122 additions and 80 deletions

View file

@ -1,7 +1,8 @@
"""Common methods used across tests for Bond."""
from asyncio import TimeoutError as AsyncIOTimeoutError
from contextlib import nullcontext
from datetime import timedelta
from typing import Any, Dict
from typing import Any, Dict, Optional
from homeassistant import core
from homeassistant.components.bond.const import DOMAIN as BOND_DOMAIN
@ -12,19 +13,35 @@ from homeassistant.util import utcnow
from tests.async_mock import patch
from tests.common import MockConfigEntry, async_fire_time_changed
MOCK_HUB_VERSION: dict = {"bondid": "test-bond-id"}
def patch_setup_entry(domain: str, *, enabled: bool = True):
"""Patch async_setup_entry for specified domain."""
if not enabled:
return nullcontext()
return patch(f"homeassistant.components.bond.{domain}.async_setup_entry")
async def setup_bond_entity(
hass: core.HomeAssistant, config_entry: MockConfigEntry, hub_version=None
hass: core.HomeAssistant,
config_entry: MockConfigEntry,
*,
patch_version=False,
patch_device_ids=False,
patch_platforms=False,
):
"""Set up Bond entity."""
if hub_version is None:
hub_version = MOCK_HUB_VERSION
config_entry.add_to_hass(hass)
with patch("homeassistant.components.bond.Bond.version", return_value=hub_version):
with patch_bond_version(enabled=patch_version), patch_bond_device_ids(
enabled=patch_device_ids
), patch_setup_entry("cover", enabled=patch_platforms), patch_setup_entry(
"fan", enabled=patch_platforms
), patch_setup_entry(
"light", enabled=patch_platforms
), patch_setup_entry(
"switch", enabled=patch_platforms
):
return await hass.config_entries.async_setup(config_entry.entry_id)
@ -36,47 +53,77 @@ async def setup_platform(
props: Dict[str, Any] = None,
):
"""Set up the specified Bond platform."""
if not props:
props = {}
mock_entry = MockConfigEntry(
domain=BOND_DOMAIN,
data={CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
)
mock_entry.add_to_hass(hass)
with patch("homeassistant.components.bond.PLATFORMS", [platform]), patch(
"homeassistant.components.bond.Bond.version", return_value=MOCK_HUB_VERSION
), patch_bond_device_ids(return_value=[bond_device_id],), patch(
"homeassistant.components.bond.Bond.device", return_value=discovered_device
), patch_bond_device_state(
return_value={}
), patch(
"homeassistant.components.bond.Bond.device_properties", return_value=props
), patch(
"homeassistant.components.bond.Bond.device_state", return_value={}
):
assert await async_setup_component(hass, BOND_DOMAIN, {})
await hass.async_block_till_done()
with patch("homeassistant.components.bond.PLATFORMS", [platform]):
with patch_bond_version(), patch_bond_device_ids(
return_value=[bond_device_id]
), patch_bond_device(
return_value=discovered_device
), patch_bond_device_state(), patch_bond_device_properties(
return_value=props
), patch_bond_device_state():
assert await async_setup_component(hass, BOND_DOMAIN, {})
await hass.async_block_till_done()
return mock_entry
def patch_bond_device_ids(return_value=None):
"""Patch Bond API devices command."""
def patch_bond_version(enabled: bool = True, return_value: Optional[dict] = None):
"""Patch Bond API version endpoint."""
if not enabled:
return nullcontext()
if return_value is None:
return_value = {"bondid": "test-bond-id"}
return patch(
"homeassistant.components.bond.Bond.version", return_value=return_value
)
def patch_bond_device_ids(enabled: bool = True, return_value=None, side_effect=None):
"""Patch Bond API devices endpoint."""
if not enabled:
return nullcontext()
if return_value is None:
return_value = []
return patch(
"homeassistant.components.bond.Bond.devices", return_value=return_value,
"homeassistant.components.bond.Bond.devices",
return_value=return_value,
side_effect=side_effect,
)
def patch_bond_device(return_value=None):
"""Patch Bond API device endpoint."""
return patch(
"homeassistant.components.bond.Bond.device", return_value=return_value,
)
def patch_bond_action():
"""Patch Bond API action command."""
"""Patch Bond API action endpoint."""
return patch("homeassistant.components.bond.Bond.action")
def patch_bond_device_properties(return_value=None):
"""Patch Bond API device properties endpoint."""
if return_value is None:
return_value = {}
return patch(
"homeassistant.components.bond.Bond.device_properties",
return_value=return_value,
)
def patch_bond_device_state(return_value=None, side_effect=None):
"""Patch Bond API device state endpoint."""
if return_value is None:

View file

@ -6,6 +6,8 @@ from homeassistant import config_entries, core, setup
from homeassistant.components.bond.const import DOMAIN
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from .common import patch_bond_device_ids
from tests.async_mock import Mock, patch
@ -18,21 +20,20 @@ async def test_form(hass: core.HomeAssistant):
assert result["type"] == "form"
assert result["errors"] == {}
with patch(
"homeassistant.components.bond.config_flow.Bond.devices", return_value=[],
), patch(
with patch_bond_device_ids(), patch(
"homeassistant.components.bond.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.bond.async_setup_entry", return_value=True,
) as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
result["flow_id"],
{CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
assert result2["type"] == "create_entry"
assert result2["title"] == "1.1.1.1"
assert result2["title"] == "some host"
assert result2["data"] == {
CONF_HOST: "1.1.1.1",
CONF_HOST: "some host",
CONF_ACCESS_TOKEN: "test-token",
}
await hass.async_block_till_done()
@ -46,12 +47,12 @@ async def test_form_invalid_auth(hass: core.HomeAssistant):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.bond.config_flow.Bond.devices",
with patch_bond_device_ids(
side_effect=ClientResponseError(Mock(), Mock(), status=401),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
result["flow_id"],
{CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
assert result2["type"] == "form"
@ -64,12 +65,10 @@ async def test_form_cannot_connect(hass: core.HomeAssistant):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.bond.config_flow.Bond.devices",
side_effect=ClientConnectionError(),
):
with patch_bond_device_ids(side_effect=ClientConnectionError()):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
result["flow_id"],
{CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
assert result2["type"] == "form"
@ -82,12 +81,12 @@ async def test_form_unexpected_error(hass: core.HomeAssistant):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.bond.config_flow.Bond.devices",
side_effect=ClientResponseError(Mock(), Mock(), status=500),
with patch_bond_device_ids(
side_effect=ClientResponseError(Mock(), Mock(), status=500)
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
result["flow_id"],
{CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
assert result2["type"] == "form"

View file

@ -6,17 +6,11 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.setup import async_setup_component
from .common import patch_bond_device_ids, setup_bond_entity
from .common import patch_bond_version, patch_setup_entry, setup_bond_entity
from tests.async_mock import patch
from tests.common import MockConfigEntry
def patch_setup_entry(domain: str):
"""Patch async_setup_entry for specified domain."""
return patch(f"homeassistant.components.bond.{domain}.async_setup_entry")
async def test_async_setup_no_domain_config(hass: HomeAssistant):
"""Test setup without configuration is noop."""
result = await async_setup_component(hass, DOMAIN, {})
@ -27,29 +21,28 @@ async def test_async_setup_no_domain_config(hass: HomeAssistant):
async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAssistant):
"""Test that configuring entry sets up cover domain."""
config_entry = MockConfigEntry(
domain=DOMAIN, data={CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
domain=DOMAIN, data={CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
with patch_bond_device_ids(), patch_setup_entry(
"cover"
) as mock_cover_async_setup_entry, patch_setup_entry(
"fan"
) as mock_fan_async_setup_entry, patch_setup_entry(
"light"
) as mock_light_async_setup_entry, patch_setup_entry(
"switch"
) as mock_switch_async_setup_entry:
result = await setup_bond_entity(
hass,
config_entry,
hub_version={
"bondid": "test-bond-id",
"target": "test-model",
"fw_ver": "test-version",
},
)
assert result is True
await hass.async_block_till_done()
with patch_bond_version(
return_value={
"bondid": "test-bond-id",
"target": "test-model",
"fw_ver": "test-version",
}
):
with patch_setup_entry(
"cover"
) as mock_cover_async_setup_entry, patch_setup_entry(
"fan"
) as mock_fan_async_setup_entry, patch_setup_entry(
"light"
) as mock_light_async_setup_entry, patch_setup_entry(
"switch"
) as mock_switch_async_setup_entry:
result = await setup_bond_entity(hass, config_entry, patch_device_ids=True)
assert result is True
await hass.async_block_till_done()
assert config_entry.entry_id in hass.data[DOMAIN]
assert config_entry.state == ENTRY_STATE_LOADED
@ -74,15 +67,18 @@ async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAss
async def test_unload_config_entry(hass: HomeAssistant):
"""Test that configuration entry supports unloading."""
config_entry = MockConfigEntry(
domain=DOMAIN, data={CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
domain=DOMAIN, data={CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
)
with patch_bond_device_ids(), patch_setup_entry("cover"), patch_setup_entry(
"fan"
), patch_setup_entry("light"), patch_setup_entry("switch"):
result = await setup_bond_entity(hass, config_entry)
assert result is True
await hass.async_block_till_done()
result = await setup_bond_entity(
hass,
config_entry,
patch_version=True,
patch_device_ids=True,
patch_platforms=True,
)
assert result is True
await hass.async_block_till_done()
await hass.config_entries.async_unload(config_entry.entry_id)
await hass.async_block_till_done()