From 804ddd3e4a966b5fda355221f9dc2d456be684e1 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Tue, 9 Feb 2021 20:32:41 +0100 Subject: [PATCH] SensorLineChartTile: added unit tests for _get_min_and_max() --- Pipfile | 1 + src/logic/tile/tiles/SensorLineChartTile.py | 22 +-- .../tile/tiles/TestSensorLineChartTile.py | 140 ++++++++++++++++++ 3 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 src/logic/tile/tiles/TestSensorLineChartTile.py diff --git a/Pipfile b/Pipfile index 27c34fa..1ec2328 100644 --- a/Pipfile +++ b/Pipfile @@ -27,3 +27,4 @@ icalendar = "==4.0.7" timeago = "==1.0.15" [dev-packages] +pytest= "*" diff --git a/src/logic/tile/tiles/SensorLineChartTile.py b/src/logic/tile/tiles/SensorLineChartTile.py index a8f006d..cc28613 100644 --- a/src/logic/tile/tiles/SensorLineChartTile.py +++ b/src/logic/tile/tiles/SensorLineChartTile.py @@ -47,6 +47,7 @@ class SensorLineChartTile(Tile): DATE_FORMAT = '%Y-%m-%d %H:%M:%S' DATE_FORMAT_CHART = '%H:%M:%S' + MAX_Y_AXIS_SPACING = 2 def __init__(self, uniqueName: str, settings: Dict, intervalInSeconds: int): @@ -70,15 +71,16 @@ class SensorLineChartTile(Tile): sensorData = storageLeafService.get_data(cacheKey, self._intervalInSeconds, serviceSettings) x, y = self.__prepare_measurement_data(sensorData['sensorValue']) - latestTime = datetime.strptime(x[-1], self.DATE_FORMAT) if x else datetime(year=1970, month=1, day=1, hour=0, minute=0, second=0) + latestTime = datetime.strptime(x[-1], self.DATE_FORMAT) if x else datetime(year=1970, month=1, day=1, hour=0, + minute=0, second=0) latestValue = y[-1] if y else '' - minValue, maxValue = self.__get_min_and_max(pageName, - sensorData['sensorInfo']['type'], - startDateTime, - endDateTime, - storageLeafService, - y) + minValue, maxValue = self._get_min_and_max(pageName, + sensorData['sensorInfo']['type'], + startDateTime, + endDateTime, + storageLeafService, + y) # Check if all values are above zero and the min value for the sensor group is below zero. # Therefore a ghost trace must be generated that fills the area underneath the x-axis. @@ -101,9 +103,9 @@ class SensorLineChartTile(Tile): 'latestTime': latestTime } - def __get_min_and_max(self, pageName: str, sensorType: Dict, - startDateTime: str, endDateTime: str, - storageLeafService: MultiCacheKeyService, y: List): + def _get_min_and_max(self, pageName: str, sensorType: Dict, + startDateTime: str, endDateTime: str, + storageLeafService: MultiCacheKeyService, y: List) -> Tuple[float, float]: if sensorType == SensorType.HUMIDITY: return 0, 100 diff --git a/src/logic/tile/tiles/TestSensorLineChartTile.py b/src/logic/tile/tiles/TestSensorLineChartTile.py new file mode 100644 index 0000000..b2ce512 --- /dev/null +++ b/src/logic/tile/tiles/TestSensorLineChartTile.py @@ -0,0 +1,140 @@ +import datetime +from unittest.mock import MagicMock + +import pytest + +from logic.tile.tiles.SensorLineChartTile import SensorLineChartTile, SensorType + + +@pytest.fixture() +def example_settings(): + return { + "title": "My Room", + "url": "http://127.0.0.1:10003", + "sensorID": 1, + "sensorIDsForMinMax": [2, 3, 4], + "numberOfHoursToShow": 4, + "decimals": 1, + "lineColor": "rgba(254, 151, 0, 1)", + "fillColor": "rgba(254, 151, 0, 0.2)", + "showAxes": False, + "outdatedValueWarningLimitInSeconds": 300 # use -1 to disable warning + } + + +@pytest.fixture() +def example_settings_with_axes(): + return { + "title": "My Room", + "url": "http://127.0.0.1:10003", + "sensorID": 1, + "sensorIDsForMinMax": [2, 3, 4], + "numberOfHoursToShow": 4, + "decimals": 1, + "lineColor": "rgba(254, 151, 0, 1)", + "fillColor": "rgba(254, 151, 0, 0.2)", + "showAxes": True, + "outdatedValueWarningLimitInSeconds": 300 # use -1 to disable warning + } + + +def storage_leaf_service_mock(minValue, maxValue): + storageLeafServiceMock = MagicMock() + storageLeafServiceMock.get_data = MagicMock(return_value={ + 'min': minValue, + 'max': maxValue + }) + return storageLeafServiceMock + + +START_DATE = datetime.date(year=2021, month=2, day=8) +END_DATE = datetime.date(year=2021, month=2, day=9) + + +def test_humidity_returns_0_and_100(example_settings): + tile = SensorLineChartTile('mySensorTile', example_settings, 10) + yValues = ['12.5', '10.5'] + + result = tile._get_min_and_max('myPage', + SensorType.HUMIDITY, + START_DATE, END_DATE, + storage_leaf_service_mock(15.0, 20.0), + yValues) + assert result == (0, 100) + + +def test_temperature_no_values_returns_min_and_max_of_api_plus_spacing(example_settings): + tile = SensorLineChartTile('mySensorTile', example_settings, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(15.0, 20.0), + []) + assert result == (0, 20 + SensorLineChartTile.MAX_Y_AXIS_SPACING) + + +def test_temperature_min_max_data_is_none_returns_zero_and_zero_plus_spacing(example_settings): + tile = SensorLineChartTile('mySensorTile', example_settings, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(None, None), + []) + assert result == (0, SensorLineChartTile.MAX_Y_AXIS_SPACING) + + +def test_temperature_min_is_above_zero_returns_zero_min(example_settings): + tile = SensorLineChartTile('mySensorTile', example_settings, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(5, 6), + []) + assert result == (0, 6 + SensorLineChartTile.MAX_Y_AXIS_SPACING) + + +def test_temperature_min_is_below_zero_returns_min(example_settings): + tile = SensorLineChartTile('mySensorTile', example_settings, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(-3, 6), + []) + assert result == (-3, 6 + SensorLineChartTile.MAX_Y_AXIS_SPACING) + + +def test_temperature_show_axes_no_values(example_settings_with_axes): + tile = SensorLineChartTile('mySensorTile', example_settings_with_axes, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(None, None), + []) + assert result == (0, SensorLineChartTile.MAX_Y_AXIS_SPACING) + + +def test_temperature_show_axes_values_above_zero_return_zero_min(example_settings_with_axes): + tile = SensorLineChartTile('mySensorTile', example_settings_with_axes, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(None, None), + [6.0, 12]) + assert result == (0, 12 + SensorLineChartTile.MAX_Y_AXIS_SPACING) + + +def test_temperature_show_axes_values_below_zero_return_min(example_settings_with_axes): + tile = SensorLineChartTile('mySensorTile', example_settings_with_axes, 10) + + result = tile._get_min_and_max('myPage', + SensorType.TEMPERATURE, + START_DATE, END_DATE, + storage_leaf_service_mock(None, None), + [-6.0, 12]) + assert result == (-6, 12 + SensorLineChartTile.MAX_Y_AXIS_SPACING) -- GitLab