diff --git a/src/logic/tile/tiles/SensorLineChartTile.py b/src/logic/tile/tiles/SensorLineChartTile.py index ab32abfaf3caf22b576fa136198b71c33ad6c7b2..4d21d148203978b67f12e64c5de45f1ac8075a1e 100644 --- a/src/logic/tile/tiles/SensorLineChartTile.py +++ b/src/logic/tile/tiles/SensorLineChartTile.py @@ -58,6 +58,7 @@ class SensorLineChartTile(Tile): def __init__(self, uniqueName: str, settings: Dict, intervalInSeconds: int): super().__init__(uniqueName, settings, intervalInSeconds) + self._notificationSent = False def fetch(self, pageName: str) -> Dict: storageLeafService = ServiceManager.get_instance().get_service_by_type_name('StorageLeafService') @@ -225,6 +226,13 @@ class SensorLineChartTile(Tile): if not warningSettings['enableNotificationViaPushbullet']: return + if not timeSinceLastValue: + self._notificationSent = False + return + + if self._notificationSent: + return + token = warningSettings['pushbulletToken'] sensorName = sensorInfo['name'] @@ -236,6 +244,7 @@ class SensorLineChartTile(Tile): f'(type: {sensorType}, device: {deviceName})' Helpers.send_notification_via_pushbullet(token, title, description) + self._notificationSent = True def __format_date(self, dateTime: str): parsedDateTime = datetime.strptime(dateTime, self.DATE_FORMAT) diff --git a/test/logic/tile/tiles/TestSensorLineChartTile.py b/test/logic/tile/tiles/TestSensorLineChartTile.py index fef996714fc487d249dd541ea58de0fa8909680a..a44e12310a47aadcafba07ac675983a6341df7e3 100644 --- a/test/logic/tile/tiles/TestSensorLineChartTile.py +++ b/test/logic/tile/tiles/TestSensorLineChartTile.py @@ -1,4 +1,5 @@ import datetime +from typing import Dict from unittest import mock from unittest.mock import MagicMock @@ -208,7 +209,7 @@ class TestGetTimeSinceLastValue: class TestSendNotification: - def __get_warning_settings(self, enable: bool, enableNotification: bool): + def __get_warning_settings(self, enable: bool, enableNotification: bool) -> Dict: return { 'enable': enable, 'limitInSeconds': 10, @@ -216,6 +217,17 @@ class TestSendNotification: 'pushbulletToken': 'myToken' } + def __get_sensor_info(self) -> Dict[str, str]: + return { + 'name': 'mySensor', + 'type': 'temperature' + } + + def __get_device_info(self) -> Dict[str, str]: + return { + 'name': 'myDevice' + } + @mock.patch('logic.tile.tiles.SensorLineChartTile.Helpers') def test_notification_disabled_should_do_nothing(self, helpersMock): tile = SensorLineChartTile('mySensorTile', example_settings(False), 10) @@ -225,22 +237,51 @@ class TestSendNotification: tile._send_notification(warningSettings, {}, {}, '1 hour ago') helpersMock.send_notification_via_pushbullet.assert_not_called() + @mock.patch('logic.tile.tiles.SensorLineChartTile.Helpers') + def test_notification_enabled_no_outdated_value_should_do_nothing(self, helpersMock): + tile = SensorLineChartTile('mySensorTile', example_settings(False), 10) + + warningSettings = self.__get_warning_settings(True, True) + + tile._send_notification(warningSettings, {}, {}, '') + helpersMock.send_notification_via_pushbullet.assert_not_called() + @mock.patch('logic.Helpers.requests') def test_send_notification_should_call_pushbullet_api(self, requestsMock): tile = SensorLineChartTile('mySensorTile', example_settings(False), 10) warningSettings = self.__get_warning_settings(True, True) - sensorInfo = { - 'name': 'mySensor', - 'type': 'temperature' - } + requestsMock.post.return_value.status_code = 200 - deviceInfo = { - 'name': 'myDevice' - } + tile._send_notification(warningSettings, self.__get_sensor_info(), self.__get_device_info(), '1 hour ago') + requestsMock.post.assert_called_once_with(Helpers.PUSHBULLET_PUSH_URL, data=mock.ANY, headers=mock.ANY) + + @mock.patch('logic.Helpers.requests') + def test_already_sent_should_skip_sending(self, requestsMock): + tile = SensorLineChartTile('mySensorTile', example_settings(False), 10) + + warningSettings = self.__get_warning_settings(True, True) requestsMock.post.return_value.status_code = 200 - tile._send_notification(warningSettings, sensorInfo, deviceInfo, '1 hour ago') - requestsMock.post.assert_called_once_with(Helpers.PUSHBULLET_PUSH_URL, data=mock.ANY, headers=mock.ANY) + tile._send_notification(warningSettings, self.__get_sensor_info(), self.__get_device_info(), '1 hour ago') + tile._send_notification(warningSettings, self.__get_sensor_info(), self.__get_device_info(), '1 hour ago') + requestsMock.post.assert_called_once() + + @mock.patch('logic.Helpers.requests') + def test_already_sent_new_value_arrives_and_gets_outdated_should_call_pushbullet_api(self, requestsMock): + tile = SensorLineChartTile('mySensorTile', example_settings(False), 10) + + warningSettings = self.__get_warning_settings(True, True) + requestsMock.post.return_value.status_code = 200 + + tile._send_notification(warningSettings, self.__get_sensor_info(), self.__get_device_info(), '1 hour ago') + + # a new valid value arrives + tile._send_notification(warningSettings, self.__get_sensor_info(), self.__get_device_info(), '') + + # value is outdated again + tile._send_notification(warningSettings, self.__get_sensor_info(), self.__get_device_info(), '1 hour ago') + + assert requestsMock.post.call_count == 2