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