Refactor all Sensibo tests (#134478)

* Add me json

* Mods

* Mods

* More

* Mods

* Mods

* clean

* last bits

* Fix

* unique id

* return_value

* remove blocking

* Fix rebase
This commit is contained in:
G Johansson 2025-01-03 12:44:47 +01:00 committed by GitHub
parent 19852ecc24
commit 36582f9ac2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1398 additions and 1880 deletions

View File

@ -2,16 +2,15 @@
from __future__ import annotations
from collections.abc import AsyncGenerator, Generator
import json
from typing import Any
from unittest.mock import patch
from unittest.mock import AsyncMock, MagicMock, patch
from pysensibo import SensiboClient
from pysensibo.model import SensiboData
from pysensibo import APIV1, APIV2, SensiboClient, SensiboData
import pytest
from homeassistant.components.sensibo.const import DOMAIN, PLATFORMS
from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
@ -21,6 +20,15 @@ from tests.common import MockConfigEntry, load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock]:
"""Override async_setup_entry."""
with patch(
"homeassistant.components.sensibo.async_setup_entry", return_value=True
) as mock_setup_entry:
yield mock_setup_entry
@pytest.fixture(name="load_platforms")
async def patch_platform_constant() -> list[Platform]:
"""Return list of platforms to load."""
@ -30,63 +38,81 @@ async def patch_platform_constant() -> list[Platform]:
@pytest.fixture
async def load_int(
hass: HomeAssistant,
get_data: SensiboData,
mock_client: SensiboClient,
load_platforms: list[Platform],
) -> MockConfigEntry:
"""Set up the Sensibo integration in Home Assistant."""
"""Set up the Sensibo integration."""
config_entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="username",
unique_id="firstnamelastname",
version=2,
)
config_entry.add_to_hass(hass)
with (
patch("homeassistant.components.sensibo.PLATFORMS", load_platforms),
patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
):
with patch("homeassistant.components.sensibo.PLATFORMS", load_platforms):
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
await hass.async_block_till_done()
return config_entry
@pytest.fixture(name="mock_client")
async def get_client(
hass: HomeAssistant,
get_data: tuple[SensiboData, dict[str, Any]],
) -> AsyncGenerator[MagicMock]:
"""Mock SensiboClient."""
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient",
autospec=True,
) as mock_client:
client = mock_client.return_value
client.async_get_devices_data.return_value = get_data[0]
client.async_get_me.return_value = get_data[1]
yield client
@pytest.fixture(name="get_data")
async def get_data_from_library(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, load_json: dict[str, Any]
) -> SensiboData:
"""Retrieve data from upstream Sensibo library."""
client = SensiboClient("123467890", aioclient_mock.create_session(hass.loop))
with patch("pysensibo.SensiboClient.async_get_devices", return_value=load_json):
output = await client.async_get_devices_data()
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
load_json: tuple[dict[str, Any], dict[str, Any]],
) -> AsyncGenerator[tuple[SensiboData, dict[str, Any]]]:
"""Get data from api."""
aioclient_mock.request(
"GET",
url=APIV1 + "/users/me",
params={"apiKey": "1234567890"},
json=load_json[1],
)
aioclient_mock.request(
"GET",
url=APIV2 + "/users/me/pods",
params={"apiKey": "1234567890", "fields": "*"},
json=load_json[0],
)
client = SensiboClient("1234567890", aioclient_mock.create_session(hass.loop))
me = await client.async_get_me()
data = await client.async_get_devices_data()
yield (data, me)
await client._session.close()
return output
@pytest.fixture(name="load_json")
def load_json_from_fixture(load_data: str) -> SensiboData:
def load_json_from_fixture(
load_data: tuple[str, str],
) -> tuple[dict[str, Any], dict[str, Any]]:
"""Load fixture with json data and return."""
json_data: dict[str, Any] = json.loads(load_data)
return json_data
json_data: dict[str, Any] = json.loads(load_data[0])
json_me: dict[str, Any] = json.loads(load_data[1])
return (json_data, json_me)
@pytest.fixture(name="load_data", scope="package")
def load_data_from_fixture() -> str:
def load_data_from_fixture() -> tuple[str, str]:
"""Load fixture with fixture data and return."""
return load_fixture("data.json", "sensibo")
return (load_fixture("data.json", "sensibo"), load_fixture("me.json", "sensibo"))

View File

@ -0,0 +1,13 @@
{
"status": "success",
"result": {
"username": "firstnamelastname",
"email": "first.last@domain.com",
"firstName": "Firstname",
"lastName": "Lastname",
"temperatureUnit": "C",
"appRegistrationSource": "Sensibo",
"organization": null,
"availableOrganizations": []
}
}

View File

