2016-08-18 22:39:16 +00:00
|
|
|
"""The tests for the WUnderground platform."""
|
2016-08-18 04:33:39 +00:00
|
|
|
import unittest
|
|
|
|
|
|
|
|
from homeassistant.components.sensor import wunderground
|
|
|
|
from homeassistant.const import TEMP_CELSIUS
|
2016-09-13 02:16:14 +00:00
|
|
|
|
|
|
|
from tests.common import get_test_home_assistant
|
2016-08-18 04:33:39 +00:00
|
|
|
|
|
|
|
VALID_CONFIG_PWS = {
|
|
|
|
'platform': 'wunderground',
|
|
|
|
'api_key': 'foo',
|
|
|
|
'pws_id': 'bar',
|
|
|
|
'monitored_conditions': [
|
2016-11-11 07:01:20 +00:00
|
|
|
'weather', 'feelslike_c', 'alerts', 'elevation', 'location'
|
2016-08-18 04:33:39 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
VALID_CONFIG = {
|
|
|
|
'platform': 'wunderground',
|
|
|
|
'api_key': 'foo',
|
|
|
|
'monitored_conditions': [
|
2016-11-11 07:01:20 +00:00
|
|
|
'weather', 'feelslike_c', 'alerts', 'elevation', 'location'
|
2016-08-18 04:33:39 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2016-12-11 23:43:42 +00:00
|
|
|
INVALID_CONFIG = {
|
|
|
|
'platform': 'wunderground',
|
|
|
|
'api_key': 'BOB',
|
|
|
|
'pws_id': 'bar',
|
|
|
|
'lang': 'foo',
|
|
|
|
'monitored_conditions': [
|
|
|
|
'weather', 'feelslike_c', 'alerts'
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2016-08-18 04:33:39 +00:00
|
|
|
FEELS_LIKE = '40'
|
|
|
|
WEATHER = 'Clear'
|
2016-11-25 20:03:12 +00:00
|
|
|
HTTPS_ICON_URL = 'https://icons.wxug.com/i/c/k/clear.gif'
|
2016-10-15 04:35:27 +00:00
|
|
|
ALERT_MESSAGE = 'This is a test alert message'
|
2016-08-18 04:33:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def mocked_requests_get(*args, **kwargs):
|
2016-08-18 16:27:38 +00:00
|
|
|
"""Mock requests.get invocations."""
|
2016-08-18 04:33:39 +00:00
|
|
|
class MockResponse:
|
2016-08-18 16:27:38 +00:00
|
|
|
"""Class to represent a mocked response."""
|
2016-08-24 03:25:52 +00:00
|
|
|
|
2016-08-18 04:33:39 +00:00
|
|
|
def __init__(self, json_data, status_code):
|
2016-08-18 16:27:38 +00:00
|
|
|
"""Initialize the mock response class."""
|
2016-08-18 04:33:39 +00:00
|
|
|
self.json_data = json_data
|
|
|
|
self.status_code = status_code
|
|
|
|
|
|
|
|
def json(self):
|
2016-08-18 16:27:38 +00:00
|
|
|
"""Return the json of the response."""
|
2016-08-18 04:33:39 +00: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
|
|
|
|
}
|
|
|
|
}, "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,
|
2016-11-25 20:03:12 +00:00
|
|
|
"icon_url": 'http://icons.wxug.com/i/c/k/clear.gif',
|
2016-11-11 07:01:20 +00:00
|
|
|
"display_location": {
|
|
|
|
"city": "Holly Springs",
|
|
|
|
"country": "US",
|
|
|
|
"full": "Holly Springs, NC"
|
|
|
|
},
|
|
|
|
"observation_location": {
|
|
|
|
"elevation": "413 ft",
|
|
|
|
"full": "Twin Lake, Holly Springs, North Carolina"
|
|
|
|
},
|
2016-10-15 04:35:27 +00:00
|
|
|
}, "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,
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
2016-08-18 04:33:39 +00:00
|
|
|
}, 200)
|
|
|
|
else:
|
|
|
|
return MockResponse({
|
2016-10-15 04:35:27 +00:00
|
|
|
"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-18 04:33:39 +00:00
|
|
|
}
|
2016-10-15 04:35:27 +00:00
|
|
|
}
|
|
|
|
}, 200)
|
2016-08-18 04:33:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TestWundergroundSetup(unittest.TestCase):
|
2016-08-18 22:39:16 +00:00
|
|
|
"""Test the WUnderground platform."""
|
2016-08-18 04:33:39 +00:00
|
|
|
|
2016-10-15 04:35:27 +00:00
|
|
|
# pylint: disable=invalid-name
|
2016-08-18 04:33:39 +00:00
|
|
|
DEVICES = []
|
|
|
|
|
|
|
|
def add_devices(self, devices):
|
2016-08-24 03:25:52 +00:00
|
|
|
"""Mock add devices."""
|
2016-08-18 04:33:39 +00:00
|
|
|
for device in devices:
|
|
|
|
self.DEVICES.append(device)
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
"""Initialize values for this testcase class."""
|
|
|
|
self.DEVICES = []
|
2016-09-13 02:16:14 +00:00
|
|
|
self.hass = get_test_home_assistant()
|
2016-08-18 04:33:39 +00: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 00:47:25 +00:00
|
|
|
def tearDown(self): # pylint: disable=invalid-name
|
|
|
|
"""Stop everything that was started."""
|
|
|
|
self.hass.stop()
|
|
|
|
|
2016-08-18 04:33:39 +00:00
|
|
|
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
|
|
|
|
def test_setup(self, req_mock):
|
2016-08-18 22:39:16 +00:00
|
|
|
"""Test that the component is loaded if passed in PWS Id."""
|
2016-08-18 04:33:39 +00:00
|
|
|
self.assertTrue(
|
|
|
|
wunderground.setup_platform(self.hass, VALID_CONFIG_PWS,
|
|
|
|
self.add_devices, None))
|
|
|
|
self.assertTrue(
|
|
|
|
wunderground.setup_platform(self.hass, VALID_CONFIG,
|
2016-10-15 04:35:27 +00:00
|
|
|
self.add_devices, None))
|
2016-08-18 04:33:39 +00:00
|
|
|
|
Removed raise statement to don't pollute the user log. (#4536)
* Removed raise statement to don't polute the user log.
Only the error message should be displayed.
Nov 22 11:28:32 tchellopi hass[20138]: 16-11-22 11:28:32 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Nov 22 11:28:32 tchellopi hass[20138]: Traceback (most recent call last):
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/tasks.py", line 241, in _step
Nov 22 11:28:32 tchellopi hass[20138]: result = coro.throw(exc)
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py", line 386, in _update_entity_states
Nov 22 11:28:32 tchellopi hass[20138]: yield from update_coro
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 213, in async_update_ha_state
Nov 22 11:28:32 tchellopi hass[20138]: yield from self.hass.loop.run_in_executor(None, self.update)
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/futures.py", line 361, in __iter__
Nov 22 11:28:32 tchellopi hass[20138]: yield self # This tells Task to wait for completion.
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
Nov 22 11:28:32 tchellopi hass[20138]: future.result()
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/futures.py", line 274, in result
Nov 22 11:28:32 tchellopi hass[20138]: raise self._exception
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/concurrent/futures/thread.py", line 55, in run
Nov 22 11:28:32 tchellopi hass[20138]: result = self.fn(*self.args, **self.kwargs)
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.homeassistant/custom_components/sensor/wunderground.py", line 187, in update
Nov 22 11:28:32 tchellopi hass[20138]: self.rest.update()
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/util/__init__.py", line 296, in wrapper
Nov 22 11:28:32 tchellopi hass[20138]: result = method(*args, **kwargs)
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.homeassistant/custom_components/sensor/wunderground.py", line 222, in update
Nov 22 11:28:32 tchellopi hass[20138]: ["description"])
Nov 22 11:28:32 tchellopi hass[20138]: ValueError: you must supply a key
* Updated unittest since we are just printing the error instead raising
2016-11-23 07:41:51 +00:00
|
|
|
self.assertTrue(
|
2016-12-11 23:43:42 +00:00
|
|
|
wunderground.setup_platform(self.hass, INVALID_CONFIG,
|
2016-08-18 04:33:39 +00:00
|
|
|
self.add_devices, None))
|
|
|
|
|
|
|
|
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
|
|
|
|
def test_sensor(self, req_mock):
|
2016-08-18 22:39:16 +00:00
|
|
|
"""Test the WUnderground sensor class and methods."""
|
2016-08-18 04:33:39 +00:00
|
|
|
wunderground.setup_platform(self.hass, VALID_CONFIG, self.add_devices,
|
|
|
|
None)
|
|
|
|
for device in self.DEVICES:
|
2016-10-15 04:35:27 +00:00
|
|
|
device.update()
|
2016-08-18 04:33:39 +00:00
|
|
|
self.assertTrue(str(device.name).startswith('PWS_'))
|
|
|
|
if device.name == 'PWS_weather':
|
2016-11-25 20:03:12 +00:00
|
|
|
self.assertEqual(HTTPS_ICON_URL, device.entity_picture)
|
2016-08-18 04:33:39 +00:00
|
|
|
self.assertEqual(WEATHER, device.state)
|
|
|
|
self.assertIsNone(device.unit_of_measurement)
|
2016-10-15 04:35:27 +00:00
|
|
|
elif device.name == 'PWS_alerts':
|
|
|
|
self.assertEqual(1, device.state)
|
|
|
|
self.assertEqual(ALERT_MESSAGE,
|
|
|
|
device.device_state_attributes['Message'])
|
|
|
|
self.assertIsNone(device.entity_picture)
|
2016-11-11 07:01:20 +00:00
|
|
|
elif device.name == 'PWS_location':
|
|
|
|
self.assertEqual('Holly Springs, NC', device.state)
|
|
|
|
elif device.name == 'PWS_elevation':
|
|
|
|
self.assertEqual('413', device.state)
|
2016-08-18 04:33:39 +00:00
|
|
|
else:
|
|
|
|
self.assertIsNone(device.entity_picture)
|
|
|
|
self.assertEqual(FEELS_LIKE, device.state)
|
|
|
|
self.assertEqual(TEMP_CELSIUS, device.unit_of_measurement)
|