Add tests for BSBLAN climate component (#124524)
* chore: Add tests for BSBLAN climate component * fix return types * fix MAC data * chore: Update BSBLAN climate component tests used setup from conftest added setup for farhenheit temp unit * chore: Update BSBLAN climate component tests use syrupy to compare results * add test for temp_unit * update climate tests set current_temperature to None in test case. Is this the correct way for testing? * chore: Update BSBLAN diagnostics to handle asynchronous data retrieval * chore: Refactor BSBLAN conftest.py to simplify fixture and patching * chore: Update BSBLAN climate component tests 100% test coverage * chore: Update BSBLAN diagnostics to handle asynchronous data retrieval * chore: Update snapshots * Fix BSBLAN climate test for async_set_preset_mode - Update test_async_set_preset_mode to correctly handle ServiceValidationError - Check for specific translation key instead of full error message - Ensure consistency between local tests and CI environment - Import ServiceValidationError explicitly for clarity * Update homeassistant/components/bsblan/entity.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * chore: Update BSBLAN conftest.py to simplify fixture and patching * chore: Update BSBLAN integration setup function parameter name * chore: removed set_static_value * refactor: Improve BSBLANClimate async_set_preset_mode method This commit refactors the async_set_preset_mode method in the BSBLANClimate class to improve code readability and maintainability. The method now checks if the HVAC mode is not set to AUTO and the preset mode is not NONE before raising a ServiceValidationError. Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * refactor: Improve tests test_celsius_fahrenheit test_climate_entity_properties test_async_set_hvac_mode test_async_set_preset_mode still broken. Not sure why hvac mode will not set. THis causes error with preset mode set * update snapshot * fix DOMAIN bsblan * refactor: Improve BSBLANClimate async_set_data method * refactor: fix last tests * refactor: Simplify async_get_config_entry_diagnostics method * refactor: Improve BSBLANClimate async_set_temperature method This commit improves the async_set_temperature method in the BSBLANClimate class. It removes the unnecessary parameter "expected_result" and simplifies the code by directly calling the service to set the temperature. The method now correctly asserts that the thermostat method is called with the correct temperature. * refactor: Add static data to async_get_config_entry_diagnostics * refactor: Add static data to async_get_config_entry_diagnostics right place * refactor: Improve error message for setting preset mode This commit updates the error message in the BSBLANClimate class when trying to set the preset mode. * refactor: Improve tests * Fix --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>pull/125501/head
parent
5108e1a1cd
commit
bfe19e82ff
|
@ -126,15 +126,14 @@ class BSBLANClimate(BSBLanEntity, ClimateEntity):
|
|||
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set preset mode."""
|
||||
# only allow preset mode when hvac mode is auto
|
||||
if self.hvac_mode == HVACMode.AUTO:
|
||||
await self.async_set_data(preset_mode=preset_mode)
|
||||
else:
|
||||
if self.hvac_mode != HVACMode.AUTO and preset_mode != PRESET_NONE:
|
||||
raise ServiceValidationError(
|
||||
"Preset mode can only be set when HVAC mode is set to 'auto'",
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="set_preset_mode_error",
|
||||
translation_placeholders={"preset_mode": preset_mode},
|
||||
)
|
||||
await self.async_set_data(preset_mode=preset_mode)
|
||||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperatures."""
|
||||
|
@ -148,11 +147,11 @@ class BSBLANClimate(BSBLanEntity, ClimateEntity):
|
|||
if ATTR_HVAC_MODE in kwargs:
|
||||
data[ATTR_HVAC_MODE] = kwargs[ATTR_HVAC_MODE]
|
||||
if ATTR_PRESET_MODE in kwargs:
|
||||
# If preset mode is None, set hvac to auto
|
||||
if kwargs[ATTR_PRESET_MODE] == PRESET_NONE:
|
||||
data[ATTR_HVAC_MODE] = HVACMode.AUTO
|
||||
else:
|
||||
data[ATTR_HVAC_MODE] = kwargs[ATTR_PRESET_MODE]
|
||||
if kwargs[ATTR_PRESET_MODE] == PRESET_ECO:
|
||||
data[ATTR_HVAC_MODE] = PRESET_ECO
|
||||
elif kwargs[ATTR_PRESET_MODE] == PRESET_NONE:
|
||||
data[ATTR_HVAC_MODE] = PRESET_NONE
|
||||
|
||||
try:
|
||||
await self.coordinator.client.thermostat(**data)
|
||||
except BSBLANError as err:
|
||||
|
|
|
@ -1 +1,18 @@
|
|||
"""Tests for the bsblan 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, config_entry: MockConfigEntry, platforms: list[Platform]
|
||||
) -> None:
|
||||
"""Set up the BSBLAN integration with the selected platforms."""
|
||||
config_entry.add_to_hass(hass)
|
||||
with patch("homeassistant.components.bsblan.PLATFORMS", platforms):
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
|
|
@ -40,7 +40,7 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bsblan() -> Generator[MagicMock]:
|
||||
def mock_bsblan() -> Generator[MagicMock, None, None]:
|
||||
"""Return a mocked BSBLAN client."""
|
||||
with (
|
||||
patch("homeassistant.components.bsblan.BSBLAN", autospec=True) as bsblan_mock,
|
||||
|
@ -52,7 +52,6 @@ def mock_bsblan() -> Generator[MagicMock]:
|
|||
load_fixture("device.json", DOMAIN)
|
||||
)
|
||||
bsblan.state.return_value = State.from_json(load_fixture("state.json", DOMAIN))
|
||||
|
||||
bsblan.static_values.return_value = StaticState.from_json(
|
||||
load_fixture("static.json", DOMAIN)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"min_temp": {
|
||||
"name": "Room temp frost protection setpoint",
|
||||
"error": 0,
|
||||
"value": "8.0",
|
||||
"desc": "",
|
||||
"dataType": 0,
|
||||
"readonly": 0,
|
||||
"unit": "°F"
|
||||
},
|
||||
"max_temp": {
|
||||
"name": "Summer/winter changeover temp heat circuit 1",
|
||||
"error": 0,
|
||||
"value": "20.0",
|
||||
"desc": "",
|
||||
"dataType": 0,
|
||||
"readonly": 0,
|
||||
"unit": "°F"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
# serializer version: 1
|
||||
# name: test_celsius_fahrenheit[static.json][climate.bsb_lan-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.AUTO: 'auto'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 20.0,
|
||||
'min_temp': 8.0,
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'none',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.bsb_lan',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bsblan',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:80:41:19:69:90-climate',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_celsius_fahrenheit[static.json][climate.bsb_lan-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 18.6,
|
||||
'friendly_name': 'BSB-LAN',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.AUTO: 'auto'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 20.0,
|
||||
'min_temp': 8.0,
|
||||
'preset_mode': 'none',
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'none',
|
||||
]),
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'temperature': 18.5,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.bsb_lan',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_celsius_fahrenheit[static_F.json][climate.bsb_lan-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.AUTO: 'auto'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': -6.7,
|
||||
'min_temp': -13.3,
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'none',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.bsb_lan',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bsblan',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:80:41:19:69:90-climate',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_celsius_fahrenheit[static_F.json][climate.bsb_lan-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': -7.4,
|
||||
'friendly_name': 'BSB-LAN',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.AUTO: 'auto'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': -6.7,
|
||||
'min_temp': -13.3,
|
||||
'preset_mode': 'none',
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'none',
|
||||
]),
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'temperature': -7.5,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.bsb_lan',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_climate_entity_properties[climate.bsb_lan-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.AUTO: 'auto'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 20.0,
|
||||
'min_temp': 8.0,
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'none',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.bsb_lan',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bsblan',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:80:41:19:69:90-climate',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_climate_entity_properties[climate.bsb_lan-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 18.6,
|
||||
'friendly_name': 'BSB-LAN',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.AUTO: 'auto'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 20.0,
|
||||
'min_temp': 8.0,
|
||||
'preset_mode': 'none',
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'none',
|
||||
]),
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'temperature': 18.5,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.bsb_lan',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
|
@ -0,0 +1,307 @@
|
|||
"""Tests for the BSB-Lan climate platform."""
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
from bsblan import BSBLANError, StaticState
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.bsblan.const import DOMAIN
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_PRESET_MODE,
|
||||
DOMAIN as CLIMATE_DOMAIN,
|
||||
PRESET_ECO,
|
||||
PRESET_NONE,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
|
||||
from . import setup_with_selected_platforms
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_time_changed,
|
||||
load_json_object_fixture,
|
||||
snapshot_platform,
|
||||
)
|
||||
|
||||
ENTITY_ID = "climate.bsb_lan"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("static_file"),
|
||||
[
|
||||
("static.json"),
|
||||
("static_F.json"),
|
||||
],
|
||||
)
|
||||
async def test_celsius_fahrenheit(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
static_file: str,
|
||||
) -> None:
|
||||
"""Test Celsius and Fahrenheit temperature units."""
|
||||
|
||||
static_data = load_json_object_fixture(static_file, DOMAIN)
|
||||
|
||||
mock_bsblan.static_values.return_value = StaticState.from_dict(static_data)
|
||||
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_climate_entity_properties(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test the climate entity properties."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
# Test when current_temperature is "---"
|
||||
mock_current_temp = MagicMock()
|
||||
mock_current_temp.value = "---"
|
||||
mock_bsblan.state.return_value.current_temperature = mock_current_temp
|
||||
|
||||
freezer.tick(timedelta(minutes=1))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state.attributes["current_temperature"] is None
|
||||
|
||||
# Test target_temperature
|
||||
mock_target_temp = MagicMock()
|
||||
mock_target_temp.value = "23.5"
|
||||
mock_bsblan.state.return_value.target_temperature = mock_target_temp
|
||||
|
||||
freezer.tick(timedelta(minutes=1))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state.attributes["temperature"] == 23.5
|
||||
|
||||
# Test hvac_mode
|
||||
mock_hvac_mode = MagicMock()
|
||||
mock_hvac_mode.value = HVACMode.AUTO
|
||||
mock_bsblan.state.return_value.hvac_mode = mock_hvac_mode
|
||||
|
||||
freezer.tick(timedelta(minutes=1))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state.state == HVACMode.AUTO
|
||||
|
||||
# Test preset_mode
|
||||
mock_hvac_mode.value = PRESET_ECO
|
||||
|
||||
freezer.tick(timedelta(minutes=1))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state.attributes["preset_mode"] == PRESET_ECO
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mode",
|
||||
[HVACMode.HEAT, HVACMode.AUTO, HVACMode.OFF],
|
||||
)
|
||||
async def test_async_set_hvac_mode(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mode: HVACMode,
|
||||
) -> None:
|
||||
"""Test setting HVAC mode via service call."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
# Call the service to set HVAC mode
|
||||
await hass.services.async_call(
|
||||
domain=CLIMATE_DOMAIN,
|
||||
service=SERVICE_SET_HVAC_MODE,
|
||||
service_data={ATTR_ENTITY_ID: ENTITY_ID, ATTR_HVAC_MODE: mode},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
# Assert that the thermostat method was called
|
||||
mock_bsblan.thermostat.assert_called_once_with(hvac_mode=mode)
|
||||
mock_bsblan.thermostat.reset_mock()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("hvac_mode", "preset_mode"),
|
||||
[
|
||||
(HVACMode.AUTO, PRESET_ECO),
|
||||
(HVACMode.AUTO, PRESET_NONE),
|
||||
],
|
||||
)
|
||||
async def test_async_set_preset_mode_succes(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
hvac_mode: HVACMode,
|
||||
preset_mode: str,
|
||||
) -> None:
|
||||
"""Test setting preset mode via service call."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
# patch hvac_mode
|
||||
mock_hvac_mode = MagicMock()
|
||||
mock_hvac_mode.value = hvac_mode
|
||||
mock_bsblan.state.return_value.hvac_mode = mock_hvac_mode
|
||||
|
||||
# Attempt to set the preset mode
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_PRESET_MODE: preset_mode},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("hvac_mode", "preset_mode"),
|
||||
[
|
||||
(
|
||||
HVACMode.HEAT,
|
||||
PRESET_ECO,
|
||||
)
|
||||
],
|
||||
)
|
||||
async def test_async_set_preset_mode_error(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
hvac_mode: HVACMode,
|
||||
preset_mode: str,
|
||||
) -> None:
|
||||
"""Test setting preset mode via service call."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
# patch hvac_mode
|
||||
mock_hvac_mode = MagicMock()
|
||||
mock_hvac_mode.value = hvac_mode
|
||||
mock_bsblan.state.return_value.hvac_mode = mock_hvac_mode
|
||||
|
||||
# Attempt to set the preset mode
|
||||
error_message = "Preset mode can only be set when HVAC mode is set to 'auto'"
|
||||
with pytest.raises(HomeAssistantError, match=error_message):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_PRESET_MODE: preset_mode},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("target_temp"),
|
||||
[
|
||||
(8.0), # Min temperature
|
||||
(15.0), # Mid-range temperature
|
||||
(20.0), # Max temperature
|
||||
],
|
||||
)
|
||||
async def test_async_set_temperature(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
target_temp: float,
|
||||
) -> None:
|
||||
"""Test setting temperature via service call."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
await hass.services.async_call(
|
||||
domain=CLIMATE_DOMAIN,
|
||||
service=SERVICE_SET_TEMPERATURE,
|
||||
service_data={ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: target_temp},
|
||||
blocking=True,
|
||||
)
|
||||
# Assert that the thermostat method was called with the correct temperature
|
||||
mock_bsblan.thermostat.assert_called_once_with(target_temperature=target_temp)
|
||||
|
||||
|
||||
async def test_async_set_data(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test setting data via service calls."""
|
||||
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.CLIMATE])
|
||||
|
||||
# Test setting temperature
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 19},
|
||||
blocking=True,
|
||||
)
|
||||
mock_bsblan.thermostat.assert_called_once_with(target_temperature=19)
|
||||
mock_bsblan.thermostat.reset_mock()
|
||||
|
||||
# Test setting HVAC mode
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
blocking=True,
|
||||
)
|
||||
mock_bsblan.thermostat.assert_called_once_with(hvac_mode=HVACMode.HEAT)
|
||||
mock_bsblan.thermostat.reset_mock()
|
||||
|
||||
# Patch HVAC mode to AUTO
|
||||
mock_hvac_mode = MagicMock()
|
||||
mock_hvac_mode.value = HVACMode.AUTO
|
||||
mock_bsblan.state.return_value.hvac_mode = mock_hvac_mode
|
||||
|
||||
# Test setting preset mode to ECO
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_PRESET_MODE: PRESET_ECO},
|
||||
blocking=True,
|
||||
)
|
||||
mock_bsblan.thermostat.assert_called_once_with(hvac_mode=PRESET_ECO)
|
||||
mock_bsblan.thermostat.reset_mock()
|
||||
|
||||
# Test setting preset mode to NONE
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_PRESET_MODE: PRESET_NONE},
|
||||
blocking=True,
|
||||
)
|
||||
mock_bsblan.thermostat.assert_called_once()
|
||||
mock_bsblan.thermostat.reset_mock()
|
||||
|
||||
# Test error handling
|
||||
mock_bsblan.thermostat.side_effect = BSBLANError("Test error")
|
||||
error_message = "An error occurred while updating the BSBLAN device"
|
||||
with pytest.raises(HomeAssistantError, match=error_message):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 20},
|
||||
blocking=True,
|
||||
)
|
|
@ -1,5 +1,7 @@
|
|||
"""Tests for the diagnostics data provided by the BSBLan integration."""
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -11,11 +13,13 @@ from tests.typing import ClientSessionGenerator
|
|||
|
||||
async def test_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
mock_bsblan: AsyncMock,
|
||||
hass_client: ClientSessionGenerator,
|
||||
init_integration: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test diagnostics."""
|
||||
|
||||
diagnostics_data = await get_diagnostics_for_config_entry(
|
||||
hass, hass_client, init_integration
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue