mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +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."""
|
"""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."""
|
"""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
|
import pytest
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components.flexit_bacnet.const import DOMAIN
|
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.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def flow_id(hass: HomeAssistant) -> str:
|
async def flow_id(hass: HomeAssistant) -> str:
|
||||||
@ -22,23 +27,44 @@ async def flow_id(hass: HomeAssistant) -> str:
|
|||||||
return result["flow_id"]
|
return result["flow_id"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture
|
||||||
def mock_serial_number_and_device_name():
|
def mock_flexit_bacnet() -> Generator[AsyncMock, None, None]:
|
||||||
"""Mock serial number of the device."""
|
"""Mock data from the device."""
|
||||||
|
flexit_bacnet = AsyncMock(spec=FlexitBACnet)
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.serial_number",
|
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet",
|
||||||
"0000-0001",
|
return_value=flexit_bacnet,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.device_name",
|
"homeassistant.components.flexit_bacnet.FlexitBACnet",
|
||||||
"Device Name",
|
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
|
@pytest.fixture
|
||||||
def mock_setup_entry():
|
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||||
"""Mock setting up a config entry."""
|
"""Mock setting up a config entry."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.flexit_bacnet.async_setup_entry", return_value=True
|
"homeassistant.components.flexit_bacnet.async_setup_entry", return_value=True
|
||||||
) as setup_entry_mock:
|
) as setup_entry_mock:
|
||||||
yield 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."""
|
"""Test the Flexit Nordic (BACnet) config flow."""
|
||||||
import asyncio.exceptions
|
import asyncio.exceptions
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from flexit_bacnet import DecodingError
|
from flexit_bacnet import DecodingError
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.flexit_bacnet.const import DOMAIN
|
|
||||||
from homeassistant.const import CONF_DEVICE_ID, CONF_IP_ADDRESS
|
from homeassistant.const import CONF_DEVICE_ID, CONF_IP_ADDRESS
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
|
||||||
|
|
||||||
|
async def test_form(
|
||||||
async def test_form(hass: HomeAssistant, flow_id: str, mock_setup_entry) -> None:
|
hass: HomeAssistant, flow_id: str, mock_setup_entry, mock_flexit_bacnet
|
||||||
|
) -> None:
|
||||||
"""Test we get the form and the happy path works."""
|
"""Test we get the form and the happy path works."""
|
||||||
with patch(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update"
|
flow_id,
|
||||||
):
|
{
|
||||||
result = await hass.config_entries.flow.async_configure(
|
CONF_IP_ADDRESS: "1.1.1.1",
|
||||||
flow_id,
|
CONF_DEVICE_ID: 2,
|
||||||
{
|
},
|
||||||
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.CREATE_ENTRY
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
assert result["title"] == "Device Name"
|
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,
|
CONF_DEVICE_ID: 2,
|
||||||
}
|
}
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
assert len(mock_flexit_bacnet.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@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(
|
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:
|
) -> None:
|
||||||
"""Test that we return 'cannot_connect' error when attempting to connect to an incorrect IP address.
|
"""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.
|
The flexit_bacnet library raises asyncio.exceptions.TimeoutError in that scenario.
|
||||||
"""
|
"""
|
||||||
with patch(
|
mock_flexit_bacnet.update.side_effect = error
|
||||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update",
|
result = await hass.config_entries.flow.async_configure(
|
||||||
side_effect=error,
|
flow_id,
|
||||||
):
|
{
|
||||||
result = await hass.config_entries.flow.async_configure(
|
CONF_IP_ADDRESS: "1.1.1.1",
|
||||||
flow_id,
|
CONF_DEVICE_ID: 2,
|
||||||
{
|
},
|
||||||
CONF_IP_ADDRESS: "1.1.1.1",
|
)
|
||||||
CONF_DEVICE_ID: 2,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == FlowResultType.FORM
|
assert result["type"] == FlowResultType.FORM
|
||||||
assert result["errors"] == {"base": message}
|
assert result["errors"] == {"base": message}
|
||||||
assert len(mock_setup_entry.mock_calls) == 0
|
assert len(mock_setup_entry.mock_calls) == 0
|
||||||
|
|
||||||
# ensure that user can recover from this error
|
# ensure that user can recover from this error
|
||||||
with patch(
|
mock_flexit_bacnet.update.side_effect = None
|
||||||
"homeassistant.components.flexit_bacnet.config_flow.FlexitBACnet.update"
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
):
|
result["flow_id"],
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
{
|
||||||
result["flow_id"],
|
CONF_IP_ADDRESS: "1.1.1.1",
|
||||||
{
|
CONF_DEVICE_ID: 2,
|
||||||
CONF_IP_ADDRESS: "1.1.1.1",
|
},
|
||||||
CONF_DEVICE_ID: 2,
|
)
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result2["type"] == FlowResultType.CREATE_ENTRY
|
assert result2["type"] == FlowResultType.CREATE_ENTRY
|
||||||
assert result2["title"] == "Device Name"
|
assert result2["title"] == "Device Name"
|
||||||
@ -94,27 +90,19 @@ async def test_flow_fails(
|
|||||||
assert len(mock_setup_entry.mock_calls) == 1
|
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."""
|
"""Test that we cannot add already added device."""
|
||||||
entry = MockConfigEntry(
|
mock_config_entry.add_to_hass(hass)
|
||||||
domain=DOMAIN,
|
|
||||||
data={
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
flow_id,
|
||||||
|
{
|
||||||
CONF_IP_ADDRESS: "1.1.1.1",
|
CONF_IP_ADDRESS: "1.1.1.1",
|
||||||
CONF_DEVICE_ID: 2,
|
CONF_DEVICE_ID: 2,
|
||||||
},
|
},
|
||||||
unique_id="0000-0001",
|
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
await hass.async_block_till_done()
|
||||||
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()
|
|
||||||
assert result["type"] == FlowResultType.ABORT
|
assert result["type"] == FlowResultType.ABORT
|
||||||
assert result["reason"] == "already_configured"
|
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