]> git.basschouten.com Git - openhab-addons.git/blob
7a007ff027a0460c24ee1744226fd267e8ec32de
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.pegelonline.internal.handler;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.Mockito.*;
17 import static org.openhab.binding.pegelonline.internal.PegelOnlineBindingConstants.*;
18
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.TimeoutException;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jetty.client.HttpClient;
24 import org.eclipse.jetty.client.api.ContentResponse;
25 import org.junit.jupiter.api.Test;
26 import org.openhab.binding.pegelonline.internal.config.PegelOnlineConfiguration;
27 import org.openhab.binding.pegelonline.internal.dto.Measure;
28 import org.openhab.binding.pegelonline.internal.dto.Station;
29 import org.openhab.binding.pegelonline.internal.util.FileReader;
30 import org.openhab.binding.pegelonline.internal.utils.Utils;
31 import org.openhab.core.config.core.Configuration;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.thing.ThingStatus;
34 import org.openhab.core.thing.ThingStatusDetail;
35 import org.openhab.core.thing.ThingStatusInfo;
36 import org.openhab.core.thing.ThingTypeUID;
37 import org.openhab.core.thing.internal.ThingImpl;
38 import org.openhab.core.types.State;
39
40 /**
41  * The {@link PegelTest} Test helper utils
42  *
43  * @author Bernd Weymann - Initial contribution
44  */
45 @NonNullByDefault
46 class PegelTest {
47     public static final String TEST_STATION_UUID = "1ebd0f94-cc06-445c-8e73-43fe2b8c72dc";
48
49     @Test
50     void testConfigurationValidations() {
51         PegelOnlineConfiguration config = new PegelOnlineConfiguration();
52         assertFalse(config.uuidCheck(), config.uuid);
53         config.uuid = "abc@";
54         assertFalse(config.uuidCheck(), config.uuid);
55         config.uuid = "abc d";
56         assertFalse(config.uuidCheck(), config.uuid);
57         config.uuid = "1234567a-abc1-efd9-cdf3-0123456789ab";
58         assertTrue(config.uuidCheck(), config.uuid);
59         assertTrue(config.warningCheck(), "Warnings");
60
61         String content = FileReader.readFileInString("src/test/resources/stations.json");
62         Station[] stationArray = GSON.fromJson(content, Station[].class);
63         assertNotNull(stationArray);
64         for (Station station : stationArray) {
65             config.uuid = station.uuid;
66             assertTrue(config.uuidCheck(), config.uuid);
67         }
68     }
69
70     @Test
71     void testNameConversion() {
72         String stationName = "EIDER-SPERRWERK BP";
73         String conversion = Utils.toTitleCase(stationName);
74         assertEquals("Eider-Sperrwerk Bp", conversion, "Station Name");
75
76         String content = FileReader.readFileInString("src/test/resources/stations.json");
77         Station[] stationArray = GSON.fromJson(content, Station[].class);
78         assertNotNull(stationArray);
79         for (Station station : stationArray) {
80             assertTrue(Character.isUpperCase(Utils.toTitleCase(station.shortname).charAt(0)),
81                     "First Character Upper Case");
82             assertTrue(Character.isUpperCase(Utils.toTitleCase(station.water.shortname).charAt(0)),
83                     "First Character Upper Case");
84         }
85     }
86
87     @Test
88     void testDistance() {
89         // Frankfurt Main: 50.117461111005, 8.639069127891485
90         String content = FileReader.readFileInString("src/test/resources/stations.json");
91         Station[] stationArray = GSON.fromJson(content, Station[].class);
92         assertNotNull(stationArray);
93         int hitCounter = 0;
94         for (Station station : stationArray) {
95             double distance = Utils.calculateDistance(50.117461111005, 8.639069127891485, station.latitude,
96                     station.longitude);
97             if (distance < 50) {
98                 hitCounter++;
99                 assertTrue(station.water.shortname.equals("RHEIN") || station.water.shortname.equals("MAIN"),
100                         "RHEIN or MAIN");
101             }
102         }
103         assertEquals(11, hitCounter, "Meassurement Stations around FRA");
104     }
105
106     @Test
107     void testMeasureObject() {
108         String content = FileReader.readFileInString("src/test/resources/measure.json");
109         Measure measure = GSON.fromJson(content, Measure.class);
110         if (measure != null) {
111             assertEquals("2021-08-01T16:00:00+02:00", measure.timestamp, "Timestamp");
112             assertEquals(238, measure.value, "Level");
113             assertEquals(-1, measure.trend, "Trend");
114         } else {
115             fail();
116         }
117     }
118
119     @Test
120     void test404Status() {
121         String stationContent = FileReader.readFileInString("src/test/resources/stations.json");
122         ContentResponse stationResponse = mock(ContentResponse.class);
123         when(stationResponse.getStatus()).thenReturn(200);
124         when(stationResponse.getContentAsString()).thenReturn(stationContent);
125
126         String content = "{}";
127         ContentResponse measureResponse = mock(ContentResponse.class);
128         when(measureResponse.getStatus()).thenReturn(404);
129         when(measureResponse.getContentAsString()).thenReturn(content);
130
131         HttpClient httpClientMock = mock(HttpClient.class);
132         try {
133             when(httpClientMock.GET(STATIONS_URI + "/" + TEST_STATION_UUID + "/W/currentmeasurement.json"))
134                     .thenReturn(measureResponse);
135             when(httpClientMock.GET(STATIONS_URI)).thenReturn(stationResponse);
136         } catch (InterruptedException | ExecutionException | TimeoutException e) {
137             fail();
138         }
139
140         CallbackMock callback = new CallbackMock();
141         ThingImpl ti = new ThingImpl(new ThingTypeUID("pegelonline:station"), "test");
142         PegelOnlineHandler handler = new PegelOnlineHandler(ti, httpClientMock);
143         Configuration config = new Configuration();
144         config.put("uuid", TEST_STATION_UUID);
145         handler.setCallback(callback);
146         handler.updateConfiguration(config);
147         handler.initialize();
148         handler.performMeasurement();
149         ThingStatusInfo tsi = callback.getThingStatus();
150         assertNotNull(tsi);
151         assertEquals(ThingStatus.OFFLINE, tsi.getStatus(), "Status");
152         assertEquals(ThingStatusDetail.CONFIGURATION_ERROR, tsi.getStatusDetail(), "Detail");
153         String description = tsi.getDescription();
154         assertNotNull(description);
155         assertEquals("@text/pegelonline.handler.status.uuid-not-found [\"" + TEST_STATION_UUID + "\"]", description,
156                 "Description");
157     }
158
159     @Test
160     void testWrongContent() {
161         String stationContent = FileReader.readFileInString("src/test/resources/stations.json");
162         ContentResponse stationResponse = mock(ContentResponse.class);
163         when(stationResponse.getStatus()).thenReturn(200);
164         when(stationResponse.getContentAsString()).thenReturn(stationContent);
165
166         String content = "{}";
167         ContentResponse measureResponse = mock(ContentResponse.class);
168         when(measureResponse.getStatus()).thenReturn(200);
169         when(measureResponse.getContentAsString()).thenReturn(content);
170
171         HttpClient httpClientMock = mock(HttpClient.class);
172         try {
173             when(httpClientMock.GET(STATIONS_URI + "/" + TEST_STATION_UUID + "/W/currentmeasurement.json"))
174                     .thenReturn(measureResponse);
175             when(httpClientMock.GET(STATIONS_URI)).thenReturn(stationResponse);
176         } catch (InterruptedException | ExecutionException | TimeoutException e) {
177             fail();
178         }
179
180         CallbackMock callback = new CallbackMock();
181         ThingImpl ti = new ThingImpl(new ThingTypeUID("pegelonline:station"), "test");
182         PegelOnlineHandler handler = new PegelOnlineHandler(ti, httpClientMock);
183         Configuration config = new Configuration();
184         config.put("uuid", TEST_STATION_UUID);
185         handler.setCallback(callback);
186         handler.updateConfiguration(config);
187         handler.initialize();
188         handler.performMeasurement();
189         ThingStatusInfo tsi = callback.getThingStatus();
190         assertNotNull(tsi);
191         assertEquals(ThingStatus.OFFLINE, tsi.getStatus(), "Status");
192         assertEquals(ThingStatusDetail.COMMUNICATION_ERROR, tsi.getStatusDetail(), "Detail");
193         String description = tsi.getDescription();
194         assertNotNull(description);
195         assertEquals("@text/pegelonline.handler.status.json-error [\"{}\"]", description, "Description");
196     }
197
198     @Test
199     public void testWrongConfiguration() {
200         CallbackMock callback = new CallbackMock();
201         PegelOnlineHandler handler = getConfiguredHandler(callback, 99);
202
203         Configuration config = new Configuration();
204         config.put("uuid", " ");
205         handler.updateConfiguration(new Configuration(config));
206         handler.initialize();
207
208         ThingStatusInfo tsi = callback.getThingStatus();
209         assertNotNull(tsi);
210         assertEquals(ThingStatus.OFFLINE, tsi.getStatus(), "Status");
211         assertEquals(ThingStatusDetail.CONFIGURATION_ERROR, tsi.getStatusDetail(), "Detail");
212         String description = tsi.getDescription();
213         assertNotNull(description);
214         assertEquals("@text/pegelonline.handler.status.uuid [\" \"]", description, "Description");
215     }
216
217     @Test
218     public void testInconsistentLevels() {
219         CallbackMock callback = new CallbackMock();
220         PegelOnlineHandler handler = getConfiguredHandler(callback, 99);
221
222         Configuration config = new Configuration();
223         config.put("uuid", TEST_STATION_UUID);
224         config.put("warningLevel1", 100);
225         config.put("warningLevel2", 200);
226         config.put("warningLevel3", 150);
227         handler.updateConfiguration(config);
228         handler.initialize();
229
230         ThingStatusInfo tsi = callback.getThingStatus();
231         assertNotNull(tsi);
232         assertEquals(ThingStatus.OFFLINE, tsi.getStatus(), "Status");
233         assertEquals(ThingStatusDetail.CONFIGURATION_ERROR, tsi.getStatusDetail(), "Detail");
234         String description = tsi.getDescription();
235         assertNotNull(description);
236         assertEquals("@text/pegelonline.handler.status.warning", description, "Description");
237
238         handler.dispose();
239         config = new Configuration();
240         config.put("uuid", TEST_STATION_UUID);
241         config.put("warningLevel1", 100);
242         config.put("warningLevel2", 200);
243         config.put("warningLevel3", 300);
244         config.put("hqExtreme", 600);
245         handler.updateConfiguration(new Configuration(config));
246         handler.initialize();
247
248         tsi = callback.getThingStatus();
249         assertNotNull(tsi);
250         assertEquals(ThingStatus.UNKNOWN, tsi.getStatus(), "Status");
251         assertEquals(ThingStatusDetail.NONE, tsi.getStatusDetail(), "Detail");
252         description = tsi.getDescription();
253         assertNotNull(description);
254         assertEquals("@text/pegelonline.handler.status.wait-feedback", description, "Description");
255
256         handler.dispose();
257         config = new Configuration();
258         config.put("uuid", TEST_STATION_UUID);
259         config.put("warningLevel1", 100);
260         config.put("warningLevel2", 200);
261         config.put("warningLevel3", 300);
262         config.put("hq10", 100);
263         config.put("hq100", 200);
264         config.put("hqExtreme", 150);
265         handler.updateConfiguration(new Configuration(config));
266         handler.initialize();
267
268         tsi = callback.getThingStatus();
269         assertNotNull(tsi);
270         assertEquals(ThingStatus.OFFLINE, tsi.getStatus(), "Status");
271         assertEquals(ThingStatusDetail.CONFIGURATION_ERROR, tsi.getStatusDetail(), "Detail");
272         description = tsi.getDescription();
273         assertNotNull(description);
274         assertEquals("@text/pegelonline.handler.status.warning", description, "Description");
275     }
276
277     @Test
278     public void testWrongResponse() {
279         String measureContent = "{}";
280         ContentResponse measureResponse = mock(ContentResponse.class);
281         when(measureResponse.getStatus()).thenReturn(500);
282         when(measureResponse.getContentAsString()).thenReturn(measureContent);
283         HttpClient httpClientMock = mock(HttpClient.class);
284         try {
285             when(httpClientMock.GET(STATIONS_URI + "/" + TEST_STATION_UUID + "/W/currentmeasurement.json"))
286                     .thenReturn(measureResponse);
287         } catch (InterruptedException | ExecutionException | TimeoutException e) {
288             fail();
289         }
290
291         CallbackMock callback = new CallbackMock();
292         ThingImpl ti = new ThingImpl(new ThingTypeUID("pegelonline:station"), "test");
293         PegelOnlineHandler handler = new PegelOnlineHandler(ti, httpClientMock);
294         Configuration config = new Configuration();
295         config.put("uuid", TEST_STATION_UUID);
296         handler.setCallback(callback);
297         handler.updateConfiguration(config);
298         handler.initialize();
299         handler.performMeasurement();
300         ThingStatusInfo tsi = callback.getThingStatus();
301         assertNotNull(tsi);
302         assertEquals(ThingStatus.OFFLINE, tsi.getStatus(), "Status");
303         assertEquals(ThingStatusDetail.COMMUNICATION_ERROR, tsi.getStatusDetail(), "Detail");
304         String description = tsi.getDescription();
305         assertNotNull(description);
306         assertEquals("@text/pegelonline.handler.status.http-status [\"500\"]", description, "Description");
307     }
308
309     @Test
310     public void testWarnings() {
311         CallbackMock callback = new CallbackMock();
312         PegelOnlineHandler handler = getConfiguredHandler(callback, 99);
313         handler.initialize();
314         handler.performMeasurement();
315         State state = callback.getState("pegelonline:station:test:warning");
316         assertTrue(state instanceof DecimalType);
317         assertEquals(NO_WARNING, ((DecimalType) state).intValue(), "No warning");
318
319         handler = getConfiguredHandler(callback, 100);
320         handler.initialize();
321         handler.performMeasurement();
322         state = callback.getState("pegelonline:station:test:warning");
323         assertTrue(state instanceof DecimalType);
324         assertEquals(WARN_LEVEL_1, ((DecimalType) state).intValue(), "Warn Level 1");
325
326         handler = getConfiguredHandler(callback, 299);
327         handler.initialize();
328         handler.performMeasurement();
329         state = callback.getState("pegelonline:station:test:warning");
330         assertTrue(state instanceof DecimalType);
331         assertEquals(WARN_LEVEL_2, ((DecimalType) state).intValue(), "Warn Level 2");
332
333         handler = getConfiguredHandler(callback, 1000);
334         handler.initialize();
335         handler.performMeasurement();
336         state = callback.getState("pegelonline:station:test:warning");
337         assertTrue(state instanceof DecimalType);
338         assertEquals(HQ_EXTREME, ((DecimalType) state).intValue(), "HQ extreme");
339     }
340
341     private PegelOnlineHandler getConfiguredHandler(CallbackMock callback, int levelSimulation) {
342         String stationContent = FileReader.readFileInString("src/test/resources/stations.json");
343         ContentResponse stationResponse = mock(ContentResponse.class);
344         when(stationResponse.getStatus()).thenReturn(200);
345         when(stationResponse.getContentAsString()).thenReturn(stationContent);
346
347         String measureContent = "{  \"timestamp\": \"2021-08-01T16:00:00+02:00\",  \"value\": " + levelSimulation
348                 + ",  \"trend\": -1}";
349         ContentResponse measureResponse = mock(ContentResponse.class);
350         when(measureResponse.getStatus()).thenReturn(200);
351         when(measureResponse.getContentAsString()).thenReturn(measureContent);
352         HttpClient httpClientMock = mock(HttpClient.class);
353         try {
354             when(httpClientMock.GET(STATIONS_URI + "/" + TEST_STATION_UUID + "/W/currentmeasurement.json"))
355                     .thenReturn(measureResponse);
356             when(httpClientMock.GET(STATIONS_URI)).thenReturn(stationResponse);
357         } catch (InterruptedException | ExecutionException | TimeoutException e) {
358             fail();
359         }
360
361         ThingImpl ti = new ThingImpl(new ThingTypeUID("pegelonline:station"), "test");
362         PegelOnlineHandler handler = new PegelOnlineHandler(ti, httpClientMock);
363         Configuration config = new Configuration();
364         config.put("uuid", TEST_STATION_UUID);
365         config.put("warningLevel1", 100);
366         config.put("warningLevel2", 200);
367         config.put("warningLevel3", 300);
368         config.put("hq10", 400);
369         config.put("hq100", 500);
370         config.put("hqExtreme", 600);
371         handler.setCallback(callback);
372         handler.updateConfiguration(config);
373         return handler;
374     }
375 }