1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-26 22:18:40 +00:00

Update pynws to v0.10.1 (#30662)

* update to pynws 0.10.1

* remove unneeded raw json files

* move test helper module to const
This commit is contained in:
MatthewFlamm
2020-01-15 15:01:47 -05:00
committed by Paulus Schoutsen
parent 3899c6ae27
commit b8feaba5cb
12 changed files with 262 additions and 1679 deletions

View File

@@ -1,87 +1,25 @@
"""Tests for the NWS weather component."""
from homeassistant.components.nws.weather import ATTR_FORECAST_PRECIP_PROB
from homeassistant.components.weather import (
ATTR_FORECAST,
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_TEMP,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
ATTR_FORECAST_WIND_SPEED,
ATTR_WEATHER_HUMIDITY,
ATTR_WEATHER_PRESSURE,
ATTR_WEATHER_TEMPERATURE,
ATTR_WEATHER_VISIBILITY,
ATTR_WEATHER_WIND_BEARING,
ATTR_WEATHER_WIND_SPEED,
)
from homeassistant.const import (
LENGTH_KILOMETERS,
LENGTH_METERS,
LENGTH_MILES,
PRESSURE_HPA,
PRESSURE_INHG,
PRESSURE_PA,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from unittest.mock import patch
import aiohttp
import pytest
from homeassistant.components.weather import ATTR_FORECAST
from homeassistant.setup import async_setup_component
from homeassistant.util.distance import convert as convert_distance
from homeassistant.util.pressure import convert as convert_pressure
from homeassistant.util.temperature import convert as convert_temperature
from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM
from tests.common import assert_setup_component, load_fixture
EXP_OBS_IMP = {
ATTR_WEATHER_TEMPERATURE: round(
convert_temperature(26.7, TEMP_CELSIUS, TEMP_FAHRENHEIT)
),
ATTR_WEATHER_WIND_BEARING: 190,
ATTR_WEATHER_WIND_SPEED: round(
convert_distance(2.6, LENGTH_METERS, LENGTH_MILES) * 3600
),
ATTR_WEATHER_PRESSURE: round(
convert_pressure(101040, PRESSURE_PA, PRESSURE_INHG), 2
),
ATTR_WEATHER_VISIBILITY: round(
convert_distance(16090, LENGTH_METERS, LENGTH_MILES)
),
ATTR_WEATHER_HUMIDITY: 64,
}
EXP_OBS_METR = {
ATTR_WEATHER_TEMPERATURE: round(26.7),
ATTR_WEATHER_WIND_BEARING: 190,
ATTR_WEATHER_WIND_SPEED: round(
convert_distance(2.6, LENGTH_METERS, LENGTH_KILOMETERS) * 3600
),
ATTR_WEATHER_PRESSURE: round(convert_pressure(101040, PRESSURE_PA, PRESSURE_HPA)),
ATTR_WEATHER_VISIBILITY: round(
convert_distance(16090, LENGTH_METERS, LENGTH_KILOMETERS)
),
ATTR_WEATHER_HUMIDITY: 64,
}
EXP_FORE_IMP = {
ATTR_FORECAST_CONDITION: "lightning-rainy",
ATTR_FORECAST_TIME: "2019-08-12T20:00:00-04:00",
ATTR_FORECAST_TEMP: 70,
ATTR_FORECAST_WIND_SPEED: 10,
ATTR_FORECAST_WIND_BEARING: 180,
ATTR_FORECAST_PRECIP_PROB: 90,
}
EXP_FORE_METR = {
ATTR_FORECAST_CONDITION: "lightning-rainy",
ATTR_FORECAST_TIME: "2019-08-12T20:00:00-04:00",
ATTR_FORECAST_TEMP: round(convert_temperature(70, TEMP_FAHRENHEIT, TEMP_CELSIUS)),
ATTR_FORECAST_WIND_SPEED: round(
convert_distance(10, LENGTH_MILES, LENGTH_KILOMETERS)
),
ATTR_FORECAST_WIND_BEARING: 180,
ATTR_FORECAST_PRECIP_PROB: 90,
}
from .const import (
DEFAULT_FORECAST,
DEFAULT_OBSERVATION,
EXPECTED_FORECAST_IMPERIAL,
EXPECTED_FORECAST_METRIC,
EXPECTED_OBSERVATION_IMPERIAL,
EXPECTED_OBSERVATION_METRIC,
NONE_FORECAST,
NONE_OBSERVATION,
)
from tests.common import mock_coro
MINIMAL_CONFIG = {
"weather": {
@@ -92,169 +30,168 @@ MINIMAL_CONFIG = {
}
}
INVALID_CONFIG = {
"weather": {"platform": "nws", "api_key": "x@example.com", "latitude": 40.0}
HOURLY_CONFIG = {
"weather": {
"platform": "nws",
"api_key": "x@example.com",
"latitude": 40.0,
"longitude": -85.0,
"mode": "hourly",
}
}
STAURL = "https://api.weather.gov/points/{},{}/stations"
OBSURL = "https://api.weather.gov/stations/{}/observations/"
FORCURL = "https://api.weather.gov/points/{},{}/forecast"
@pytest.mark.parametrize(
"units,result_observation,result_forecast",
[
(IMPERIAL_SYSTEM, EXPECTED_OBSERVATION_IMPERIAL, EXPECTED_FORECAST_IMPERIAL),
(METRIC_SYSTEM, EXPECTED_OBSERVATION_METRIC, EXPECTED_FORECAST_METRIC),
],
)
async def test_imperial_metric(hass, units, result_observation, result_forecast):
"""Test with imperial and metric units."""
hass.config.units = units
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.return_value = mock_coro()
instance.update_observation.return_value = mock_coro()
instance.update_forecast.return_value = mock_coro()
instance.observation = DEFAULT_OBSERVATION
instance.forecast = DEFAULT_FORECAST
async def test_imperial(hass, aioclient_mock):
"""Test with imperial units."""
aioclient_mock.get(
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
)
aioclient_mock.get(
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
)
aioclient_mock.get(
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
)
hass.config.units = IMPERIAL_SYSTEM
with assert_setup_component(1, "weather"):
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
state = hass.states.get("weather.kmie")
state = hass.states.get("weather.abc")
assert state
assert state.state == "sunny"
data = state.attributes
for key, value in EXP_OBS_IMP.items():
for key, value in result_observation.items():
assert data.get(key) == value
assert state.attributes.get("friendly_name") == "KMIE"
forecast = data.get(ATTR_FORECAST)
for key, value in EXP_FORE_IMP.items():
for key, value in result_forecast.items():
assert forecast[0].get(key) == value
async def test_metric(hass, aioclient_mock):
"""Test with metric units."""
aioclient_mock.get(
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
)
aioclient_mock.get(
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
)
aioclient_mock.get(
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
)
async def test_hourly(hass):
"""Test with hourly option."""
hass.config.units = IMPERIAL_SYSTEM
hass.config.units = METRIC_SYSTEM
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.return_value = mock_coro()
instance.update_observation.return_value = mock_coro()
instance.update_forecast_hourly.return_value = mock_coro()
instance.observation = DEFAULT_OBSERVATION
instance.forecast_hourly = DEFAULT_FORECAST
with assert_setup_component(1, "weather"):
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
await async_setup_component(hass, "weather", HOURLY_CONFIG)
state = hass.states.get("weather.kmie")
state = hass.states.get("weather.abc")
assert state
assert state.state == "sunny"
data = state.attributes
for key, value in EXP_OBS_METR.items():
for key, value in EXPECTED_OBSERVATION_IMPERIAL.items():
assert data.get(key) == value
assert state.attributes.get("friendly_name") == "KMIE"
forecast = data.get(ATTR_FORECAST)
for key, value in EXP_FORE_METR.items():
for key, value in EXPECTED_FORECAST_IMPERIAL.items():
assert forecast[0].get(key) == value
async def test_none(hass, aioclient_mock):
"""Test with imperial units."""
aioclient_mock.get(
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
)
aioclient_mock.get(
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-null.json")
)
aioclient_mock.get(
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-null.json")
)
hass.config.units = IMPERIAL_SYSTEM
with assert_setup_component(1, "weather"):
async def test_none_values(hass):
"""Test with none values in observation and forecast dicts."""
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.return_value = mock_coro()
instance.update_observation.return_value = mock_coro()
instance.update_forecast.return_value = mock_coro()
instance.observation = NONE_OBSERVATION
instance.forecast = NONE_FORECAST
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
state = hass.states.get("weather.kmie")
state = hass.states.get("weather.abc")
assert state
assert state.state == "unknown"
data = state.attributes
for key in EXP_OBS_IMP:
for key in EXPECTED_OBSERVATION_IMPERIAL:
assert data.get(key) is None
assert state.attributes.get("friendly_name") == "KMIE"
forecast = data.get(ATTR_FORECAST)
for key in EXP_FORE_IMP:
for key in EXPECTED_FORECAST_IMPERIAL:
assert forecast[0].get(key) is None
async def test_fail_obs(hass, aioclient_mock):
"""Test failing observation/forecast update."""
aioclient_mock.get(
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
)
aioclient_mock.get(
OBSURL.format("KMIE"),
text=load_fixture("nws-weather-obs-valid.json"),
status=400,
)
aioclient_mock.get(
FORCURL.format(40.0, -85.0),
text=load_fixture("nws-weather-fore-valid.json"),
status=400,
)
hass.config.units = IMPERIAL_SYSTEM
with assert_setup_component(1, "weather"):
async def test_none(hass):
"""Test with None as observation and forecast."""
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.return_value = mock_coro()
instance.update_observation.return_value = mock_coro()
instance.update_forecast.return_value = mock_coro()
instance.observation = None
instance.forecast = None
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
state = hass.states.get("weather.kmie")
state = hass.states.get("weather.abc")
assert state
assert state.state == "unknown"
data = state.attributes
for key in EXPECTED_OBSERVATION_IMPERIAL:
assert data.get(key) is None
forecast = data.get(ATTR_FORECAST)
assert forecast is None
async def test_fail_stn(hass, aioclient_mock):
"""Test failing station update."""
aioclient_mock.get(
STAURL.format(40.0, -85.0),
text=load_fixture("nws-weather-sta-valid.json"),
status=400,
)
aioclient_mock.get(
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
)
aioclient_mock.get(
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
)
hass.config.units = IMPERIAL_SYSTEM
with assert_setup_component(1, "weather"):
async def test_error_station(hass):
"""Test error in setting station."""
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.side_effect = aiohttp.ClientError
instance.update_observation.return_value = mock_coro()
instance.update_forecast.return_value = mock_coro()
instance.observation = None
instance.forecast = None
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
state = hass.states.get("weather.kmie")
assert state is None
state = hass.states.get("weather.abc")
assert state is None
async def test_invalid_config(hass, aioclient_mock):
"""Test invalid config.."""
aioclient_mock.get(
STAURL.format(40.0, -85.0), text=load_fixture("nws-weather-sta-valid.json")
)
aioclient_mock.get(
OBSURL.format("KMIE"), text=load_fixture("nws-weather-obs-valid.json")
)
aioclient_mock.get(
FORCURL.format(40.0, -85.0), text=load_fixture("nws-weather-fore-valid.json")
)
async def test_error_observation(hass, caplog):
"""Test error during update observation."""
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.return_value = mock_coro()
instance.update_observation.side_effect = aiohttp.ClientError
instance.update_forecast.return_value = mock_coro()
instance.observation = None
instance.forecast = None
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
hass.config.units = IMPERIAL_SYSTEM
assert "Error updating observation from station ABC" in caplog.text
with assert_setup_component(0, "weather"):
await async_setup_component(hass, "weather", INVALID_CONFIG)
state = hass.states.get("weather.kmie")
assert state is None
async def test_error_forecast(hass, caplog):
"""Test error during update forecast."""
with patch("homeassistant.components.nws.weather.SimpleNWS") as mock_nws:
instance = mock_nws.return_value
instance.station = "ABC"
instance.set_station.return_value = mock_coro()
instance.update_observation.return_value = mock_coro()
instance.update_forecast.side_effect = aiohttp.ClientError
instance.observation = None
instance.forecast = None
await async_setup_component(hass, "weather", MINIMAL_CONFIG)
assert "Error updating forecast from station ABC" in caplog.text