hass-core/tests/components/sensor/test_wunderground.py

305 lines
11 KiB
Python
Raw Normal View History

2016-08-18 16:39:16 -06:00
"""The tests for the WUnderground platform."""
2016-08-17 22:33:39 -06:00
import unittest
from homeassistant.components.sensor import wunderground
from homeassistant.const import TEMP_CELSIUS, LENGTH_INCHES, STATE_UNKNOWN
from homeassistant.exceptions import PlatformNotReady
from requests.exceptions import ConnectionError
from tests.common import get_test_home_assistant
2016-08-17 22:33:39 -06:00
VALID_CONFIG_PWS = {
'platform': 'wunderground',
'api_key': 'foo',
'pws_id': 'bar',
'monitored_conditions': [
'weather', 'feelslike_c', 'alerts', 'elevation', 'location'
2016-08-17 22:33:39 -06:00
]
}
VALID_CONFIG = {
'platform': 'wunderground',
'api_key': 'foo',
'monitored_conditions': [
'weather', 'feelslike_c', 'alerts', 'elevation', 'location',
'weather_1d_metric', 'precip_1d_in'
2016-08-17 22:33:39 -06:00
]
}
INVALID_CONFIG = {
'platform': 'wunderground',
'api_key': 'BOB',
'pws_id': 'bar',
'lang': 'foo',
'monitored_conditions': [
'weather', 'feelslike_c', 'alerts'
]
}
2016-08-17 22:33:39 -06:00
FEELS_LIKE = '40'
WEATHER = 'Clear'
HTTPS_ICON_URL = 'https://icons.wxug.com/i/c/k/clear.gif'
ALERT_MESSAGE = 'This is a test alert message'
ALERT_ICON = 'mdi:alert-circle-outline'
FORECAST_TEXT = 'Mostly Cloudy. Fog overnight.'
PRECIP_IN = 0.03
2016-08-17 22:33:39 -06:00
def mocked_requests_get(*args, **kwargs):
2016-08-18 10:27:38 -06:00
"""Mock requests.get invocations."""
2016-08-17 22:33:39 -06:00
class MockResponse:
2016-08-18 10:27:38 -06:00
"""Class to represent a mocked response."""
2016-08-23 20:25:52 -07:00
2016-08-17 22:33:39 -06:00
def __init__(self, json_data, status_code):
2016-08-18 10:27:38 -06:00
"""Initialize the mock response class."""
2016-08-17 22:33:39 -06:00
self.json_data = json_data
self.status_code = status_code
def json(self):
2016-08-18 10:27:38 -06:00
"""Return the json of the response."""
2016-08-17 22:33:39 -06:00
return self.json_data
if str(args[0]).startswith('http://api.wunderground.com/api/foo/'):
return MockResponse({
"response": {
"version": "0.1",
"termsofService":
"http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"conditions": 1,
"alerts": 1,
"forecast": 1,
2016-08-17 22:33:39 -06:00
}
}, "current_observation": {
"image": {
"url":
'http://icons.wxug.com/graphics/wu2/logo_130x80.png',
"title": "Weather Underground",
"link": "http://www.wunderground.com"
},
"feelslike_c": FEELS_LIKE,
"weather": WEATHER,
"icon_url": 'http://icons.wxug.com/i/c/k/clear.gif',
"display_location": {
"city": "Holly Springs",
"country": "US",
"full": "Holly Springs, NC"
},
"observation_location": {
"elevation": "413 ft",
"full": "Twin Lake, Holly Springs, North Carolina"
},
}, "alerts": [
{
"type": 'FLO',
"description": "Areal Flood Warning",
"date": "9:36 PM CDT on September 22, 2016",
"expires": "10:00 AM CDT on September 23, 2016",
"message": ALERT_MESSAGE,
},
], "forecast": {
"txt_forecast": {
"date": "22:35 CEST",
"forecastday": [
{
"period": 0,
"icon_url":
"http://icons.wxug.com/i/c/k/clear.gif",
"title": "Tuesday",
"fcttext": FORECAST_TEXT,
"fcttext_metric": FORECAST_TEXT,
"pop": "0"
},
],
}, "simpleforecast": {
"forecastday": [
{
"date": {
"pretty": "19:00 CEST 4. Duben 2017",
},
"period": 1,
"high": {
"fahrenheit": "56",
"celsius": "13",
},
"low": {
"fahrenheit": "43",
"celsius": "6",
},
"conditions": "Možnost deště",
"icon_url":
"http://icons.wxug.com/i/c/k/chancerain.gif",
"qpf_allday": {
"in": PRECIP_IN,
"mm": 1,
},
"maxwind": {
"mph": 0,
"kph": 0,
"dir": "",
"degrees": 0,
},
"avewind": {
"mph": 0,
"kph": 0,
"dir": "severní",
"degrees": 0
}
},
],
},
},
2016-08-17 22:33:39 -06:00
}, 200)
else:
return MockResponse({
"response": {
"version": "0.1",
"termsofService":
"http://www.wunderground.com/weather/api/d/terms.html",
"features": {},
"error": {
"type": "keynotfound",
"description": "this key does not exist"
2016-08-17 22:33:39 -06:00
}
}
}, 200)
2016-08-17 22:33:39 -06:00
def mocked_requests_get_invalid(*args, **kwargs):
"""Mock requests.get invocations invalid data."""
class MockResponse:
"""Class to represent a mocked response."""
def __init__(self, json_data, status_code):
"""Initialize the mock response class."""
self.json_data = json_data
self.status_code = status_code
def json(self):
"""Return the json of the response."""
return self.json_data
return MockResponse({
"response": {
"version": "0.1",
"termsofService":
"http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"conditions": 1,
"alerts": 1,
"forecast": 1,
}
}, "current_observation": {
"image": {
"url":
'http://icons.wxug.com/graphics/wu2/logo_130x80.png',
"title": "Weather Underground",
"link": "http://www.wunderground.com"
},
},
}, 200)
2016-08-17 22:33:39 -06:00
class TestWundergroundSetup(unittest.TestCase):
2016-08-18 16:39:16 -06:00
"""Test the WUnderground platform."""
2016-08-17 22:33:39 -06:00
# pylint: disable=invalid-name
2016-08-17 22:33:39 -06:00
DEVICES = []
def add_devices(self, devices):
2016-08-23 20:25:52 -07:00
"""Mock add devices."""
2016-08-17 22:33:39 -06:00
for device in devices:
self.DEVICES.append(device)
def setUp(self):
"""Initialize values for this testcase class."""
self.DEVICES = []
self.hass = get_test_home_assistant()
2016-08-17 22:33:39 -06:00
self.key = 'foo'
self.config = VALID_CONFIG_PWS
self.lat = 37.8267
self.lon = -122.423
self.hass.config.latitude = self.lat
self.hass.config.longitude = self.lon
2017-01-07 01:47:25 +01:00
def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started."""
self.hass.stop()
2016-08-17 22:33:39 -06:00
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
def test_setup(self, req_mock):
2016-08-18 16:39:16 -06:00
"""Test that the component is loaded if passed in PWS Id."""
2016-08-17 22:33:39 -06:00
self.assertTrue(
wunderground.setup_platform(self.hass, VALID_CONFIG_PWS,
self.add_devices, None))
self.assertTrue(
wunderground.setup_platform(self.hass, VALID_CONFIG,
self.add_devices, None))
2016-08-17 22:33:39 -06:00
with self.assertRaises(PlatformNotReady):
wunderground.setup_platform(self.hass, INVALID_CONFIG,
self.add_devices, None)
2016-08-17 22:33:39 -06:00
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
def test_sensor(self, req_mock):
2016-08-18 16:39:16 -06:00
"""Test the WUnderground sensor class and methods."""
2016-08-17 22:33:39 -06:00
wunderground.setup_platform(self.hass, VALID_CONFIG, self.add_devices,
None)
for device in self.DEVICES:
device.update()
entity_id = device.entity_id
friendly_name = device.name
self.assertTrue(entity_id.startswith('sensor.pws_'))
if entity_id == 'sensor.pws_weather':
self.assertEqual(HTTPS_ICON_URL, device.entity_picture)
2016-08-17 22:33:39 -06:00
self.assertEqual(WEATHER, device.state)
self.assertIsNone(device.unit_of_measurement)
self.assertEqual("Weather Summary", friendly_name)
elif entity_id == 'sensor.pws_alerts':
self.assertEqual(1, device.state)
self.assertEqual(ALERT_MESSAGE,
device.device_state_attributes['Message'])
self.assertEqual(ALERT_ICON, device.icon)
self.assertIsNone(device.entity_picture)
self.assertEqual('Alerts', friendly_name)
elif entity_id == 'sensor.pws_location':
self.assertEqual('Holly Springs, NC', device.state)
self.assertEqual('Location', friendly_name)
elif entity_id == 'sensor.pws_elevation':
self.assertEqual('413', device.state)
self.assertEqual('Elevation', friendly_name)
elif entity_id == 'sensor.pws_feelslike_c':
2016-08-17 22:33:39 -06:00
self.assertIsNone(device.entity_picture)
self.assertEqual(FEELS_LIKE, device.state)
self.assertEqual(TEMP_CELSIUS, device.unit_of_measurement)
self.assertEqual("Feels Like", friendly_name)
elif entity_id == 'sensor.pws_weather_1d_metric':
self.assertEqual(FORECAST_TEXT, device.state)
self.assertEqual('Tuesday', friendly_name)
else:
self.assertEqual(entity_id, 'sensor.pws_precip_1d_in')
self.assertEqual(PRECIP_IN, device.state)
self.assertEqual(LENGTH_INCHES, device.unit_of_measurement)
self.assertEqual('Precipitation Intensity Today',
friendly_name)
@unittest.mock.patch('requests.get',
side_effect=ConnectionError('test exception'))
def test_connect_failed(self, req_mock):
"""Test the WUnderground connection error."""
with self.assertRaises(PlatformNotReady):
wunderground.setup_platform(self.hass, VALID_CONFIG,
self.add_devices, None)
@unittest.mock.patch('requests.get',
side_effect=mocked_requests_get_invalid)
def test_invalid_data(self, req_mock):
"""Test the WUnderground invalid data."""
wunderground.setup_platform(self.hass, VALID_CONFIG_PWS,
self.add_devices, None)
for device in self.DEVICES:
device.update()
self.assertEqual(STATE_UNKNOWN, device.state)