@ -0,0 +1,137 @@
# serializer version: 1
# name: test_device
list([
DeviceRegistryEntrySnapshot({
'area_id': 'hallway',
'config_entries': <ANY>,
'configuration_url': 'https://home.sensibo.com/',
'connections': set({
tuple(
'mac',
'00:02:00:b6:00:00',
),
}),
'disabled_by': None,
'entry_type': None,
'hw_version': 'esp8266ex',
'id': <ANY>,
'identifiers': set({
tuple(
'sensibo',
'ABC999111',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'Sensibo',
'model': 'skyv2',
'model_id': None,
'name': 'Hallway',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': '1234567890',
'suggested_area': 'Hallway',
'sw_version': 'SKY30046',
'via_device_id': None,
}),
DeviceRegistryEntrySnapshot({
'area_id': 'kitchen',
'config_entries': <ANY>,
'configuration_url': 'https://home.sensibo.com/',
'connections': set({
tuple(
'mac',
'00:01:00:01:00:01',
),
}),
'disabled_by': None,
'entry_type': None,
'hw_version': 'pure-esp32',
'id': <ANY>,
'identifiers': set({
tuple(
'sensibo',
'AAZZAAZZ',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'Sensibo',
'model': 'pure',
'model_id': None,
'name': 'Kitchen',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': '0987654321',
'suggested_area': 'Kitchen',
'sw_version': 'PUR00111',
'via_device_id': None,
}),
DeviceRegistryEntrySnapshot({
'area_id': 'bedroom',
'config_entries': <ANY>,
'configuration_url': 'https://home.sensibo.com/',
'connections': set({
tuple(
'mac',
'00:03:00:03:00:03',
),
}),
'disabled_by': None,
'entry_type': None,
'hw_version': 'pure-esp32',
'id': <ANY>,
'identifiers': set({
tuple(
'sensibo',
'BBZZBBZZ',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'Sensibo',
'model': 'pure',
'model_id': None,
'name': 'Bedroom',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': '0987654329',
'suggested_area': 'Bedroom',
'sw_version': 'PUR00111',
'via_device_id': None,
}),
DeviceRegistryEntrySnapshot({
'area_id': None,
'config_entries': <ANY>,
'configuration_url': 'https://home.sensibo.com/',
'connections': set({
}),
'disabled_by': None,
'entry_type': None,
'hw_version': 'nrf52',
'id': <ANY>,
'identifiers': set({
tuple(
'sensibo',
'AABBCC',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'Sensibo',
'model': 'motion_sensor',
'model_id': None,
'name': 'Hallway Motion Sensor',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': None,
'suggested_area': None,
'sw_version': 'V17',
'via_device_id': <ANY>,
}),
])
# ---

View File

@ -3,9 +3,11 @@
from __future__ import annotations
from datetime import timedelta
from typing import Any
from unittest.mock import patch
from pysensibo.model import SensiboData
from freezegun.api import FrozenDateTimeFactory
from pysensibo import SensiboData
import pytest
from syrupy.assertion import SnapshotAssertion
@ -13,7 +15,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_OFF, STATE_ON, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, snapshot_platform
@ -27,29 +28,31 @@ async def test_binary_sensor(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
get_data: tuple[SensiboData, dict[str, Any]],
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo binary sensor."""
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
monkeypatch.setattr(
get_data.parsed["ABC999111"].motion_sensors["AABBCC"], "motion", False
get_data[0].parsed["ABC999111"].motion_sensors["AABBCC"], "motion", False
)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("binary_sensor.hallway_motion_sensor_connectivity")
state3 = hass.states.get("binary_sensor.hallway_motion_sensor_motion")
assert state1.state == STATE_ON
assert state3.state == STATE_OFF
assert (
hass.states.get("binary_sensor.hallway_motion_sensor_connectivity").state
== STATE_ON
)
assert (
hass.states.get("binary_sensor.hallway_motion_sensor_motion").state == STATE_OFF
)

View File

@ -2,12 +2,13 @@
from __future__ import annotations
from datetime import datetime, timedelta
from unittest.mock import patch
from datetime import timedelta
from typing import Any
from unittest.mock import MagicMock
from freezegun import freeze_time
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import SensiboData
from pysensibo import SensiboData
import pytest
from syrupy.assertion import SnapshotAssertion
@ -45,14 +46,20 @@ async def test_button(
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@pytest.mark.parametrize(
"load_platforms",
[[Platform.BINARY_SENSOR, Platform.BUTTON, Platform.SENSOR]],
)
async def test_button_update(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo button."""
"""Test the Sensibo button press."""
state_button = hass.states.get("button.hallway_reset_filter")
state_filter_clean = hass.states.get("binary_sensor.hallway_filter_clean_required")
@ -62,48 +69,32 @@ async def test_button_update(
assert state_filter_clean.state is STATE_ON
assert state_filter_last_reset.state == "2022-03-12T15:24:26+00:00"
today = datetime(datetime.now().year + 1, 6, 19, 20, 0, 0).replace(
tzinfo=dt_util.UTC
)
today_str = today.isoformat()
today = dt_util.utcnow() + timedelta(minutes=10)
today = today.replace(microsecond=0)
today_str = today.isoformat(timespec="seconds")
freezer.move_to(today)
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_reset_filter",
return_value={"status": "success"},
),
):
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{
ATTR_ENTITY_ID: state_button.entity_id,
},
blocking=True,
)
await hass.async_block_till_done()
mock_client.async_reset_filter.return_value = {"status": "success"}
monkeypatch.setattr(get_data.parsed["ABC999111"], "filter_clean", False)
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{
ATTR_ENTITY_ID: state_button.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "filter_clean", False)
monkeypatch.setattr(
get_data.parsed["ABC999111"],
get_data[0].parsed["ABC999111"],
"filter_last_reset",
today,
)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state_button = hass.states.get("button.hallway_reset_filter")
state_filter_clean = hass.states.get("binary_sensor.hallway_filter_clean_required")
@ -116,31 +107,22 @@ async def test_button_update(
async def test_button_failure(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
mock_client: MagicMock,
) -> None:
"""Test the Sensibo button fails."""
"""Test the Sensibo button failure."""
state_button = hass.states.get("button.hallway_reset_filter")
state = hass.states.get("button.hallway_reset_filter")
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_reset_filter",
return_value={"status": "failure"},
),
pytest.raises(
HomeAssistantError,
),
mock_client.async_reset_filter.return_value = {"status": "failure"}
with pytest.raises(
HomeAssistantError,
):
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{
ATTR_ENTITY_ID: state_button.entity_id,
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)

File diff suppressed because it is too large Load Diff

View File

@ -3,24 +3,26 @@
from __future__ import annotations
from typing import Any
from unittest.mock import patch
from unittest.mock import AsyncMock, MagicMock, patch
import aiohttp
from pysensibo.exceptions import AuthenticationError, SensiboError
from pysensibo import AuthenticationError, SensiboError
import pytest
from homeassistant import config_entries
from homeassistant.components.sensibo.const import DOMAIN
from homeassistant.const import CONF_API_KEY
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
DOMAIN = "sensibo"
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
async def test_form(hass: HomeAssistant) -> None:
"""Test we get the form."""
async def test_basic_setup(
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_client: MagicMock
) -> None:
"""Test we get and complete the form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -29,32 +31,20 @@ async def test_form(hass: HomeAssistant) -> None:
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
patch(
"homeassistant.components.sensibo.async_setup_entry",
return_value=True,
) as mock_setup_entry,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_API_KEY: "1234567890",
},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_API_KEY: "1234567890",
},
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["version"] == 2
assert result2["data"] == {
"api_key": "1234567890",
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["version"] == 2
assert result["title"] == "firstnamelastname"
assert result["result"].unique_id == "firstnamelastname"
assert result["data"] == {
CONF_API_KEY: "1234567890",
}
assert len(mock_setup_entry.mock_calls) == 1
@ -63,14 +53,12 @@ async def test_form(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
("error_message", "p_error"),
[
(aiohttp.ClientConnectionError, "cannot_connect"),
(TimeoutError, "cannot_connect"),
(AuthenticationError, "invalid_auth"),
(SensiboError, "cannot_connect"),
],
)
async def test_flow_fails(
hass: HomeAssistant, error_message: Exception, p_error: str
hass: HomeAssistant, mock_client: MagicMock, error_message: Exception, p_error: str
) -> None:
"""Test config flow errors."""
@ -85,44 +73,30 @@ async def test_flow_fails(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
side_effect=error_message,
):
result2 = await hass.config_entries.flow.async_configure(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
},
)
assert result2["errors"] == {"base": p_error}
assert result["errors"] == {"base": p_error}
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
patch(
"homeassistant.components.sensibo.async_setup_entry",
return_value=True,
),
):
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567891",
},
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
},
)
assert result3["type"] is FlowResultType.CREATE_ENTRY
assert result3["title"] == "username"
assert result3["data"] == {
"api_key": "1234567891",
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "firstnamelastname"
assert result["data"] == {
CONF_API_KEY: "1234567890",
}
async def test_flow_get_no_devices(hass: HomeAssistant) -> None:
async def test_flow_get_no_devices(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test config flow get no devices from api."""
result = await hass.config_entries.flow.async_init(
@ -132,27 +106,36 @@ async def test_flow_get_no_devices(hass: HomeAssistant) -> None:
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == config_entries.SOURCE_USER
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": []},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {}},
),
with patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": {}},
):
result2 = await hass.config_entries.flow.async_configure(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
},
)
assert result2["errors"] == {"base": "no_devices"}
assert result["errors"] == {"base": "no_devices"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "firstnamelastname"
assert result["data"] == {
CONF_API_KEY: "1234567890",
}
async def test_flow_get_no_username(hass: HomeAssistant) -> None:
async def test_flow_get_no_username(
hass: HomeAssistant, mock_client: MagicMock
) -> None:
"""Test config flow get no username from api."""
result = await hass.config_entries.flow.async_init(
@ -162,15 +145,9 @@ async def test_flow_get_no_username(hass: HomeAssistant) -> None:
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == config_entries.SOURCE_USER
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {}},
),
with patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {}},
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
@ -181,14 +158,27 @@ async def test_flow_get_no_username(hass: HomeAssistant) -> None:
assert result2["errors"] == {"base": "no_username"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
},
)
async def test_reauth_flow(hass: HomeAssistant) -> None:
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "firstnamelastname"
assert result["data"] == {
CONF_API_KEY: "1234567890",
}
async def test_reauth_flow(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test a reauthentication flow."""
entry = MockConfigEntry(
version=2,
domain=DOMAIN,
unique_id="username",
data={"api_key": "1234567890"},
unique_id="firstnamelastname",
data={CONF_API_KEY: "1234567890"},
)
entry.add_to_hass(hass)
@ -197,52 +187,33 @@ async def test_reauth_flow(hass: HomeAssistant) -> None:
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
) as mock_sensibo,
patch(
"homeassistant.components.sensibo.async_setup_entry",
return_value=True,
) as mock_setup_entry,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567891"},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "reauth_successful"
assert entry.data == {"api_key": "1234567891"}
assert len(mock_sensibo.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert entry.data == {CONF_API_KEY: "1234567890"}
@pytest.mark.parametrize(
("sideeffect", "p_error"),
[
(aiohttp.ClientConnectionError, "cannot_connect"),
(TimeoutError, "cannot_connect"),
(AuthenticationError, "invalid_auth"),
(SensiboError, "cannot_connect"),
],
)
async def test_reauth_flow_error(
hass: HomeAssistant, sideeffect: Exception, p_error: str
hass: HomeAssistant, sideeffect: Exception, p_error: str, mock_client: MagicMock
) -> None:
"""Test a reauthentication flow with error."""
entry = MockConfigEntry(
version=2,
domain=DOMAIN,
unique_id="username",
data={"api_key": "1234567890"},
unique_id="firstnamelastname",
data={CONF_API_KEY: "1234567890"},
)
entry.add_to_hass(hass)
@ -252,39 +223,25 @@ async def test_reauth_flow_error(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
side_effect=sideeffect,
):
result2 = await hass.config_entries.flow.async_configure(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result2["step_id"] == "reauth_confirm"
assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": p_error}
assert result["step_id"] == "reauth_confirm"
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": p_error}
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
patch(
"homeassistant.components.sensibo.async_setup_entry",
return_value=True,
),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567891"},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "reauth_successful"
assert entry.data == {"api_key": "1234567891"}
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert entry.data == {CONF_API_KEY: "1234567890"}
@pytest.mark.parametrize(
@ -297,12 +254,12 @@ async def test_reauth_flow_error(
),
(
{"result": []},
{"result": {"username": "username"}},
{"result": {"username": "firstnamelastname"}},
"no_devices",
),
(
{"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
{"result": {"username": "username2"}},
{"result": {"username": "firstnamelastname2"}},
"incorrect_api_key",
),
],
@ -312,13 +269,14 @@ async def test_flow_reauth_no_username_or_device(
get_devices: dict[str, Any],
get_me: dict[str, Any],
p_error: str,
mock_client: MagicMock,
) -> None:
"""Test config flow get no username from api."""
"""Test reauth flow with errors from api."""
entry = MockConfigEntry(
version=2,
domain=DOMAIN,
unique_id="username",
data={"api_key": "1234567890"},
unique_id="firstnamelastname",
data={CONF_API_KEY: "1234567890"},
)
entry.add_to_hass(hass)
@ -337,7 +295,7 @@ async def test_flow_reauth_no_username_or_device(
return_value=get_me,
),
):
result2 = await hass.config_entries.flow.async_configure(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
@ -345,18 +303,28 @@ async def test_flow_reauth_no_username_or_device(
)
await hass.async_block_till_done()
assert result2["step_id"] == "reauth_confirm"
assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": p_error}
assert result["step_id"] == "reauth_confirm"
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": p_error}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert entry.data == {CONF_API_KEY: "1234567890"}
async def test_reconfigure_flow(hass: HomeAssistant) -> None:
async def test_reconfigure_flow(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test a reconfigure flow."""
entry = MockConfigEntry(
version=2,
domain=DOMAIN,
unique_id="username",
data={"api_key": "1234567890"},
unique_id="firstnamelastname",
data={CONF_API_KEY: "1234567890"},
)
entry.add_to_hass(hass)
@ -365,52 +333,33 @@ async def test_reconfigure_flow(hass: HomeAssistant) -> None:
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
) as mock_sensibo,
patch(
"homeassistant.components.sensibo.async_setup_entry",
return_value=True,
) as mock_setup_entry,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567891"},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "reconfigure_successful"
assert entry.data == {"api_key": "1234567891"}
assert len(mock_sensibo.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert entry.data == {CONF_API_KEY: "1234567890"}
@pytest.mark.parametrize(
("sideeffect", "p_error"),
[
(aiohttp.ClientConnectionError, "cannot_connect"),
(TimeoutError, "cannot_connect"),
(AuthenticationError, "invalid_auth"),
(SensiboError, "cannot_connect"),
],
)
async def test_reconfigure_flow_error(
hass: HomeAssistant, sideeffect: Exception, p_error: str
hass: HomeAssistant, sideeffect: Exception, p_error: str, mock_client: MagicMock
) -> None:
"""Test a reconfigure flow with error."""
entry = MockConfigEntry(
version=2,
domain=DOMAIN,
unique_id="username",
data={"api_key": "1234567890"},
unique_id="firstnamelastname",
data={CONF_API_KEY: "1234567890"},
)
entry.add_to_hass(hass)
@ -420,39 +369,25 @@ async def test_reconfigure_flow_error(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
side_effect=sideeffect,
):
result2 = await hass.config_entries.flow.async_configure(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result2["step_id"] == "reconfigure"
assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": p_error}
assert result["step_id"] == "reconfigure"
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": p_error}
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
patch(
"homeassistant.components.sensibo.async_setup_entry",
return_value=True,
),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567891"},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "reconfigure_successful"
assert entry.data == {"api_key": "1234567891"}
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert entry.data == {CONF_API_KEY: "1234567890"}
@pytest.mark.parametrize(
@ -465,12 +400,12 @@ async def test_reconfigure_flow_error(
),
(
{"result": []},
{"result": {"username": "username"}},
{"result": {"username": "firstnamelastname"}},
"no_devices",
),
(
{"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
{"result": {"username": "username2"}},
{"result": {"username": "firstnamelastname2"}},
"incorrect_api_key",
),
],
@ -480,13 +415,14 @@ async def test_flow_reconfigure_no_username_or_device(
get_devices: dict[str, Any],
get_me: dict[str, Any],
p_error: str,
mock_client: MagicMock,
) -> None:
"""Test config flow get no username from api."""
"""Test reconfigure flow with errors from api."""
entry = MockConfigEntry(
version=2,
domain=DOMAIN,
unique_id="username",
data={"api_key": "1234567890"},
unique_id="firstnamelastname",
data={CONF_API_KEY: "1234567890"},
)
entry.add_to_hass(hass)
@ -505,7 +441,7 @@ async def test_flow_reconfigure_no_username_or_device(
return_value=get_me,
),
):
result2 = await hass.config_entries.flow.async_configure(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_API_KEY: "1234567890",
@ -513,6 +449,16 @@ async def test_flow_reconfigure_no_username_or_device(
)
await hass.async_block_till_done()
assert result2["step_id"] == "reconfigure"
assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": p_error}
assert result["step_id"] == "reconfigure"
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": p_error}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_API_KEY: "1234567890"},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert entry.data == {CONF_API_KEY: "1234567890"}

View File

@ -3,17 +3,18 @@
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from typing import Any
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pysensibo.exceptions import AuthenticationError, SensiboError
from pysensibo.model import SensiboData
import pytest
from homeassistant.components.climate import HVACMode
from homeassistant.components.sensibo.const import DOMAIN
from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.util import dt as dt_util
from . import ENTRY_CONFIG
@ -21,75 +22,71 @@ from tests.common import MockConfigEntry, async_fire_time_changed
async def test_coordinator(
hass: HomeAssistant, monkeypatch: pytest.MonkeyPatch, get_data: SensiboData
hass: HomeAssistant,
monkeypatch: pytest.MonkeyPatch,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo coordinator with errors."""
config_entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="username",
unique_id="firstnamelastname",
version=2,
)
config_entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
) as mock_data,
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
):
monkeypatch.setattr(get_data.parsed["ABC999111"], "hvac_mode", "heat")
monkeypatch.setattr(get_data.parsed["ABC999111"], "device_on", True)
mock_data.return_value = get_data
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == "heat"
mock_data.reset_mock()
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "hvac_mode", "heat")
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "device_on", True)
mock_data.side_effect = SensiboError("info")
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=1))
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE
mock_data.reset_mock()
mock_data = mock_client.async_get_devices_data
mock_data.return_value = get_data[0]
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == HVACMode.HEAT
mock_data.reset_mock()
mock_data.return_value = SensiboData(raw={}, parsed={})
mock_data.side_effect = None
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=3))
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE
mock_data.reset_mock()
mock_data.side_effect = SensiboError("info")
freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE
mock_data.reset_mock()
monkeypatch.setattr(get_data.parsed["ABC999111"], "hvac_mode", "heat")
monkeypatch.setattr(get_data.parsed["ABC999111"], "device_on", True)
mock_data.return_value = SensiboData(raw={}, parsed={})
mock_data.side_effect = None
freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE
mock_data.reset_mock()
mock_data.return_value = get_data
mock_data.side_effect = None
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=5))
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == "heat"
mock_data.reset_mock()
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "hvac_mode", "heat")
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "device_on", True)
mock_data.side_effect = AuthenticationError("info")
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=7))
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE
mock_data.return_value = get_data[0]
mock_data.side_effect = None
freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == HVACMode.HEAT
mock_data.reset_mock()
mock_data.side_effect = AuthenticationError("info")
freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done()
mock_data.assert_called_once()
state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE

View File

@ -2,10 +2,10 @@
from __future__ import annotations
from unittest.mock import patch
from unittest.mock import MagicMock
from pysensibo.model import SensiboData
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.climate import (
ATTR_FAN_MODE,
@ -17,35 +17,24 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers import device_registry as dr
async def test_entity(
async def test_device(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
load_int: ConfigEntry,
get_data: SensiboData,
snapshot: SnapshotAssertion,
) -> None:
"""Test the Sensibo climate."""
"""Test the Sensibo device."""
state1 = hass.states.get("climate.hallway")
assert state1
dr_entries = dr.async_entries_for_config_entry(device_registry, load_int.entry_id)
dr_entry: dr.DeviceEntry
for dr_entry in dr_entries:
if dr_entry.name == "Hallway":
assert dr_entry.identifiers == {("sensibo", "ABC999111")}
device_id = dr_entry.id
er_entries = er.async_entries_for_device(
entity_registry, device_id, include_disabled_entities=True
assert (
dr.async_entries_for_config_entry(device_registry, load_int.entry_id)
== snapshot
)
er_entry: er.RegistryEntry
for er_entry in er_entries:
if er_entry.name == "Hallway":
assert er_entry.unique_id == "Hallway"
@pytest.mark.parametrize("p_error", SENSIBO_ERRORS)
@ -53,35 +42,30 @@ async def test_entity_failed_service_calls(
hass: HomeAssistant,
p_error: Exception,
load_int: ConfigEntry,
get_data: SensiboData,
mock_client: MagicMock,
) -> None:
"""Test the Sensibo send command with error."""
state = hass.states.get("climate.hallway")
assert state
with patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
return_value={"result": {"status": "Success"}},
):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: state.entity_id, ATTR_FAN_MODE: "low"},
blocking=True,
)
await hass.async_block_till_done()
mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "Success"}
}
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,
{ATTR_ENTITY_ID: state.entity_id, ATTR_FAN_MODE: "low"},
blocking=True,
)
state = hass.states.get("climate.hallway")
assert state.attributes["fan_mode"] == "low"
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
side_effect=p_error,
),
pytest.raises(HomeAssistantError),
):
mock_client.async_set_ac_state_property.side_effect = p_error
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE,

View File

@ -1,10 +1,8 @@
"""Test for Sensibo component Init."""
"""Test for Sensibo integration setup."""
from __future__ import annotations
from unittest.mock import patch
from pysensibo.model import SensiboData
from unittest.mock import MagicMock, patch
from homeassistant.components.sensibo.const import DOMAIN
from homeassistant.components.sensibo.util import NoUsernameError
@ -19,137 +17,70 @@ from tests.common import MockConfigEntry
from tests.typing import WebSocketGenerator
async def test_setup_entry(hass: HomeAssistant, get_data: SensiboData) -> None:
"""Test setup entry."""
async def test_load_unload_entry(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test setup and unload config entry."""
entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="12",
unique_id="firstnamelastname",
version=2,
)
entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
async def test_migrate_entry(hass: HomeAssistant, get_data: SensiboData) -> None:
assert entry.state is ConfigEntryState.NOT_LOADED
async def test_migrate_entry(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test migrate entry unique id."""
entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="12",
unique_id="someother",
version=1,
)
entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED
assert entry.version == 2
assert entry.unique_id == "username"
assert entry.unique_id == "firstnamelastname"
async def test_migrate_entry_fails(hass: HomeAssistant, get_data: SensiboData) -> None:
"""Test migrate entry unique id."""
async def test_migrate_entry_fails(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test migrate entry fails."""
entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="12",
unique_id="someother",
version=1,
)
entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
side_effect=NoUsernameError("No username returned"),
),
with patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
side_effect=NoUsernameError("No username returned"),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.MIGRATION_ERROR
assert entry.version == 1
assert entry.unique_id == "12"
async def test_unload_entry(hass: HomeAssistant, get_data: SensiboData) -> None:
"""Test unload an entry."""
entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="12",
version="2",
)
entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices",
return_value={"result": [{"id": "xyzxyz"}, {"id": "abcabc"}]},
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_me",
return_value={"result": {"username": "username"}},
),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.NOT_LOADED
assert entry.unique_id == "someother"
async def test_device_remove_devices(

View File

@ -3,8 +3,10 @@
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from typing import Any
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import SensiboData
import pytest
from syrupy.assertion import SnapshotAssertion
@ -19,7 +21,6 @@ from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, snapshot_platform
@ -33,80 +34,55 @@ async def test_number(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
get_data: tuple[SensiboData, dict[str, Any]],
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo number."""
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
monkeypatch.setattr(get_data.parsed["ABC999111"], "calibration_temp", 0.2)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "calibration_temp", 0.2)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("number.hallway_temperature_calibration")
assert state1.state == "0.2"
state = hass.states.get("number.hallway_temperature_calibration")
assert state.state == "0.2"
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_number_set_value(
hass: HomeAssistant,
load_int: ConfigEntry,
get_data: SensiboData,
hass: HomeAssistant, load_int: ConfigEntry, mock_client: MagicMock
) -> None:
"""Test the Sensibo number service."""
state1 = hass.states.get("number.hallway_temperature_calibration")
assert state1.state == "0.1"
state = hass.states.get("number.hallway_temperature_calibration")
assert state.state == "0.1"
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_calibration",
return_value={"status": "failure"},
),
):
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: state1.entity_id, ATTR_VALUE: "0.2"},
blocking=True,
)
await hass.async_block_till_done()
mock_client.async_set_calibration.return_value = {"status": "failure"}
state2 = hass.states.get("number.hallway_temperature_calibration")
assert state2.state == "0.1"
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_calibration",
return_value={"status": "success"},
),
):
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: state1.entity_id, ATTR_VALUE: "0.2"},
{ATTR_ENTITY_ID: state.entity_id, ATTR_VALUE: "0.2"},
blocking=True,
)
await hass.async_block_till_done()
state2 = hass.states.get("number.hallway_temperature_calibration")
assert state2.state == "0.2"
state = hass.states.get("number.hallway_temperature_calibration")
assert state.state == "0.1"
mock_client.async_set_calibration.return_value = {"status": "success"}
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: state.entity_id, ATTR_VALUE: "0.2"},
blocking=True,
)
state = hass.states.get("number.hallway_temperature_calibration")
assert state.state == "0.2"

View File

@ -3,8 +3,10 @@
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from typing import Any
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import SensiboData
import pytest
from syrupy.assertion import SnapshotAssertion
@ -19,7 +21,6 @@ from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, snapshot_platform
@ -32,42 +33,39 @@ async def test_select(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
get_data: tuple[SensiboData, dict[str, Any]],
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo select."""
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
monkeypatch.setattr(
get_data.parsed["ABC999111"], "horizontal_swing_mode", "fixedleft"
get_data[0].parsed["ABC999111"], "horizontal_swing_mode", "fixedleft"
)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("select.hallway_horizontal_swing")
assert state1.state == "fixedleft"
state = hass.states.get("select.hallway_horizontal_swing")
assert state.state == "fixedleft"
async def test_select_set_option(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo select service."""
monkeypatch.setattr(
get_data.parsed["ABC999111"],
get_data[0].parsed["ABC999111"],
"active_features",
[
"timestamp",
@ -78,45 +76,32 @@ async def test_select_set_option(
],
)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("select.hallway_horizontal_swing")
assert state1.state == "stopped"
state = hass.states.get("select.hallway_horizontal_swing")
assert state.state == "stopped"
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
return_value={"result": {"status": "failed"}},
),
pytest.raises(
HomeAssistantError,
),
mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "failed"}
}
with pytest.raises(
HomeAssistantError,
):
await hass.services.async_call(
SELECT_DOMAIN,
SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state1.entity_id, ATTR_OPTION: "fixedleft"},
{ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "fixedleft"},
blocking=True,
)
await hass.async_block_till_done()
state2 = hass.states.get("select.hallway_horizontal_swing")
assert state2.state == "stopped"
state = hass.states.get("select.hallway_horizontal_swing")
assert state.state == "stopped"
monkeypatch.setattr(
get_data.parsed["ABC999111"],
get_data[0].parsed["ABC999111"],
"active_features",
[
"timestamp",
@ -128,58 +113,37 @@ async def test_select_set_option(
],
)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
return_value={
"result": {"status": "Failed", "failureReason": "No connection"}
},
),
pytest.raises(
HomeAssistantError,
),
mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "Failed", "failureReason": "No connection"}
}
with pytest.raises(
HomeAssistantError,
):
await hass.services.async_call(
SELECT_DOMAIN,
SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state1.entity_id, ATTR_OPTION: "fixedleft"},
{ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "fixedleft"},
blocking=True,
)
await hass.async_block_till_done()
state2 = hass.states.get("select.hallway_horizontal_swing")
assert state2.state == "stopped"
state = hass.states.get("select.hallway_horizontal_swing")
assert state.state == "stopped"
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",
return_value={"result": {"status": "Success"}},
),
):
await hass.services.async_call(
SELECT_DOMAIN,
SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state1.entity_id, ATTR_OPTION: "fixedleft"},
blocking=True,
)
await hass.async_block_till_done()
mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "Success"}
}
state2 = hass.states.get("select.hallway_horizontal_swing")
assert state2.state == "fixedleft"
await hass.services.async_call(
SELECT_DOMAIN,
SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "fixedleft"},
blocking=True,
)
state = hass.states.get("select.hallway_horizontal_swing")
assert state.state == "fixedleft"

View File

@ -1,9 +1,9 @@
"""The test for the sensibo select platform."""
"""The test for the sensibo sensor platform."""
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from typing import Any
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import PureAQI, SensiboData
@ -14,7 +14,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, snapshot_platform
@ -28,7 +27,7 @@ async def test_sensor(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
get_data: tuple[SensiboData, dict[str, Any]],
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
freezer: FrozenDateTimeFactory,
@ -37,17 +36,11 @@ async def test_sensor(
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pm25_pure", PureAQI(2))
monkeypatch.setattr(get_data[0].parsed["AAZZAAZZ"], "pm25_pure", PureAQI(2))
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("sensor.kitchen_pure_aqi")
assert state1.state == "moderate"
state = hass.states.get("sensor.kitchen_pure_aqi")
assert state.state == "moderate"

View File

@ -3,8 +3,10 @@
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from typing import Any
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import SensiboData
import pytest
from syrupy.assertion import SnapshotAssertion
@ -22,7 +24,6 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, snapshot_platform
@ -46,220 +47,154 @@ async def test_switch_timer(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo switch."""
"""Test the Sensibo switch timer."""
state1 = hass.states.get("switch.hallway_timer")
assert state1.state == STATE_OFF
assert state1.attributes["id"] is None
assert state1.attributes["turn_on"] is None
state = hass.states.get("switch.hallway_timer")
assert state.state == STATE_OFF
assert state.attributes["id"] is None
assert state.attributes["turn_on"] is None
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_timer",
return_value={"status": "success", "result": {"id": "SzTGE4oZ4D"}},
),
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state1.entity_id,
},
blocking=True,
)
mock_client.async_set_timer.return_value = {
"status": "success",
"result": {"id": "SzTGE4oZ4D"},
}
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "timer_on", True)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "timer_id", "SzTGE4oZ4D")
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "timer_state_on", False)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", True)
monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_id", "SzTGE4oZ4D")
monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_state_on", False)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
state1 = hass.states.get("switch.hallway_timer")
assert state1.state == STATE_ON
assert state1.attributes["id"] == "SzTGE4oZ4D"
assert state1.attributes["turn_on"] is False
state = hass.states.get("switch.hallway_timer")
assert state.state == STATE_ON
assert state.attributes["id"] == "SzTGE4oZ4D"
assert state.attributes["turn_on"] is False
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_del_timer",
return_value={"status": "success", "result": {"id": "SzTGE4oZ4D"}},
),
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state1.entity_id,
},
blocking=True,
)
mock_client.async_del_timer.return_value = {
"status": "success",
"result": {"id": "SzTGE4oZ4D"},
}
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "timer_on", False)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", False)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
state1 = hass.states.get("switch.hallway_timer")
assert state1.state == STATE_OFF
state = hass.states.get("switch.hallway_timer")
assert state.state == STATE_OFF
async def test_switch_pure_boost(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo switch."""
"""Test the Sensibo switch pure boost."""
state1 = hass.states.get("switch.kitchen_pure_boost")
assert state1.state == STATE_OFF
state = hass.states.get("switch.kitchen_pure_boost")
assert state.state == STATE_OFF
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_pureboost",
return_value={"status": "success"},
),
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state1.entity_id,
},
blocking=True,
)
mock_client.async_set_pureboost.return_value = {"status": "success"}
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["AAZZAAZZ"], "pure_boost_enabled", True)
monkeypatch.setattr(
get_data[0].parsed["AAZZAAZZ"], "pure_measure_integration", None
)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_boost_enabled", True)
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_measure_integration", None)
state = hass.states.get("switch.kitchen_pure_boost")
assert state.state == STATE_ON
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
state1 = hass.states.get("switch.kitchen_pure_boost")
assert state1.state == STATE_ON
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_pureboost",
return_value={"status": "success"},
),
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state1.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["AAZZAAZZ"], "pure_boost_enabled", False)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_boost_enabled", False)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
state1 = hass.states.get("switch.kitchen_pure_boost")
assert state1.state == STATE_OFF
state = hass.states.get("switch.kitchen_pure_boost")
assert state.state == STATE_OFF
async def test_switch_command_failure(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
hass: HomeAssistant, load_int: ConfigEntry, mock_client: MagicMock
) -> None:
"""Test the Sensibo switch fails commands."""
state1 = hass.states.get("switch.hallway_timer")
state = hass.states.get("switch.hallway_timer")
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_timer",
return_value={"status": "failure"},
),
pytest.raises(
HomeAssistantError,
),
mock_client.async_set_timer.return_value = {"status": "failure"}
with pytest.raises(
HomeAssistantError,
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state1.entity_id,
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_del_timer",
return_value={"status": "failure"},
),
pytest.raises(
HomeAssistantError,
),
mock_client.async_del_timer.return_value = {"status": "failure"}
with pytest.raises(
HomeAssistantError,
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state1.entity_id,
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
@ -269,113 +204,78 @@ async def test_switch_climate_react(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo switch for climate react."""
state1 = hass.states.get("switch.hallway_climate_react")
assert state1.state == STATE_OFF
state = hass.states.get("switch.hallway_climate_react")
assert state.state == STATE_OFF
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_enable_climate_react",
return_value={"status": "success"},
),
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state1.entity_id,
},
blocking=True,
)
mock_client.async_enable_climate_react.return_value = {"status": "success"}
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "smart_on", True)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["ABC999111"], "smart_on", True)
state = hass.states.get("switch.hallway_climate_react")
assert state.state == STATE_ON
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
state1 = hass.states.get("switch.hallway_climate_react")
assert state1.state == STATE_ON
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
with (
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
),
patch(
"homeassistant.components.sensibo.util.SensiboClient.async_enable_climate_react",
return_value={"status": "success"},
),
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: state1.entity_id,
},
blocking=True,
)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "smart_on", False)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["ABC999111"], "smart_on", False)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
state1 = hass.states.get("switch.hallway_climate_react")
assert state1.state == STATE_OFF
state = hass.states.get("switch.hallway_climate_react")
assert state.state == STATE_OFF
async def test_switch_climate_react_no_data(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
get_data: tuple[SensiboData, dict[str, Any]],
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo switch for climate react."""
"""Test the Sensibo switch for climate react with no data."""
monkeypatch.setattr(get_data.parsed["ABC999111"], "smart_type", None)
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "smart_type", None)
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
async_fire_time_changed(
hass,
dt_util.utcnow() + timedelta(minutes=5),
)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("switch.hallway_climate_react")
assert state1.state == STATE_OFF
state = hass.states.get("switch.hallway_climate_react")
assert state.state == STATE_OFF
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: state1.entity_id,
ATTR_ENTITY_ID: state.entity_id,
},
blocking=True,
)
await hass.async_block_till_done()

View File

@ -3,7 +3,7 @@
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from typing import Any
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import SensiboData
@ -27,7 +27,7 @@ async def test_update(
hass: HomeAssistant,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
get_data: tuple[SensiboData, dict[str, Any]],
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
freezer: FrozenDateTimeFactory,
@ -36,15 +36,11 @@ async def test_update(
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
monkeypatch.setattr(get_data.parsed["ABC999111"], "fw_ver", "SKY30048")
monkeypatch.setattr(get_data[0].parsed["ABC999111"], "fw_ver", "SKY30048")
with patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data",
return_value=get_data,
):
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state1 = hass.states.get("update.hallway_firmware")
assert state1.state == STATE_OFF
state = hass.states.get("update.hallway_firmware")
assert state.state == STATE_OFF