Refactor Airly tests (#44315)

This commit is contained in:
Maciej Bieniek 2020-12-17 16:44:46 +01:00 committed by GitHub
parent 7c63119ad2
commit 94e1f8e631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 171 additions and 185 deletions

View File

@ -1,30 +1,31 @@
"""Tests for Airly."""
import json
from homeassistant.components.airly.const import DOMAIN
from tests.async_mock import patch
from tests.common import MockConfigEntry, load_fixture
API_KEY_VALIDATION_URL = (
"https://airapi.airly.eu/v2/measurements/point?lat=52.241310&lng=20.991010"
)
API_POINT_URL = (
"https://airapi.airly.eu/v2/measurements/point?lat=123.000000&lng=456.000000"
)
async def init_integration(hass, forecast=False) -> MockConfigEntry:
async def init_integration(hass, aioclient_mock) -> MockConfigEntry:
"""Set up the Airly integration in Home Assistant."""
entry = MockConfigEntry(
domain=DOMAIN,
title="Home",
unique_id="55.55-122.12",
unique_id="123-456",
data={
"api_key": "foo",
"latitude": 55.55,
"longitude": 122.12,
"latitude": 123,
"longitude": 456,
"name": "Home",
},
)
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_valid_station.json"))
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

View File

@ -1,6 +1,5 @@
"""Test air_quality of Airly integration."""
from datetime import timedelta
import json
from airly.exceptions import AirlyError
@ -21,19 +20,21 @@ from homeassistant.const import (
ATTR_ICON,
ATTR_UNIT_OF_MEASUREMENT,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
HTTP_INTERNAL_SERVER_ERROR,
STATE_UNAVAILABLE,
)
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow
from tests.async_mock import patch
from . import API_POINT_URL
from tests.common import async_fire_time_changed, load_fixture
from tests.components.airly import init_integration
async def test_air_quality(hass):
async def test_air_quality(hass, aioclient_mock):
"""Test states of the air_quality."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
registry = await hass.helpers.entity_registry.async_get_registry()
state = hass.states.get("air_quality.home")
@ -58,23 +59,24 @@ async def test_air_quality(hass):
entry = registry.async_get("air_quality.home")
assert entry
assert entry.unique_id == "55.55-122.12"
assert entry.unique_id == "123-456"
async def test_availability(hass):
async def test_availability(hass, aioclient_mock):
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
state = hass.states.get("air_quality.home")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "14"
aioclient_mock.clear_requests()
aioclient_mock.get(
API_POINT_URL, exc=AirlyError(HTTP_INTERNAL_SERVER_ERROR, "Unexpected error")
)
future = utcnow() + timedelta(minutes=60)
with patch(
"airly._private._RequestsHandler.get",
side_effect=AirlyError(500, "Unexpected error"),
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@ -82,11 +84,10 @@ async def test_availability(hass):
assert state
assert state.state == STATE_UNAVAILABLE
aioclient_mock.clear_requests()
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_valid_station.json"))
future = utcnow() + timedelta(minutes=120)
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@ -96,18 +97,17 @@ async def test_availability(hass):
assert state.state == "14"
async def test_manual_update_entity(hass):
async def test_manual_update_entity(hass, aioclient_mock):
"""Test manual update entity via service homeasasistant/update_entity."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
call_count = aioclient_mock.call_count
await async_setup_component(hass, "homeassistant", {})
with patch(
"homeassistant.components.airly.AirlyDataUpdateCoordinator._async_update_data"
) as mock_update:
await hass.services.async_call(
"homeassistant",
"update_entity",
{ATTR_ENTITY_ID: ["air_quality.home"]},
blocking=True,
)
assert mock_update.call_count == 1
assert aioclient_mock.call_count == call_count + 1

View File

@ -1,6 +1,4 @@
"""Define tests for the Airly config flow."""
import json
from airly.exceptions import AirlyError
from homeassistant import data_entry_flow
@ -11,14 +9,15 @@ from homeassistant.const import (
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_NAME,
HTTP_FORBIDDEN,
HTTP_UNAUTHORIZED,
)
from tests.async_mock import patch
from tests.common import MockConfigEntry, load_fixture
from . import API_KEY_VALIDATION_URL, API_POINT_URL
from tests.common import MockConfigEntry, load_fixture, patch
CONFIG = {
CONF_NAME: "abcd",
CONF_NAME: "Home",
CONF_API_KEY: "foo",
CONF_LATITUDE: 123,
CONF_LONGITUDE: 456,
@ -35,14 +34,14 @@ async def test_show_form(hass):
assert result["step_id"] == SOURCE_USER
async def test_invalid_api_key(hass):
async def test_invalid_api_key(hass, aioclient_mock):
"""Test that errors are shown when API key is invalid."""
with patch(
"airly._private._RequestsHandler.get",
side_effect=AirlyError(
HTTP_FORBIDDEN, {"message": "Invalid authentication credentials"}
aioclient_mock.get(
API_KEY_VALIDATION_URL,
exc=AirlyError(
HTTP_UNAUTHORIZED, {"message": "Invalid authentication credentials"}
),
):
)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
@ -51,12 +50,12 @@ async def test_invalid_api_key(hass):
assert result["errors"] == {"base": "invalid_api_key"}
async def test_invalid_location(hass):
async def test_invalid_location(hass, aioclient_mock):
"""Test that errors are shown when location is invalid."""
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_no_station.json")),
):
aioclient_mock.get(
API_KEY_VALIDATION_URL, text=load_fixture("airly_valid_station.json")
)
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_no_station.json"))
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
@ -65,16 +64,10 @@ async def test_invalid_location(hass):
assert result["errors"] == {"base": "wrong_location"}
async def test_duplicate_error(hass):
async def test_duplicate_error(hass, aioclient_mock):
"""Test that errors are shown when duplicates are added."""
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
MockConfigEntry(domain=DOMAIN, unique_id="123-456", data=CONFIG).add_to_hass(
hass
)
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_valid_station.json"))
MockConfigEntry(domain=DOMAIN, unique_id="123-456", data=CONFIG).add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
@ -84,14 +77,14 @@ async def test_duplicate_error(hass):
assert result["reason"] == "already_configured"
async def test_create_entry(hass):
async def test_create_entry(hass, aioclient_mock):
"""Test that the user step works."""
aioclient_mock.get(
API_KEY_VALIDATION_URL, text=load_fixture("airly_valid_station.json")
)
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_valid_station.json"))
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
with patch("homeassistant.components.airly.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)

View File

@ -1,6 +1,5 @@
"""Test init of Airly integration."""
from datetime import timedelta
import json
from homeassistant.components.airly.const import DOMAIN
from homeassistant.config_entries import (
@ -10,14 +9,15 @@ from homeassistant.config_entries import (
)
from homeassistant.const import STATE_UNAVAILABLE
from tests.async_mock import patch
from . import API_POINT_URL
from tests.common import MockConfigEntry, load_fixture
from tests.components.airly import init_integration
async def test_async_setup_entry(hass):
async def test_async_setup_entry(hass, aioclient_mock):
"""Test a successful setup entry."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
state = hass.states.get("air_quality.home")
assert state is not None
@ -25,75 +25,69 @@ async def test_async_setup_entry(hass):
assert state.state == "14"
async def test_config_not_ready(hass):
async def test_config_not_ready(hass, aioclient_mock):
"""Test for setup failure if connection to Airly is missing."""
entry = MockConfigEntry(
domain=DOMAIN,
title="Home",
unique_id="55.55-122.12",
unique_id="123-456",
data={
"api_key": "foo",
"latitude": 55.55,
"longitude": 122.12,
"latitude": 123,
"longitude": 456,
"name": "Home",
},
)
with patch("airly._private._RequestsHandler.get", side_effect=ConnectionError()):
aioclient_mock.get(API_POINT_URL, exc=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_config_without_unique_id(hass):
async def test_config_without_unique_id(hass, aioclient_mock):
"""Test for setup entry without unique_id."""
entry = MockConfigEntry(
domain=DOMAIN,
title="Home",
data={
"api_key": "foo",
"latitude": 55.55,
"longitude": 122.12,
"latitude": 123,
"longitude": 456,
"name": "Home",
},
)
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_valid_station.json"))
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
assert entry.state == ENTRY_STATE_LOADED
assert entry.unique_id == "55.55-122.12"
assert entry.unique_id == "123-456"
async def test_config_with_turned_off_station(hass):
async def test_config_with_turned_off_station(hass, aioclient_mock):
"""Test for setup entry for a turned off measuring station."""
entry = MockConfigEntry(
domain=DOMAIN,
title="Home",
unique_id="55.55-122.12",
unique_id="123-456",
data={
"api_key": "foo",
"latitude": 55.55,
"longitude": 122.12,
"latitude": 123,
"longitude": 456,
"name": "Home",
},
)
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_no_station.json")),
):
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_no_station.json"))
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
assert entry.state == ENTRY_STATE_SETUP_RETRY
async def test_update_interval(hass):
async def test_update_interval(hass, aioclient_mock):
"""Test correct update interval when the number of configured instances changes."""
entry = await init_integration(hass)
entry = await init_integration(hass, aioclient_mock)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state == ENTRY_STATE_LOADED
@ -112,10 +106,10 @@ async def test_update_interval(hass):
},
)
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
aioclient_mock.get(
"https://airapi.airly.eu/v2/measurements/point?lat=66.660000&lng=111.110000",
text=load_fixture("airly_valid_station.json"),
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
@ -126,9 +120,9 @@ async def test_update_interval(hass):
assert instance.update_interval == timedelta(minutes=30)
async def test_unload_entry(hass):
async def test_unload_entry(hass, aioclient_mock):
"""Test successful unload of entry."""
entry = await init_integration(hass)
entry = await init_integration(hass, aioclient_mock)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state == ENTRY_STATE_LOADED

View File

@ -1,6 +1,5 @@
"""Test sensor of Airly integration."""
from datetime import timedelta
import json
from homeassistant.components.airly.sensor import ATTRIBUTION
from homeassistant.const import (
@ -21,14 +20,15 @@ from homeassistant.const import (
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow
from tests.async_mock import patch
from . import API_POINT_URL
from tests.common import async_fire_time_changed, load_fixture
from tests.components.airly import init_integration
async def test_sensor(hass):
async def test_sensor(hass, aioclient_mock):
"""Test states of the sensor."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
registry = await hass.helpers.entity_registry.async_get_registry()
state = hass.states.get("sensor.home_humidity")
@ -40,7 +40,7 @@ async def test_sensor(hass):
entry = registry.async_get("sensor.home_humidity")
assert entry
assert entry.unique_id == "55.55-122.12-humidity"
assert entry.unique_id == "123-456-humidity"
state = hass.states.get("sensor.home_pm1")
assert state
@ -54,7 +54,7 @@ async def test_sensor(hass):
entry = registry.async_get("sensor.home_pm1")
assert entry
assert entry.unique_id == "55.55-122.12-pm1"
assert entry.unique_id == "123-456-pm1"
state = hass.states.get("sensor.home_pressure")
assert state
@ -65,7 +65,7 @@ async def test_sensor(hass):
entry = registry.async_get("sensor.home_pressure")
assert entry
assert entry.unique_id == "55.55-122.12-pressure"
assert entry.unique_id == "123-456-pressure"
state = hass.states.get("sensor.home_temperature")
assert state
@ -76,20 +76,21 @@ async def test_sensor(hass):
entry = registry.async_get("sensor.home_temperature")
assert entry
assert entry.unique_id == "55.55-122.12-temperature"
assert entry.unique_id == "123-456-temperature"
async def test_availability(hass):
async def test_availability(hass, aioclient_mock):
"""Ensure that we mark the entities unavailable correctly when service is offline."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
state = hass.states.get("sensor.home_humidity")
assert state
assert state.state != STATE_UNAVAILABLE
assert state.state == "92.8"
aioclient_mock.clear_requests()
aioclient_mock.get(API_POINT_URL, exc=ConnectionError())
future = utcnow() + timedelta(minutes=60)
with patch("airly._private._RequestsHandler.get", side_effect=ConnectionError()):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@ -97,11 +98,9 @@ async def test_availability(hass):
assert state
assert state.state == STATE_UNAVAILABLE
aioclient_mock.clear_requests()
aioclient_mock.get(API_POINT_URL, text=load_fixture("airly_valid_station.json"))
future = utcnow() + timedelta(minutes=120)
with patch(
"airly._private._RequestsHandler.get",
return_value=json.loads(load_fixture("airly_valid_station.json")),
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@ -111,18 +110,17 @@ async def test_availability(hass):
assert state.state == "92.8"
async def test_manual_update_entity(hass):
async def test_manual_update_entity(hass, aioclient_mock):
"""Test manual update entity via service homeasasistant/update_entity."""
await init_integration(hass)
await init_integration(hass, aioclient_mock)
call_count = aioclient_mock.call_count
await async_setup_component(hass, "homeassistant", {})
with patch(
"homeassistant.components.airly.AirlyDataUpdateCoordinator._async_update_data"
) as mock_update:
await hass.services.async_call(
"homeassistant",
"update_entity",
{ATTR_ENTITY_ID: ["sensor.home_humidity"]},
blocking=True,
)
assert mock_update.call_count == 1
assert aioclient_mock.call_count == call_count + 1