mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Rewrite dyson air quality tests (#45466)
This commit is contained in:
parent
0e068a5f39
commit
59b0a4d060
@ -74,37 +74,24 @@ class DysonAirSensor(DysonEntity, AirQualityEntity):
|
|||||||
@property
|
@property
|
||||||
def particulate_matter_2_5(self):
|
def particulate_matter_2_5(self):
|
||||||
"""Return the particulate matter 2.5 level."""
|
"""Return the particulate matter 2.5 level."""
|
||||||
if self._device.environmental_state:
|
|
||||||
return int(self._device.environmental_state.particulate_matter_25)
|
return int(self._device.environmental_state.particulate_matter_25)
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def particulate_matter_10(self):
|
def particulate_matter_10(self):
|
||||||
"""Return the particulate matter 10 level."""
|
"""Return the particulate matter 10 level."""
|
||||||
if self._device.environmental_state:
|
|
||||||
return int(self._device.environmental_state.particulate_matter_10)
|
return int(self._device.environmental_state.particulate_matter_10)
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nitrogen_dioxide(self):
|
def nitrogen_dioxide(self):
|
||||||
"""Return the NO2 (nitrogen dioxide) level."""
|
"""Return the NO2 (nitrogen dioxide) level."""
|
||||||
if self._device.environmental_state:
|
|
||||||
return int(self._device.environmental_state.nitrogen_dioxide)
|
return int(self._device.environmental_state.nitrogen_dioxide)
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def volatile_organic_compounds(self):
|
def volatile_organic_compounds(self):
|
||||||
"""Return the VOC (Volatile Organic Compounds) level."""
|
"""Return the VOC (Volatile Organic Compounds) level."""
|
||||||
if self._device.environmental_state:
|
|
||||||
return int(self._device.environmental_state.volatile_organic_compounds)
|
return int(self._device.environmental_state.volatile_organic_compounds)
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the device state attributes."""
|
"""Return the device state attributes."""
|
||||||
data = {}
|
return {ATTR_VOC: self.volatile_organic_compounds}
|
||||||
|
|
||||||
voc = self.volatile_organic_compounds
|
|
||||||
if voc is not None:
|
|
||||||
data[ATTR_VOC] = voc
|
|
||||||
return data
|
|
||||||
|
@ -1,159 +1,67 @@
|
|||||||
"""Test the Dyson air quality component."""
|
"""Test the Dyson air quality component."""
|
||||||
import json
|
|
||||||
from unittest import mock
|
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from libpurecool.dyson_pure_cool import DysonPureCool
|
from libpurecool.dyson_pure_cool import DysonPureCool
|
||||||
from libpurecool.dyson_pure_state_v2 import DysonEnvironmentalSensorV2State
|
from libpurecool.dyson_pure_state_v2 import DysonEnvironmentalSensorV2State
|
||||||
|
|
||||||
from homeassistant.components import dyson as dyson_parent
|
|
||||||
from homeassistant.components.air_quality import (
|
from homeassistant.components.air_quality import (
|
||||||
|
ATTR_AQI,
|
||||||
ATTR_NO2,
|
ATTR_NO2,
|
||||||
ATTR_PM_2_5,
|
ATTR_PM_2_5,
|
||||||
ATTR_PM_10,
|
ATTR_PM_10,
|
||||||
DOMAIN as AIQ_DOMAIN,
|
DOMAIN as PLATFORM_DOMAIN,
|
||||||
)
|
)
|
||||||
import homeassistant.components.dyson.air_quality as dyson
|
from homeassistant.components.dyson.air_quality import ATTR_VOC
|
||||||
from homeassistant.helpers import discovery
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.setup import async_setup_component
|
|
||||||
|
|
||||||
from .common import load_mock_device
|
from .common import ENTITY_NAME, async_get_purecool_device, async_update_device
|
||||||
|
|
||||||
|
ENTITY_ID = f"{PLATFORM_DOMAIN}.{ENTITY_NAME}"
|
||||||
|
|
||||||
|
MOCKED_VALUES = {
|
||||||
|
ATTR_PM_2_5: 10,
|
||||||
|
ATTR_PM_10: 20,
|
||||||
|
ATTR_NO2: 30,
|
||||||
|
ATTR_VOC: 40,
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCKED_UPDATED_VALUES = {
|
||||||
|
ATTR_PM_2_5: 60,
|
||||||
|
ATTR_PM_10: 50,
|
||||||
|
ATTR_NO2: 40,
|
||||||
|
ATTR_VOC: 30,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _get_dyson_purecool_device():
|
def _async_assign_values(device: DysonPureCool, values=MOCKED_VALUES) -> None:
|
||||||
"""Return a valid device as provided by the Dyson web services."""
|
"""Assign mocked environmental states to the device."""
|
||||||
device = mock.Mock(spec=DysonPureCool)
|
device.environmental_state.particulate_matter_25 = values[ATTR_PM_2_5]
|
||||||
load_mock_device(device)
|
device.environmental_state.particulate_matter_10 = values[ATTR_PM_10]
|
||||||
device.name = "Living room"
|
device.environmental_state.nitrogen_dioxide = values[ATTR_NO2]
|
||||||
device.environmental_state.particulate_matter_25 = "0014"
|
device.environmental_state.volatile_organic_compounds = values[ATTR_VOC]
|
||||||
device.environmental_state.particulate_matter_10 = "0025"
|
|
||||||
device.environmental_state.nitrogen_dioxide = "0042"
|
|
||||||
device.environmental_state.volatile_organic_compounds = "0035"
|
@callback
|
||||||
|
def async_get_device() -> DysonPureCool:
|
||||||
|
"""Return a device of the given type."""
|
||||||
|
device = async_get_purecool_device()
|
||||||
|
_async_assign_values(device)
|
||||||
return device
|
return device
|
||||||
|
|
||||||
|
|
||||||
def _get_config():
|
async def test_air_quality(hass: HomeAssistant, device: DysonPureCool) -> None:
|
||||||
"""Return a config dictionary."""
|
"""Test the state and attributes of the air quality entity."""
|
||||||
return {
|
state = hass.states.get(ENTITY_ID)
|
||||||
dyson_parent.DOMAIN: {
|
assert state.state == str(MOCKED_VALUES[ATTR_PM_2_5])
|
||||||
dyson_parent.CONF_USERNAME: "email",
|
attributes = state.attributes
|
||||||
dyson_parent.CONF_PASSWORD: "password",
|
for attr, value in MOCKED_VALUES.items():
|
||||||
dyson_parent.CONF_LANGUAGE: "GB",
|
assert attributes[attr] == value
|
||||||
dyson_parent.CONF_DEVICES: [
|
assert attributes[ATTR_AQI] == 40
|
||||||
{"device_id": "XX-XXXXX-XX", "device_ip": "192.168.0.1"}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_async_assign_values(device, MOCKED_UPDATED_VALUES)
|
||||||
@patch("libpurecool.dyson.DysonAccount.login", return_value=True)
|
await async_update_device(hass, device, DysonEnvironmentalSensorV2State)
|
||||||
@patch(
|
state = hass.states.get(ENTITY_ID)
|
||||||
"libpurecool.dyson.DysonAccount.devices",
|
assert state.state == str(MOCKED_UPDATED_VALUES[ATTR_PM_2_5])
|
||||||
return_value=[_get_dyson_purecool_device()],
|
attributes = state.attributes
|
||||||
)
|
for attr, value in MOCKED_UPDATED_VALUES.items():
|
||||||
async def test_purecool_aiq_attributes(devices, login, hass):
|
assert attributes[attr] == value
|
||||||
"""Test state attributes."""
|
assert attributes[ATTR_AQI] == 60
|
||||||
await async_setup_component(hass, dyson_parent.DOMAIN, _get_config())
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
fan_state = hass.states.get("air_quality.living_room")
|
|
||||||
attributes = fan_state.attributes
|
|
||||||
|
|
||||||
assert fan_state.state == "14"
|
|
||||||
assert attributes[ATTR_PM_2_5] == 14
|
|
||||||
assert attributes[ATTR_PM_10] == 25
|
|
||||||
assert attributes[ATTR_NO2] == 42
|
|
||||||
assert attributes[dyson.ATTR_VOC] == 35
|
|
||||||
|
|
||||||
|
|
||||||
@patch("libpurecool.dyson.DysonAccount.login", return_value=True)
|
|
||||||
@patch(
|
|
||||||
"libpurecool.dyson.DysonAccount.devices",
|
|
||||||
return_value=[_get_dyson_purecool_device()],
|
|
||||||
)
|
|
||||||
async def test_purecool_aiq_update_state(devices, login, hass):
|
|
||||||
"""Test state update."""
|
|
||||||
device = devices.return_value[0]
|
|
||||||
await async_setup_component(hass, dyson_parent.DOMAIN, _get_config())
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
event = {
|
|
||||||
"msg": "ENVIRONMENTAL-CURRENT-SENSOR-DATA",
|
|
||||||
"time": "2019-03-29T10:00:01.000Z",
|
|
||||||
"data": {
|
|
||||||
"pm10": "0080",
|
|
||||||
"p10r": "0151",
|
|
||||||
"hact": "0040",
|
|
||||||
"va10": "0055",
|
|
||||||
"p25r": "0161",
|
|
||||||
"noxl": "0069",
|
|
||||||
"pm25": "0035",
|
|
||||||
"sltm": "OFF",
|
|
||||||
"tact": "2960",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
device.environmental_state = DysonEnvironmentalSensorV2State(json.dumps(event))
|
|
||||||
|
|
||||||
for call in device.add_message_listener.call_args_list:
|
|
||||||
callback = call[0][0]
|
|
||||||
if type(callback.__self__) == dyson.DysonAirSensor:
|
|
||||||
callback(device.environmental_state)
|
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
fan_state = hass.states.get("air_quality.living_room")
|
|
||||||
attributes = fan_state.attributes
|
|
||||||
|
|
||||||
assert fan_state.state == "35"
|
|
||||||
assert attributes[ATTR_PM_2_5] == 35
|
|
||||||
assert attributes[ATTR_PM_10] == 80
|
|
||||||
assert attributes[ATTR_NO2] == 69
|
|
||||||
assert attributes[dyson.ATTR_VOC] == 55
|
|
||||||
|
|
||||||
|
|
||||||
@patch("libpurecool.dyson.DysonAccount.login", return_value=True)
|
|
||||||
@patch(
|
|
||||||
"libpurecool.dyson.DysonAccount.devices",
|
|
||||||
return_value=[_get_dyson_purecool_device()],
|
|
||||||
)
|
|
||||||
async def test_purecool_component_setup_only_once(devices, login, hass):
|
|
||||||
"""Test if entities are created only once."""
|
|
||||||
config = _get_config()
|
|
||||||
await async_setup_component(hass, dyson_parent.DOMAIN, config)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
discovery.load_platform(hass, AIQ_DOMAIN, dyson_parent.DOMAIN, {}, config)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert len(hass.data[dyson.DYSON_AIQ_DEVICES]) == 1
|
|
||||||
|
|
||||||
|
|
||||||
@patch("libpurecool.dyson.DysonAccount.login", return_value=True)
|
|
||||||
@patch(
|
|
||||||
"libpurecool.dyson.DysonAccount.devices",
|
|
||||||
return_value=[_get_dyson_purecool_device()],
|
|
||||||
)
|
|
||||||
async def test_purecool_aiq_without_discovery(devices, login, hass):
|
|
||||||
"""Test if component correctly returns if discovery not set."""
|
|
||||||
await async_setup_component(hass, dyson_parent.DOMAIN, _get_config())
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
add_entities_mock = mock.MagicMock()
|
|
||||||
|
|
||||||
dyson.setup_platform(hass, None, add_entities_mock, None)
|
|
||||||
|
|
||||||
assert add_entities_mock.call_count == 0
|
|
||||||
|
|
||||||
|
|
||||||
@patch("libpurecool.dyson.DysonAccount.login", return_value=True)
|
|
||||||
@patch(
|
|
||||||
"libpurecool.dyson.DysonAccount.devices",
|
|
||||||
return_value=[_get_dyson_purecool_device()],
|
|
||||||
)
|
|
||||||
async def test_purecool_aiq_empty_environment_state(devices, login, hass):
|
|
||||||
"""Test device with empty environmental state."""
|
|
||||||
await async_setup_component(hass, dyson_parent.DOMAIN, _get_config())
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
device = hass.data[dyson.DYSON_AIQ_DEVICES][0]
|
|
||||||
device._device.environmental_state = None
|
|
||||||
|
|
||||||
assert device.state is None
|
|
||||||
assert device.particulate_matter_2_5 is None
|
|
||||||
assert device.particulate_matter_10 is None
|
|
||||||
assert device.nitrogen_dioxide is None
|
|
||||||
assert device.volatile_organic_compounds is None
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user