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.""" """Common methods used across tests for Bond."""
from asyncio import TimeoutError as AsyncIOTimeoutError from asyncio import TimeoutError as AsyncIOTimeoutError
from contextlib import nullcontext
from datetime import timedelta from datetime import timedelta
from typing import Any, Dict from typing import Any, Dict, Optional
from homeassistant import core from homeassistant import core
from homeassistant.components.bond.const import DOMAIN as BOND_DOMAIN 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.async_mock import patch
from tests.common import MockConfigEntry, async_fire_time_changed 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( 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.""" """Set up Bond entity."""
if hub_version is None:
hub_version = MOCK_HUB_VERSION
config_entry.add_to_hass(hass) 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) return await hass.config_entries.async_setup(config_entry.entry_id)
@ -36,47 +53,77 @@ async def setup_platform(
props: Dict[str, Any] = None, props: Dict[str, Any] = None,
): ):
"""Set up the specified Bond platform.""" """Set up the specified Bond platform."""
if not props:
props = {}
mock_entry = MockConfigEntry( mock_entry = MockConfigEntry(
domain=BOND_DOMAIN, domain=BOND_DOMAIN,
data={CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"}, data={CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
) )
mock_entry.add_to_hass(hass) mock_entry.add_to_hass(hass)
with patch("homeassistant.components.bond.PLATFORMS", [platform]), patch( with patch("homeassistant.components.bond.PLATFORMS", [platform]):
"homeassistant.components.bond.Bond.version", return_value=MOCK_HUB_VERSION with patch_bond_version(), patch_bond_device_ids(
), patch_bond_device_ids(return_value=[bond_device_id],), patch( return_value=[bond_device_id]
"homeassistant.components.bond.Bond.device", return_value=discovered_device ), patch_bond_device(
), patch_bond_device_state( return_value=discovered_device
return_value={} ), patch_bond_device_state(), patch_bond_device_properties(
), patch( return_value=props
"homeassistant.components.bond.Bond.device_properties", return_value=props ), patch_bond_device_state():
), patch( assert await async_setup_component(hass, BOND_DOMAIN, {})
"homeassistant.components.bond.Bond.device_state", return_value={} await hass.async_block_till_done()
):
assert await async_setup_component(hass, BOND_DOMAIN, {})
await hass.async_block_till_done()
return mock_entry return mock_entry
def patch_bond_device_ids(return_value=None): def patch_bond_version(enabled: bool = True, return_value: Optional[dict] = None):
"""Patch Bond API devices command.""" """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: if return_value is None:
return_value = [] return_value = []
return patch( 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(): def patch_bond_action():
"""Patch Bond API action command.""" """Patch Bond API action endpoint."""
return patch("homeassistant.components.bond.Bond.action") 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): def patch_bond_device_state(return_value=None, side_effect=None):
"""Patch Bond API device state endpoint.""" """Patch Bond API device state endpoint."""
if return_value is None: 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.components.bond.const import DOMAIN
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from .common import patch_bond_device_ids
from tests.async_mock import Mock, patch from tests.async_mock import Mock, patch
@ -18,21 +20,20 @@ async def test_form(hass: core.HomeAssistant):
assert result["type"] == "form" assert result["type"] == "form"
assert result["errors"] == {} assert result["errors"] == {}
with patch( with patch_bond_device_ids(), patch(
"homeassistant.components.bond.config_flow.Bond.devices", return_value=[],
), patch(
"homeassistant.components.bond.async_setup", return_value=True "homeassistant.components.bond.async_setup", return_value=True
) as mock_setup, patch( ) as mock_setup, patch(
"homeassistant.components.bond.async_setup_entry", return_value=True, "homeassistant.components.bond.async_setup_entry", return_value=True,
) as mock_setup_entry: ) as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure( 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["type"] == "create_entry"
assert result2["title"] == "1.1.1.1" assert result2["title"] == "some host"
assert result2["data"] == { assert result2["data"] == {
CONF_HOST: "1.1.1.1", CONF_HOST: "some host",
CONF_ACCESS_TOKEN: "test-token", CONF_ACCESS_TOKEN: "test-token",
} }
await hass.async_block_till_done() 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} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
with patch( with patch_bond_device_ids(
"homeassistant.components.bond.config_flow.Bond.devices",
side_effect=ClientResponseError(Mock(), Mock(), status=401), side_effect=ClientResponseError(Mock(), Mock(), status=401),
): ):
result2 = await hass.config_entries.flow.async_configure( 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" assert result2["type"] == "form"
@ -64,12 +65,10 @@ async def test_form_cannot_connect(hass: core.HomeAssistant):
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
with patch( with patch_bond_device_ids(side_effect=ClientConnectionError()):
"homeassistant.components.bond.config_flow.Bond.devices",
side_effect=ClientConnectionError(),
):
result2 = await hass.config_entries.flow.async_configure( 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" assert result2["type"] == "form"
@ -82,12 +81,12 @@ async def test_form_unexpected_error(hass: core.HomeAssistant):
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
with patch( with patch_bond_device_ids(
"homeassistant.components.bond.config_flow.Bond.devices", side_effect=ClientResponseError(Mock(), Mock(), status=500)
side_effect=ClientResponseError(Mock(), Mock(), status=500),
): ):
result2 = await hass.config_entries.flow.async_configure( 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" 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.helpers import device_registry as dr
from homeassistant.setup import async_setup_component 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 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): async def test_async_setup_no_domain_config(hass: HomeAssistant):
"""Test setup without configuration is noop.""" """Test setup without configuration is noop."""
result = await async_setup_component(hass, DOMAIN, {}) 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): async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAssistant):
"""Test that configuring entry sets up cover domain.""" """Test that configuring entry sets up cover domain."""
config_entry = MockConfigEntry( 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( with patch_bond_version(
"cover" return_value={
) as mock_cover_async_setup_entry, patch_setup_entry( "bondid": "test-bond-id",
"fan" "target": "test-model",
) as mock_fan_async_setup_entry, patch_setup_entry( "fw_ver": "test-version",
"light" }
) as mock_light_async_setup_entry, patch_setup_entry( ):
"switch" with patch_setup_entry(
) as mock_switch_async_setup_entry: "cover"
result = await setup_bond_entity( ) as mock_cover_async_setup_entry, patch_setup_entry(
hass, "fan"
config_entry, ) as mock_fan_async_setup_entry, patch_setup_entry(
hub_version={ "light"
"bondid": "test-bond-id", ) as mock_light_async_setup_entry, patch_setup_entry(
"target": "test-model", "switch"
"fw_ver": "test-version", ) as mock_switch_async_setup_entry:
}, result = await setup_bond_entity(hass, config_entry, patch_device_ids=True)
) assert result is True
assert result is True await hass.async_block_till_done()
await hass.async_block_till_done()
assert config_entry.entry_id in hass.data[DOMAIN] assert config_entry.entry_id in hass.data[DOMAIN]
assert config_entry.state == ENTRY_STATE_LOADED 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): async def test_unload_config_entry(hass: HomeAssistant):
"""Test that configuration entry supports unloading.""" """Test that configuration entry supports unloading."""
config_entry = MockConfigEntry( 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( result = await setup_bond_entity(
"fan" hass,
), patch_setup_entry("light"), patch_setup_entry("switch"): config_entry,
result = await setup_bond_entity(hass, config_entry) patch_version=True,
assert result is True patch_device_ids=True,
await hass.async_block_till_done() 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.config_entries.async_unload(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()