mirror of
https://github.com/craigerl/aprsd.git
synced 2026-10-12 02:04:18 -04:00
get_weather_gov_metar() called json.loads(response) with the
requests.Response object, which raises TypeError ('the JSON object
must be str, bytes or bytearray'). Every METAR-by-station request
fell into the plugin's catch-all and returned 'Unable to find
station METAR'.
Parse response.text instead and return the dict. USMetarPlugin
was then double-parsing with json.loads(resp.text) on the result;
it now consumes the dict directly. The now-unused json import in
weather.py was dropped.
73 lines
2.7 KiB
Python
73 lines
2.7 KiB
Python
import unittest
|
|
from unittest import mock
|
|
|
|
from aprsd import plugin_utils
|
|
|
|
|
|
class TestPluginUtilsTimeouts(unittest.TestCase):
|
|
"""Every outbound requests.get() must use an explicit timeout."""
|
|
|
|
def test_request_timeout_is_positive(self):
|
|
self.assertIsInstance(plugin_utils.REQUEST_TIMEOUT, int)
|
|
self.assertGreater(plugin_utils.REQUEST_TIMEOUT, 0)
|
|
|
|
def _assert_timeout(self, mock_get):
|
|
args, kwargs = mock_get.call_args
|
|
self.assertEqual(kwargs.get('timeout'), plugin_utils.REQUEST_TIMEOUT)
|
|
|
|
def test_get_aprs_fi_uses_timeout(self):
|
|
with (
|
|
mock.patch('aprsd.plugin_utils.requests.get') as mock_get,
|
|
mock.patch('aprsd.plugin_utils.json.loads') as mock_loads,
|
|
):
|
|
mock_loads.return_value = {}
|
|
plugin_utils.get_aprs_fi('key', 'N0CALL')
|
|
self._assert_timeout(mock_get)
|
|
|
|
def test_get_weather_gov_for_gps_uses_timeout(self):
|
|
with (
|
|
mock.patch('aprsd.plugin_utils.requests.get') as mock_get,
|
|
mock.patch('aprsd.plugin_utils.json.loads') as mock_loads,
|
|
):
|
|
mock_loads.return_value = {}
|
|
plugin_utils.get_weather_gov_for_gps(37.7, -122.4)
|
|
self._assert_timeout(mock_get)
|
|
|
|
def test_get_weather_gov_metar_uses_timeout(self):
|
|
with (
|
|
mock.patch('aprsd.plugin_utils.requests.get') as mock_get,
|
|
mock.patch('aprsd.plugin_utils.json.loads') as mock_loads,
|
|
):
|
|
mock_loads.return_value = {}
|
|
plugin_utils.get_weather_gov_metar('KJFK')
|
|
self._assert_timeout(mock_get)
|
|
|
|
def test_get_weather_gov_metar_returns_parsed_json(self):
|
|
"""get_weather_gov_metar must return the parsed JSON dict.
|
|
|
|
It previously called json.loads(response) with a requests.Response
|
|
object, which raises TypeError: the JSON object must be str, bytes
|
|
or bytearray. That made every METAR-by-station request fail.
|
|
"""
|
|
|
|
class Response:
|
|
text = '{"properties": {"rawMessage": "BOGUSMETAR"}}'
|
|
|
|
def raise_for_status(self):
|
|
pass
|
|
|
|
with mock.patch('aprsd.plugin_utils.requests.get') as mock_get:
|
|
mock_get.return_value = Response()
|
|
result = plugin_utils.get_weather_gov_metar('KJFK')
|
|
|
|
self.assertEqual(result, {'properties': {'rawMessage': 'BOGUSMETAR'}})
|
|
|
|
def test_fetch_openweathermap_uses_timeout(self):
|
|
with (
|
|
mock.patch('aprsd.plugin_utils.requests.get') as mock_get,
|
|
mock.patch('aprsd.plugin_utils.json.loads') as mock_loads,
|
|
):
|
|
mock_loads.return_value = {}
|
|
plugin_utils.fetch_openweathermap('key', 37.7, -122.4)
|
|
self._assert_timeout(mock_get)
|