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:
committed by
Paulus Schoutsen
parent
3899c6ae27
commit
b8feaba5cb
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user