Improve tests for GIOS integration (#39514)

This commit is contained in:
Maciej Bieniek 2020-09-03 09:27:21 +02:00 committed by GitHub
parent d66bc6a873
commit 226406b853
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 406 additions and 30 deletions

View File

@ -306,8 +306,6 @@ omit =
homeassistant/components/gc100/*
homeassistant/components/geniushub/*
homeassistant/components/geizhals/sensor.py
homeassistant/components/gios/__init__.py
homeassistant/components/gios/air_quality.py
homeassistant/components/github/sensor.py
homeassistant/components/gitlab_ci/sensor.py
homeassistant/components/gitter/sensor.py

View File

@ -24,6 +24,8 @@ SENSOR_MAP = {
"SO2": ATTR_SO2,
}
PARALLEL_UPDATES = 1
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Add a GIOS entities from a config_entry."""

View File

@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/gios",
"codeowners": ["@bieniu"],
"requirements": ["gios==0.1.3"],
"config_flow": true
"config_flow": true,
"quality_scale": "platinum"
}

View File

@ -1 +1,47 @@
"""Tests for GIOS."""
import json
from homeassistant.components.gios.const import DOMAIN
from tests.async_mock import patch
from tests.common import MockConfigEntry, load_fixture
STATIONS = [
{"id": 123, "stationName": "Test Name 1", "gegrLat": "99.99", "gegrLon": "88.88"},
{"id": 321, "stationName": "Test Name 2", "gegrLat": "77.77", "gegrLon": "66.66"},
]
async def init_integration(hass, incomplete_data=False) -> MockConfigEntry:
"""Set up the GIOS integration in Home Assistant."""
entry = MockConfigEntry(
domain=DOMAIN,
title="Home",
unique_id=123,
data={"station_id": 123, "name": "Home"},
)
indexes = json.loads(load_fixture("gios/indexes.json"))
station = json.loads(load_fixture("gios/station.json"))
sensors = json.loads(load_fixture("gios/sensors.json"))
if incomplete_data:
indexes["stIndexLevel"]["indexLevelName"] = "foo"
sensors["PM10"]["values"][0]["value"] = None
sensors["PM10"]["values"][1]["value"] = None
with patch(
"homeassistant.components.gios.Gios._get_stations", return_value=STATIONS
), patch(
"homeassistant.components.gios.Gios._get_station",
return_value=station,
), patch(
"homeassistant.components.gios.Gios._get_all_sensors",
return_value=sensors,
), patch(
"homeassistant.components.gios.Gios._get_indexes", return_value=indexes
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return entry

View File

@ -0,0 +1,123 @@
"""Test air_quality of GIOS integration."""
from datetime import timedelta
import json
from gios import ApiError
from homeassistant.components.air_quality import (
ATTR_AQI,
ATTR_CO,
ATTR_NO2,
ATTR_OZONE,
ATTR_PM_2_5,
ATTR_PM_10,
ATTR_SO2,
)
from homeassistant.components.gios.air_quality import ATTRIBUTION
from homeassistant.components.gios.const import AQI_GOOD
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_ICON,
ATTR_UNIT_OF_MEASUREMENT,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
STATE_UNAVAILABLE,
)
from homeassistant.util.dt import utcnow
from tests.async_mock import patch
from tests.common import async_fire_time_changed, load_fixture
from tests.components.gios import init_integration
async def test_air_quality(hass):
"""Test states of the air_quality."""
await init_integration(hass)
registry = await hass.helpers.entity_registry.async_get_registry()
state = hass.states.get("air_quality.home")
assert state
assert state.state == "4"
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_AQI) == AQI_GOOD
assert state.attributes.get(ATTR_PM_10) == 17
assert state.attributes.get(ATTR_PM_2_5) == 4
assert state.attributes.get(ATTR_CO) == 252
assert state.attributes.get(ATTR_SO2) == 4
assert state.attributes.get(ATTR_NO2) == 7
assert state.attributes.get(ATTR_OZONE) == 96
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
)
assert state.attributes.get(ATTR_ICON) == "mdi:emoticon-happy"
assert state.attributes.get("station") == "Test Name 1"
entry = registry.async_get("air_quality.home")
assert entry
assert entry.unique_id == 123
async def test_air_quality_with_incomplete_data(hass):
"""Test states of the air_quality with incomplete data from measuring station."""
await init_integration(hass, incomplete_data=True)
registry = await hass.helpers.entity_registry.async_get_registry()
state = hass.states.get("air_quality.home")
assert state
assert state.state == "4"
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
assert state.attributes.get(ATTR_AQI) == "foo"
assert state.attributes.get(ATTR_PM_10) is None
assert state.attributes.get(ATTR_PM_2_5) == 4
assert state.attributes.get(ATTR_CO) == 252
assert state.attributes.get(ATTR_SO2) == 4
assert state.attributes.get(ATTR_NO2) == 7
assert state.attributes.get(ATTR_OZONE) == 96
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
)
assert state.attributes.get(ATTR_ICON) == "mdi:blur"
assert state.attributes.get("station") == "Test Name 1"
entry = registry.async_get("air_quality.home")
assert entry
assert entry.unique_id == 123
async def test_availability(hass):
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
await init_integration(hass)
state = hass.states.get("air_quality.home")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "4"
future = utcnow() + timedelta(minutes=60)
with patch(
"homeassistant.components.gios.Gios._get_all_sensors",
side_effect=ApiError("Unexpected error"),
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
state = hass.states.get("air_quality.home")
assert state
assert state.state == STATE_UNAVAILABLE
future = utcnow() + timedelta(minutes=120)
with patch(
"homeassistant.components.gios.Gios._get_all_sensors",
return_value=json.loads(load_fixture("gios/sensors.json")),
), patch(
"homeassistant.components.gios.Gios._get_indexes",
return_value=json.loads(load_fixture("gios/indexes.json")),
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
state = hass.states.get("air_quality.home")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "4"

View File

@ -1,4 +1,6 @@
"""Define tests for the GIOS config flow."""
import json
from gios import ApiError
from homeassistant import data_entry_flow
@ -7,28 +9,14 @@ from homeassistant.components.gios.const import CONF_STATION_ID
from homeassistant.const import CONF_NAME
from tests.async_mock import patch
from tests.common import load_fixture
from tests.components.gios import STATIONS
CONFIG = {
CONF_NAME: "Foo",
CONF_STATION_ID: 123,
}
VALID_STATIONS = [
{"id": 123, "stationName": "Test Name 1", "gegrLat": "99.99", "gegrLon": "88.88"},
{"id": 321, "stationName": "Test Name 2", "gegrLat": "77.77", "gegrLon": "66.66"},
]
VALID_STATION = [
{"id": 3764, "param": {"paramName": "particulate matter PM10", "paramCode": "PM10"}}
]
VALID_INDEXES = {
"stIndexLevel": {"id": 1, "indexLevelName": "Good"},
"pm10IndexLevel": {"id": 0, "indexLevelName": "Very good"},
}
VALID_SENSOR = {"key": "PM10", "values": [{"value": 11.11}]}
async def test_show_form(hass):
"""Test that the form is served with no input."""
@ -43,7 +31,9 @@ async def test_show_form(hass):
async def test_invalid_station_id(hass):
"""Test that errors are shown when measuring station ID is invalid."""
with patch("gios.Gios._get_stations", return_value=VALID_STATIONS):
with patch(
"homeassistant.components.gios.Gios._get_stations", return_value=STATIONS
):
flow = config_flow.GiosFlowHandler()
flow.hass = hass
flow.context = {}
@ -57,10 +47,13 @@ async def test_invalid_station_id(hass):
async def test_invalid_sensor_data(hass):
"""Test that errors are shown when sensor data is invalid."""
with patch("gios.Gios._get_stations", return_value=VALID_STATIONS), patch(
"gios.Gios._get_station", return_value=VALID_STATION
), patch("gios.Gios._get_station", return_value=VALID_STATION), patch(
"gios.Gios._get_sensor", return_value={}
with patch(
"homeassistant.components.gios.Gios._get_stations", return_value=STATIONS
), patch(
"homeassistant.components.gios.Gios._get_station",
return_value=json.loads(load_fixture("gios/station.json")),
), patch(
"homeassistant.components.gios.Gios._get_sensor", return_value={}
):
flow = config_flow.GiosFlowHandler()
flow.hass = hass
@ -73,7 +66,9 @@ async def test_invalid_sensor_data(hass):
async def test_cannot_connect(hass):
"""Test that errors are shown when cannot connect to GIOS server."""
with patch("gios.Gios._async_get", side_effect=ApiError("error")):
with patch(
"homeassistant.components.gios.Gios._async_get", side_effect=ApiError("error")
):
flow = config_flow.GiosFlowHandler()
flow.hass = hass
flow.context = {}
@ -85,12 +80,17 @@ async def test_cannot_connect(hass):
async def test_create_entry(hass):
"""Test that the user step works."""
with patch("gios.Gios._get_stations", return_value=VALID_STATIONS), patch(
"gios.Gios._get_station", return_value=VALID_STATION
), patch("gios.Gios._get_station", return_value=VALID_STATION), patch(
"gios.Gios._get_sensor", return_value=VALID_SENSOR
with patch(
"homeassistant.components.gios.Gios._get_stations", return_value=STATIONS
), patch(
"gios.Gios._get_indexes", return_value=VALID_INDEXES
"homeassistant.components.gios.Gios._get_station",
return_value=json.loads(load_fixture("gios/station.json")),
), patch(
"homeassistant.components.gios.Gios._get_all_sensors",
return_value=json.loads(load_fixture("gios/sensors.json")),
), patch(
"homeassistant.components.gios.Gios._get_indexes",
return_value=json.loads(load_fixture("gios/indexes.json")),
):
flow = config_flow.GiosFlowHandler()
flow.hass = hass

View File

@ -0,0 +1,54 @@
"""Test init of GIOS integration."""
from homeassistant.components.gios.const import DOMAIN
from homeassistant.config_entries import (
ENTRY_STATE_LOADED,
ENTRY_STATE_NOT_LOADED,
ENTRY_STATE_SETUP_RETRY,
)
from homeassistant.const import STATE_UNAVAILABLE
from tests.async_mock import patch
from tests.common import MockConfigEntry
from tests.components.gios import init_integration
async def test_async_setup_entry(hass):
"""Test a successful setup entry."""
await init_integration(hass)
state = hass.states.get("air_quality.home")
assert state is not None
assert state.state != STATE_UNAVAILABLE
assert state.state == "4"
async def test_config_not_ready(hass):
"""Test for setup failure if connection to GIOS is missing."""
entry = MockConfigEntry(
domain=DOMAIN,
title="Home",
unique_id=123,
data={"station_id": 123, "name": "Home"},
)
with patch(
"homeassistant.components.gios.Gios._get_stations",
side_effect=ConnectionError(),
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
assert entry.state == ENTRY_STATE_SETUP_RETRY
async def test_unload_entry(hass):
"""Test successful unload of entry."""
entry = await init_integration(hass)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state == ENTRY_STATE_LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
assert entry.state == ENTRY_STATE_NOT_LOADED
assert not hass.data.get(DOMAIN)

29
tests/fixtures/gios/indexes.json vendored Normal file
View File

@ -0,0 +1,29 @@
{
"id": 123,
"stCalcDate": "2020-07-31 15:10:17",
"stIndexLevel": { "id": 1, "indexLevelName": "dobry" },
"stSourceDataDate": "2020-07-31 14:00:00",
"so2CalcDate": "2020-07-31 15:10:17",
"so2IndexLevel": { "id": 0, "indexLevelName": "bardzo dobry" },
"so2SourceDataDate": "2020-07-31 14:00:00",
"no2CalcDate": 1596201017000,
"no2IndexLevel": { "id": 0, "indexLevelName": "dobry" },
"no2SourceDataDate": "2020-07-31 14:00:00",
"coCalcDate": "2020-07-31 15:10:17",
"coIndexLevel": { "id": 0, "indexLevelName": "dobry" },
"coSourceDataDate": "2020-07-31 14:00:00",
"pm10CalcDate": "2020-07-31 15:10:17",
"pm10IndexLevel": { "id": 0, "indexLevelName": "dobry" },
"pm10SourceDataDate": "2020-07-31 14:00:00",
"pm25CalcDate": "2020-07-31 15:10:17",
"pm25IndexLevel": { "id": 0, "indexLevelName": "dobry" },
"pm25SourceDataDate": "2020-07-31 14:00:00",
"o3CalcDate": "2020-07-31 15:10:17",
"o3IndexLevel": { "id": 1, "indexLevelName": "dobry" },
"o3SourceDataDate": "2020-07-31 14:00:00",
"c6h6CalcDate": "2020-07-31 15:10:17",
"c6h6IndexLevel": { "id": 0, "indexLevelName": "bardzo dobry" },
"c6h6SourceDataDate": "2020-07-31 14:00:00",
"stIndexStatus": true,
"stIndexCrParam": "OZON"
}

51
tests/fixtures/gios/sensors.json vendored Normal file
View File

@ -0,0 +1,51 @@
{
"SO2": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 4.35478 },
{ "date": "2020-07-31 14:00:00", "value": 4.25478 },
{ "date": "2020-07-31 13:00:00", "value": 4.34309 }
]
},
"C6H6": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 0.23789 },
{ "date": "2020-07-31 14:00:00", "value": 0.22789 },
{ "date": "2020-07-31 13:00:00", "value": 0.21315 }
]
},
"CO": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 251.874 },
{ "date": "2020-07-31 14:00:00", "value": 250.874 },
{ "date": "2020-07-31 13:00:00", "value": 251.097 }
]
},
"NO2": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 7.13411 },
{ "date": "2020-07-31 14:00:00", "value": 7.33411 },
{ "date": "2020-07-31 13:00:00", "value": 9.32578 }
]
},
"O3": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 95.7768 },
{ "date": "2020-07-31 14:00:00", "value": 93.7768 },
{ "date": "2020-07-31 13:00:00", "value": 89.4232 }
]
},
"PM2.5": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 4 },
{ "date": "2020-07-31 14:00:00", "value": 4 },
{ "date": "2020-07-31 13:00:00", "value": 5 }
]
},
"PM10": {
"values": [
{ "date": "2020-07-31 15:00:00", "value": 16.8344 },
{ "date": "2020-07-31 14:00:00", "value": 17.8344 },
{ "date": "2020-07-31 13:00:00", "value": 20.8094 }
]
}
}

72
tests/fixtures/gios/station.json vendored Normal file
View File

@ -0,0 +1,72 @@
[
{
"id": 672,
"stationId": 117,
"param": {
"paramName": "dwutlenek siarki",
"paramFormula": "SO2",
"paramCode": "SO2",
"idParam": 1
}
},
{
"id": 658,
"stationId": 117,
"param": {
"paramName": "benzen",
"paramFormula": "C6H6",
"paramCode": "C6H6",
"idParam": 10
}
},
{
"id": 660,
"stationId": 117,
"param": {
"paramName": "tlenek węgla",
"paramFormula": "CO",
"paramCode": "CO",
"idParam": 8
}
},
{
"id": 665,
"stationId": 117,
"param": {
"paramName": "dwutlenek azotu",
"paramFormula": "NO2",
"paramCode": "NO2",
"idParam": 6
}
},
{
"id": 667,
"stationId": 117,
"param": {
"paramName": "ozon",
"paramFormula": "O3",
"paramCode": "O3",
"idParam": 5
}
},
{
"id": 670,
"stationId": 117,
"param": {
"paramName": "pył zawieszony PM2.5",
"paramFormula": "PM2.5",
"paramCode": "PM2.5",
"idParam": 69
}
},
{
"id": 14395,
"stationId": 117,
"param": {
"paramName": "pył zawieszony PM10",
"paramFormula": "PM10",
"paramCode": "PM10",
"idParam": 3
}
}
]