Files
aprsd/tests/test_plugin_utils.py
hemna 8c45c762c7 fix: return parsed JSON from get_weather_gov_metar
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.
2026-09-20 10:48:44 -04:00

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)