mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Add tests to flexit_bacnet integration (#108291)
* Add fixture for update method * Mock flexit_bacnet * Adds test for climate * Adds snapshot testing * Adds test for init, refactor test for config flow
This commit is contained in:
parent
65abbe5369
commit
7d5a672ed1
@ -1 +1,17 @@
|
||||
"""Tests for the Flexit Nordic (BACnet) integration."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_with_selected_platforms(
|
||||
hass: HomeAssistant, entry: MockConfigEntry, platforms: list[Platform]
|
||||
) -> None:
|
||||
"""Set up the Flexit Nordic (BACnet) integration with the selected platforms."""
|
||||
entry.add_to_hass(hass)
|
||||
with patch("homeassistant.components.flexit_bacnet.PLATFORMS", platforms):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -1,13 +1,18 @@
|
||||
"""Configuration for Flexit Nordic (BACnet) tests."""
|
||||
from unittest.mock import patch
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from flexit_bacnet import FlexitBACnet
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.flexit_bacnet.const import DOMAIN
|
||||
from homeassistant.const import CONF_DEVICE_ID, CONF_IP_ADDRESS
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def flow_id(hass: HomeAssistant) -> str:
|
||||
@ -22,23 +27,44 @@ async def flow_id(hass: HomeAssistant) -> str:
|
||||
return result["flow_id"]
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_serial_number_and_device_name():
|
||||
"""Mock serial number of the device."""
|
||||
@pytest.fixture
|
||||
def mock_flexit_bacnet() -> Generator[AsyncMock, None, None]:
|
||||
"""Mock data from the device."""
|
||||
flexit_bacnet = AsyncMock(spec=FlexitBACnet)
|
||||
with patch(
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.serial_number",
|
||||
"0000-0001",
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet",
|
||||
return_value=flexit_bacnet,
|
||||
), patch(
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.device_name",
|
||||
"Device Name",
|
||||
"homeassistant.components.flexit_bacnet.FlexitBACnet",
|
||||
return_value=flexit_bacnet,
|
||||
):
|
||||
yield
|
||||
flexit_bacnet.serial_number = "0000-0001"
|
||||
flexit_bacnet.device_name = "Device Name"
|
||||
flexit_bacnet.room_temperature = 19.0
|
||||
flexit_bacnet.air_temp_setpoint_away = 18.0
|
||||
flexit_bacnet.air_temp_setpoint_home = 22.0
|
||||
flexit_bacnet.ventilation_mode = 4
|
||||
|
||||
yield flexit_bacnet
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_setup_entry():
|
||||
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||
"""Mock setting up a config entry."""
|
||||
with patch(
|
||||
"homeassistant.components.flexit_bacnet.async_setup_entry", return_value=True
|
||||
) as setup_entry_mock:
|
||||
yield setup_entry_mock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Mock a config entry."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
unique_id="0000-0001",
|
||||
)
|
||||
|
73
tests/components/flexit_bacnet/snapshots/test_climate.ambr
Normal file
73
tests/components/flexit_bacnet/snapshots/test_climate.ambr
Normal file
@ -0,0 +1,73 @@
|
||||
# serializer version: 1
|
||||
# name: test_climate_entity
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 19.0,
|
||||
'friendly_name': 'Device Name',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
]),
|
||||
'max_temp': 30,
|
||||
'min_temp': 10,
|
||||
'preset_mode': 'boost',
|
||||
'preset_modes': list([
|
||||
'away',
|
||||
'home',
|
||||
'boost',
|
||||
]),
|
||||
'supported_features': <ClimateEntityFeature: 17>,
|
||||
'target_temp_step': 0.5,
|
||||
'temperature': 22.0,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.device_name',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'fan_only',
|
||||
})
|
||||
# ---
|
||||
# name: test_climate_entity.1
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
]),
|
||||
'max_temp': 30,
|
||||
'min_temp': 10,
|
||||
'preset_modes': list([
|
||||
'away',
|
||||
'home',
|
||||
'boost',
|
||||
]),
|
||||
'target_temp_step': 0.5,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.device_name',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'flexit_bacnet',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 17>,
|
||||
'translation_key': None,
|
||||
'unique_id': '0000-0001',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
27
tests/components/flexit_bacnet/test_climate.py
Normal file
27
tests/components/flexit_bacnet/test_climate.py
Normal file
@ -0,0 +1,27 @@
|
||||
"""Tests for the Flexit Nordic (BACnet) climate entity."""
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.flexit_bacnet import setup_with_selected_platforms
|
||||
|
||||
ENTITY_CLIMATE = "climate.device_name"
|
||||
|
||||
|
||||
async def test_climate_entity(
|
||||
hass: HomeAssistant,
|
||||
mock_flexit_bacnet: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test the initial parameters."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
assert hass.states.get(ENTITY_CLIMATE) == snapshot
|
||||
assert entity_registry.async_get(ENTITY_CLIMATE) == snapshot
|
@ -1,31 +1,26 @@
|
||||
"""Test the Flexit Nordic (BACnet) config flow."""
|
||||
import asyncio.exceptions
|
||||
from unittest.mock import patch
|
||||
|
||||
from flexit_bacnet import DecodingError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.flexit_bacnet.const import DOMAIN
|
||||
from homeassistant.const import CONF_DEVICE_ID, CONF_IP_ADDRESS
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_form(hass: HomeAssistant, flow_id: str, mock_setup_entry) -> None:
|
||||
async def test_form(
|
||||
hass: HomeAssistant, flow_id: str, mock_setup_entry, mock_flexit_bacnet
|
||||
) -> None:
|
||||
"""Test we get the form and the happy path works."""
|
||||
with patch(
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update"
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow_id,
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow_id,
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "Device Name"
|
||||
@ -35,6 +30,7 @@ async def test_form(hass: HomeAssistant, flow_id: str, mock_setup_entry) -> None
|
||||
CONF_DEVICE_ID: 2,
|
||||
}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(mock_flexit_bacnet.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -50,39 +46,39 @@ async def test_form(hass: HomeAssistant, flow_id: str, mock_setup_entry) -> None
|
||||
],
|
||||
)
|
||||
async def test_flow_fails(
|
||||
hass: HomeAssistant, flow_id: str, error: Exception, message: str, mock_setup_entry
|
||||
hass: HomeAssistant,
|
||||
flow_id: str,
|
||||
error: Exception,
|
||||
message: str,
|
||||
mock_setup_entry,
|
||||
mock_flexit_bacnet,
|
||||
) -> None:
|
||||
"""Test that we return 'cannot_connect' error when attempting to connect to an incorrect IP address.
|
||||
|
||||
The flexit_bacnet library raises asyncio.exceptions.TimeoutError in that scenario.
|
||||
"""
|
||||
with patch(
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update",
|
||||
side_effect=error,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow_id,
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
mock_flexit_bacnet.update.side_effect = error
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow_id,
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["errors"] == {"base": message}
|
||||
assert len(mock_setup_entry.mock_calls) == 0
|
||||
|
||||
# ensure that user can recover from this error
|
||||
with patch(
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update"
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
mock_flexit_bacnet.update.side_effect = None
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
|
||||
assert result2["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == "Device Name"
|
||||
@ -94,27 +90,19 @@ async def test_flow_fails(
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_device_already_exist(hass: HomeAssistant, flow_id: str) -> None:
|
||||
async def test_form_device_already_exist(
|
||||
hass: HomeAssistant, flow_id: str, mock_flexit_bacnet, mock_config_entry
|
||||
) -> None:
|
||||
"""Test that we cannot add already added device."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow_id,
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
unique_id="0000-0001",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
with patch(
|
||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update"
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow_id,
|
||||
{
|
||||
CONF_IP_ADDRESS: "1.1.1.1",
|
||||
CONF_DEVICE_ID: 2,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
24
tests/components/flexit_bacnet/test_init.py
Normal file
24
tests/components/flexit_bacnet/test_init.py
Normal file
@ -0,0 +1,24 @@
|
||||
"""Tests for the Flexit Nordic (BACnet) __init__."""
|
||||
from homeassistant.components.flexit_bacnet.const import DOMAIN as FLEXIT_BACNET_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.flexit_bacnet import setup_with_selected_platforms
|
||||
|
||||
|
||||
async def test_loading_and_unloading_config_entry(
|
||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_flexit_bacnet
|
||||
) -> None:
|
||||
"""Test loading and unloading a config entry."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
assert len(hass.config_entries.async_entries(FLEXIT_BACNET_DOMAIN)) == 1
|
||||
assert mock_config_entry.state == ConfigEntryState.LOADED
|
||||
|
||||
assert await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert not hass.data.get(FLEXIT_BACNET_DOMAIN)
|
Loading…
x
Reference in New Issue
Block a user