Add 100% test coverage to Ambee integration (#51670)

* Add 100% test coverage to Ambee integration

* Add tests for device and entity registry
This commit is contained in:
Franck Nijhof 2021-06-09 20:23:16 +02:00 committed by GitHub
parent 332c86ff8c
commit e5c6ac5ba8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 254 additions and 2 deletions

View File

@ -45,8 +45,6 @@ omit =
homeassistant/components/alarmdecoder/sensor.py
homeassistant/components/alpha_vantage/sensor.py
homeassistant/components/amazon_polly/*
homeassistant/components/ambee/__init__.py
homeassistant/components/ambee/sensor.py
homeassistant/components/ambiclimate/climate.py
homeassistant/components/ambient_station/*
homeassistant/components/amcrest/*

View File

@ -0,0 +1,50 @@
"""Fixtures for Ambee integration tests."""
import json
from unittest.mock import AsyncMock, MagicMock, patch
from ambee import AirQuality
import pytest
from homeassistant.components.ambee.const import DOMAIN
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Return the default mocked config entry."""
return MockConfigEntry(
title="Home Sweet Home",
domain=DOMAIN,
data={CONF_LATITUDE: 52.42, CONF_LONGITUDE: 4.44, CONF_API_KEY: "example"},
unique_id="unique_thingy",
)
@pytest.fixture
def mock_ambee(aioclient_mock: AiohttpClientMocker):
"""Return a mocked Ambee client."""
with patch("homeassistant.components.ambee.Ambee") as ambee_mock:
client = ambee_mock.return_value
client.air_quality = AsyncMock(
return_value=AirQuality.from_dict(
json.loads(load_fixture("ambee/air_quality.json"))
)
)
yield ambee_mock
@pytest.fixture
async def init_integration(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_ambee: MagicMock
) -> MockConfigEntry:
"""Set up the Ambee integration for testing."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
return mock_config_entry

View File

@ -0,0 +1,46 @@
"""Tests for the Ambee integration."""
from unittest.mock import AsyncMock, MagicMock, patch
from ambee import AmbeeConnectionError
from homeassistant.components.ambee.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def test_load_unload_config_entry(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ambee: AsyncMock,
) -> None:
"""Test the Ambee configuration entry loading/unloading."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.LOADED
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert not hass.data.get(DOMAIN)
@patch(
"homeassistant.components.ambee.Ambee.air_quality",
side_effect=AmbeeConnectionError,
)
async def test_config_entry_not_ready(
mock_air_quality: MagicMock,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the Ambee configuration entry not ready."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_air_quality.call_count == 1
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY

View File

@ -0,0 +1,130 @@
"""Tests for the sensors provided by the Ambee integration."""
from homeassistant.components.ambee.const import DOMAIN
from homeassistant.components.sensor import ATTR_STATE_CLASS, STATE_CLASS_MEASUREMENT
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_FRIENDLY_NAME,
ATTR_UNIT_OF_MEASUREMENT,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
DEVICE_CLASS_CO,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from tests.common import MockConfigEntry
async def test_air_quality(
hass: HomeAssistant,
init_integration: MockConfigEntry,
) -> None:
"""Test the Ambee Air Quality sensors."""
entry_id = init_integration.entry_id
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
state = hass.states.get("sensor.particulate_matter_2_5_mm")
entry = entity_registry.async_get("sensor.particulate_matter_2_5_mm")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_particulate_matter_2_5"
assert state.state == "3.14"
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Particulate Matter < 2.5 μm"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
)
assert ATTR_DEVICE_CLASS not in state.attributes
state = hass.states.get("sensor.particulate_matter_10_mm")
entry = entity_registry.async_get("sensor.particulate_matter_10_mm")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_particulate_matter_10"
assert state.state == "5.24"
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Particulate Matter < 10 μm"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
)
assert ATTR_DEVICE_CLASS not in state.attributes
state = hass.states.get("sensor.sulphur_dioxide_so2")
entry = entity_registry.async_get("sensor.sulphur_dioxide_so2")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_sulphur_dioxide"
assert state.state == "0.031"
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Sulphur Dioxide (SO2)"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_PARTS_PER_BILLION
)
assert ATTR_DEVICE_CLASS not in state.attributes
state = hass.states.get("sensor.nitrogen_dioxide_no2")
entry = entity_registry.async_get("sensor.nitrogen_dioxide_no2")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_nitrogen_dioxide"
assert state.state == "0.66"
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Nitrogen Dioxide (NO2)"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_PARTS_PER_BILLION
)
assert ATTR_DEVICE_CLASS not in state.attributes
state = hass.states.get("sensor.ozone")
entry = entity_registry.async_get("sensor.ozone")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_ozone"
assert state.state == "17.067"
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Ozone"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_PARTS_PER_BILLION
)
assert ATTR_DEVICE_CLASS not in state.attributes
state = hass.states.get("sensor.carbon_monoxide_co")
entry = entity_registry.async_get("sensor.carbon_monoxide_co")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_carbon_monoxide"
assert state.state == "0.105"
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_CO
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Carbon Monoxide (CO)"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_PARTS_PER_MILLION
)
state = hass.states.get("sensor.air_quality_index_aqi")
entry = entity_registry.async_get("sensor.air_quality_index_aqi")
assert entry
assert state
assert entry.unique_id == f"{entry_id}_air_quality_index"
assert state.state == "13"
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Air Quality Index (AQI)"
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert ATTR_DEVICE_CLASS not in state.attributes
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert entry.device_id
device_entry = device_registry.async_get(entry.device_id)
assert device_entry
assert device_entry.identifiers == {(DOMAIN, f"{entry_id}_air_quality")}
assert device_entry.manufacturer == "Ambee"
assert device_entry.name == "Air Quality"
assert not device_entry.model
assert not device_entry.sw_version

28
tests/fixtures/ambee/air_quality.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
"message": "success",
"stations": [
{
"CO": 0.105,
"NO2": 0.66,
"OZONE": 17.067,
"PM10": 5.24,
"PM25": 3.14,
"SO2": 0.031,
"city": "Hellendoorn",
"countryCode": "NL",
"division": "",
"lat": 52.3981,
"lng": 6.4493,
"placeName": "Hellendoorn",
"postalCode": "7447",
"state": "Overijssel",
"updatedAt": "2021-05-29T14:00:00.000Z",
"AQI": 13,
"aqiInfo": {
"pollutant": "PM2.5",
"concentration": 3.14,
"category": "Good"
}
}
]
}