2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.wundergroundupdatereceiver.internal;
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.core.Is.is;
17 import static org.hamcrest.core.IsIterableContaining.hasItems;
18 import static org.mockito.Mockito.any;
19 import static org.mockito.Mockito.eq;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.never;
22 import static org.mockito.Mockito.verify;
23 import static org.mockito.Mockito.when;
24 import static org.mockito.MockitoAnnotations.openMocks;
25 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.DATEUTC_DATETIME_CHANNELTYPEUID;
26 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.HUMIDITY_GROUP;
27 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.LAST_QUERY_STATE_CHANNELTYPEUID;
28 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.LAST_QUERY_TRIGGER_CHANNELTYPEUID;
29 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.LAST_RECEIVED_DATETIME_CHANNELTYPEUID;
30 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.METADATA_GROUP;
31 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.POLLUTION_GROUP;
32 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.PRESSURE_GROUP;
33 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.RAIN_GROUP;
34 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.SUNLIGHT_GROUP;
35 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.TEMPERATURE_GROUP;
36 import static org.openhab.binding.wundergroundupdatereceiver.internal.WundergroundUpdateReceiverBindingConstants.WIND_GROUP;
38 import java.io.IOException;
39 import java.util.List;
42 import javax.servlet.ServletException;
43 import javax.servlet.http.HttpServletResponse;
45 import org.eclipse.jdt.annotation.NonNullByDefault;
46 import org.eclipse.jetty.http.HttpFields;
47 import org.eclipse.jetty.http.HttpURI;
48 import org.eclipse.jetty.http.HttpVersion;
49 import org.eclipse.jetty.http.MetaData;
50 import org.eclipse.jetty.server.HttpChannel;
51 import org.eclipse.jetty.server.Request;
52 import org.junit.jupiter.api.BeforeEach;
53 import org.junit.jupiter.api.Test;
54 import org.mockito.Answers;
55 import org.mockito.ArgumentCaptor;
56 import org.mockito.Mock;
57 import org.openhab.core.config.core.Configuration;
58 import org.openhab.core.library.types.DateTimeType;
59 import org.openhab.core.library.types.DecimalType;
60 import org.openhab.core.library.types.OnOffType;
61 import org.openhab.core.library.types.QuantityType;
62 import org.openhab.core.library.types.StringType;
63 import org.openhab.core.library.unit.ImperialUnits;
64 import org.openhab.core.library.unit.Units;
65 import org.openhab.core.thing.Channel;
66 import org.openhab.core.thing.ChannelUID;
67 import org.openhab.core.thing.ManagedThingProvider;
68 import org.openhab.core.thing.Thing;
69 import org.openhab.core.thing.ThingStatus;
70 import org.openhab.core.thing.ThingUID;
71 import org.openhab.core.thing.binding.ThingHandlerCallback;
72 import org.openhab.core.thing.binding.builder.ChannelBuilder;
73 import org.openhab.core.thing.binding.builder.ThingBuilder;
74 import org.openhab.core.thing.type.ChannelKind;
75 import org.openhab.core.thing.type.ChannelTypeBuilder;
76 import org.openhab.core.thing.type.ChannelTypeRegistry;
77 import org.osgi.service.http.NamespaceException;
80 * @author Daniel Demus - Initial contribution
83 class WundergroundUpdateReceiverServletTest {
85 private static final String STATION_ID_1 = "abcd1234";
86 private static final String STATION_ID_2 = "1234abcd";
87 private static final String REQ_STATION_ID = "dfggger";
88 private static final ThingUID TEST_THING_UID = new ThingUID(
89 WundergroundUpdateReceiverBindingConstants.THING_TYPE_UPDATE_RECEIVER, "test-receiver");
91 private @Mock ChannelTypeRegistry channelTypeRegistry;
92 private @Mock WundergroundUpdateReceiverDiscoveryService discoveryService;
93 private @Mock ManagedThingProvider managedThingProvider;
101 void theServletIsActiveAfterTheFirstHandlerIsAdded() throws ServletException, NamespaceException {
103 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
104 WundergroundUpdateReceiverHandler handler = mock(WundergroundUpdateReceiverHandler.class);
105 when(handler.getStationId()).thenReturn(STATION_ID_1);
108 sut.addHandler(handler);
111 assertThat(sut.isActive(), is(true));
115 void theServletIsInactiveAfterTheLastHandlerIsRemovedAndBackgroundDiscoveryIsDisabled()
116 throws ServletException, NamespaceException {
118 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
119 WundergroundUpdateReceiverHandler handler = mock(WundergroundUpdateReceiverHandler.class);
120 when(handler.getStationId()).thenReturn(STATION_ID_1);
121 when(discoveryService.isBackgroundDiscoveryEnabled()).thenReturn(false);
124 sut.addHandler(handler);
127 assertThat(sut.isActive(), is(true));
130 sut.removeHandler(handler.getStationId());
133 assertThat(sut.isActive(), is(false));
137 void theServletIsActiveAfterTheLastHandlerIsRemovedButBackgroundDiscoveryIsEnabled()
138 throws ServletException, NamespaceException {
140 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
141 WundergroundUpdateReceiverHandler handler = mock(WundergroundUpdateReceiverHandler.class);
142 when(handler.getStationId()).thenReturn(STATION_ID_1);
143 when(discoveryService.isBackgroundDiscoveryEnabled()).thenReturn(true);
146 sut.addHandler(handler);
149 assertThat(sut.isActive(), is(true));
152 sut.removeHandler(handler.getStationId());
155 assertThat(sut.isActive(), is(true));
159 void onDisposeAllHandlersAreRemovedAndServletIsInactive() throws ServletException, NamespaceException {
161 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
162 WundergroundUpdateReceiverHandler handler1 = mock(WundergroundUpdateReceiverHandler.class);
163 when(handler1.getStationId()).thenReturn(STATION_ID_1);
164 WundergroundUpdateReceiverHandler handler2 = mock(WundergroundUpdateReceiverHandler.class);
165 when(handler2.getStationId()).thenReturn(STATION_ID_2);
168 sut.addHandler(handler1);
169 sut.addHandler(handler2);
172 assertThat(sut.isActive(), is(true));
178 assertThat(sut.isActive(), is(false));
182 void OnDisposeAllHandlersAreRemovedAndServletIsInactiveEvenThoughBackgroundDiscoveryIsEnabled()
183 throws ServletException, NamespaceException {
185 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
186 WundergroundUpdateReceiverHandler handler1 = mock(WundergroundUpdateReceiverHandler.class);
187 when(handler1.getStationId()).thenReturn(STATION_ID_1);
188 WundergroundUpdateReceiverHandler handler2 = mock(WundergroundUpdateReceiverHandler.class);
189 when(handler2.getStationId()).thenReturn(STATION_ID_2);
190 when(discoveryService.isBackgroundDiscoveryEnabled()).thenReturn(true);
193 sut.addHandler(handler1);
194 sut.addHandler(handler2);
197 assertThat(sut.isActive(), is(true));
203 assertThat(sut.isActive(), is(false));
207 void changedStationIdPropagatesToHandlerKey() throws ServletException, NamespaceException {
209 Thing thing = mock(Thing.class);
210 when(thing.getUID()).thenReturn(TEST_THING_UID);
211 when(thing.getConfiguration()).thenReturn(new Configuration(
212 Map.of(WundergroundUpdateReceiverBindingConstants.REPRESENTATION_PROPERTY, STATION_ID_1)));
213 when(thing.getStatus()).thenReturn(ThingStatus.ONLINE);
214 when(this.channelTypeRegistry.getChannelType(LAST_RECEIVED_DATETIME_CHANNELTYPEUID))
215 .thenReturn(ChannelTypeBuilder.state(LAST_RECEIVED_DATETIME_CHANNELTYPEUID, "Label", "String").build());
216 when(this.channelTypeRegistry.getChannelType(DATEUTC_DATETIME_CHANNELTYPEUID))
217 .thenReturn(ChannelTypeBuilder.state(DATEUTC_DATETIME_CHANNELTYPEUID, "Label", "DateTime").build());
218 when(this.channelTypeRegistry.getChannelType(LAST_QUERY_STATE_CHANNELTYPEUID))
219 .thenReturn(ChannelTypeBuilder.state(LAST_QUERY_STATE_CHANNELTYPEUID, "Label", "String").build());
220 when(this.channelTypeRegistry.getChannelType(LAST_QUERY_TRIGGER_CHANNELTYPEUID))
221 .thenReturn(ChannelTypeBuilder.trigger(LAST_QUERY_TRIGGER_CHANNELTYPEUID, "Label").build());
222 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
223 WundergroundUpdateReceiverHandler handler = new WundergroundUpdateReceiverHandler(thing, sut, discoveryService,
224 new WundergroundUpdateReceiverUnknownChannelTypeProvider(), channelTypeRegistry, managedThingProvider);
225 ThingHandlerCallback mockCallback = mock(ThingHandlerCallback.class);
226 handler.setCallback(mockCallback);
229 handler.initialize();
232 assertThat(sut.isActive(), is(true));
233 assertThat(sut.getStationIds(), hasItems(STATION_ID_1));
236 handler.handleConfigurationUpdate(
237 Map.of(WundergroundUpdateReceiverBindingConstants.REPRESENTATION_PROPERTY, STATION_ID_2));
240 assertThat(sut.isActive(), is(true));
241 ArgumentCaptor<Thing> thingArg = ArgumentCaptor.forClass(Thing.class);
242 verify(mockCallback).configurationUpdated(thingArg.capture());
243 assertThat(thingArg.getValue().getConfiguration().getProperties()
244 .get(WundergroundUpdateReceiverBindingConstants.REPRESENTATION_PROPERTY), is(STATION_ID_2));
248 void aGetRequestIsCorrectlyParsed() throws IOException {
250 ThingUID testThingUID = new ThingUID(WundergroundUpdateReceiverBindingConstants.THING_TYPE_UPDATE_RECEIVER,
252 final String queryString = "ID=dfggger&PASSWORD=XXXXXX&tempf=26.1&humidity=74&dewptf=18.9&windchillf=26.1&winddir=14&windspeedmph=1.34&windgustmph=2.46&rainin=0.00&dailyrainin=0.00&weeklyrainin=0.00&monthlyrainin=0.08&yearlyrainin=3.06&solarradiation=42.24&UV=1&indoortempf=69.3&indoorhumidity=32&baromin=30.39&AqNOX=21&lowbatt=1&dateutc=2021-02-07%2014:04:03&softwaretype=WH2600%20V2.2.8&action=updateraw&realtime=1&rtfreq=5";
253 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
254 List<Channel> channels = List.of(
256 .create(new ChannelUID(testThingUID, METADATA_GROUP,
257 WundergroundUpdateReceiverBindingConstants.DATEUTC), "String")
258 .withKind(ChannelKind.STATE).build(),
260 .create(new ChannelUID(testThingUID, METADATA_GROUP,
261 WundergroundUpdateReceiverBindingConstants.REALTIME_FREQUENCY), "Number")
262 .withKind(ChannelKind.STATE).build(),
264 .create(new ChannelUID(testThingUID, METADATA_GROUP,
265 WundergroundUpdateReceiverBindingConstants.LOW_BATTERY), "Switch")
266 .withKind(ChannelKind.STATE).build(),
268 .create(new ChannelUID(testThingUID, WIND_GROUP,
269 WundergroundUpdateReceiverBindingConstants.WIND_DIRECTION), "Number:Angle")
270 .withKind(ChannelKind.STATE).build(),
272 .create(new ChannelUID(testThingUID, WIND_GROUP,
273 WundergroundUpdateReceiverBindingConstants.WIND_SPEED), "Number:Speed")
274 .withKind(ChannelKind.STATE).build(),
276 .create(new ChannelUID(testThingUID, WIND_GROUP,
277 WundergroundUpdateReceiverBindingConstants.GUST_SPEED), "Number:Speed")
278 .withKind(ChannelKind.STATE).build(),
280 .create(new ChannelUID(testThingUID, TEMPERATURE_GROUP,
281 WundergroundUpdateReceiverBindingConstants.TEMPERATURE), "Number:Temperature")
282 .withKind(ChannelKind.STATE).build(),
284 .create(new ChannelUID(testThingUID, RAIN_GROUP,
285 WundergroundUpdateReceiverBindingConstants.RAIN_IN), "Number:Length")
286 .withKind(ChannelKind.STATE).build(),
288 .create(new ChannelUID(testThingUID, SUNLIGHT_GROUP,
289 WundergroundUpdateReceiverBindingConstants.SOLAR_RADIATION), "Number:Intensity")
290 .withKind(ChannelKind.STATE).build(),
292 .create(new ChannelUID(testThingUID, SUNLIGHT_GROUP,
293 WundergroundUpdateReceiverBindingConstants.UV), "Number")
294 .withKind(ChannelKind.STATE).build(),
296 .create(new ChannelUID(testThingUID, PRESSURE_GROUP,
297 WundergroundUpdateReceiverBindingConstants.BAROM_IN), "Number:Pressure")
298 .withKind(ChannelKind.STATE).build(),
300 .create(new ChannelUID(testThingUID, HUMIDITY_GROUP,
301 WundergroundUpdateReceiverBindingConstants.DEWPOINT), "Number:Temperature")
302 .withKind(ChannelKind.STATE).build(),
304 .create(new ChannelUID(testThingUID, HUMIDITY_GROUP,
305 WundergroundUpdateReceiverBindingConstants.HUMIDITY), "Number:Dimensionless")
306 .withKind(ChannelKind.STATE).build(),
308 .create(new ChannelUID(testThingUID, POLLUTION_GROUP,
309 WundergroundUpdateReceiverBindingConstants.AQ_NOX), "Number:Dimensionless")
310 .withKind(ChannelKind.STATE).build(),
312 .create(new ChannelUID(testThingUID, METADATA_GROUP,
313 WundergroundUpdateReceiverBindingConstants.LAST_QUERY_TRIGGER), "StringType")
314 .withKind(ChannelKind.TRIGGER).build());
316 Configuration config = new Configuration(Map.of("stationId", REQ_STATION_ID));
317 Thing testThing = ThingBuilder
318 .create(WundergroundUpdateReceiverBindingConstants.THING_TYPE_UPDATE_RECEIVER, testThingUID)
319 .withChannels(channels).withConfiguration(config).build();
320 ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
321 WundergroundUpdateReceiverHandler handler = new WundergroundUpdateReceiverHandler(testThing, sut,
322 discoveryService, new WundergroundUpdateReceiverUnknownChannelTypeProvider(), channelTypeRegistry,
323 managedThingProvider);
324 handler.setCallback(callback);
325 handler.initialize();
327 HttpChannel httpChannel = mock(HttpChannel.class);
328 MetaData.Request request = new MetaData.Request("GET",
329 new HttpURI("http://localhost" + WundergroundUpdateReceiverServlet.SERVLET_URL + "?" + queryString),
330 HttpVersion.HTTP_1_1, new HttpFields());
331 Request req = new Request(httpChannel, null);
332 req.setMetaData(request);
335 sut.doGet(req, mock(HttpServletResponse.class, Answers.RETURNS_MOCKS));
338 verify(callback).stateUpdated(
339 new ChannelUID(TEST_THING_UID, METADATA_GROUP, WundergroundUpdateReceiverBindingConstants.DATEUTC),
340 StringType.valueOf("2021-02-07 14:04:03"));
341 verify(callback).stateUpdated(
342 new ChannelUID(TEST_THING_UID, METADATA_GROUP, WundergroundUpdateReceiverBindingConstants.LOW_BATTERY),
344 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
345 WundergroundUpdateReceiverBindingConstants.REALTIME_FREQUENCY), new DecimalType(5));
346 verify(callback).stateUpdated(
347 new ChannelUID(TEST_THING_UID, WIND_GROUP, WundergroundUpdateReceiverBindingConstants.WIND_DIRECTION),
348 new QuantityType<>(14, Units.DEGREE_ANGLE));
349 verify(callback).stateUpdated(
350 new ChannelUID(TEST_THING_UID, WIND_GROUP, WundergroundUpdateReceiverBindingConstants.WIND_SPEED),
351 new QuantityType<>(1.34, ImperialUnits.MILES_PER_HOUR));
352 verify(callback).stateUpdated(
353 new ChannelUID(TEST_THING_UID, WIND_GROUP, WundergroundUpdateReceiverBindingConstants.GUST_SPEED),
354 new QuantityType<>(2.46, ImperialUnits.MILES_PER_HOUR));
355 verify(callback).stateUpdated(
356 new ChannelUID(TEST_THING_UID, TEMPERATURE_GROUP,
357 WundergroundUpdateReceiverBindingConstants.TEMPERATURE),
358 new QuantityType<>(26.1, ImperialUnits.FAHRENHEIT));
359 verify(callback).stateUpdated(
360 new ChannelUID(TEST_THING_UID, RAIN_GROUP, WundergroundUpdateReceiverBindingConstants.RAIN_IN),
361 new QuantityType<>(0, ImperialUnits.INCH));
362 verify(callback).stateUpdated(
363 new ChannelUID(TEST_THING_UID, SUNLIGHT_GROUP,
364 WundergroundUpdateReceiverBindingConstants.SOLAR_RADIATION),
365 new QuantityType<>(42.24, Units.IRRADIANCE));
366 verify(callback).stateUpdated(
367 new ChannelUID(TEST_THING_UID, SUNLIGHT_GROUP, WundergroundUpdateReceiverBindingConstants.UV),
369 verify(callback).stateUpdated(
370 new ChannelUID(TEST_THING_UID, PRESSURE_GROUP, WundergroundUpdateReceiverBindingConstants.BAROM_IN),
371 new QuantityType<>(30.39, ImperialUnits.INCH_OF_MERCURY));
372 verify(callback).stateUpdated(
373 new ChannelUID(TEST_THING_UID, HUMIDITY_GROUP, WundergroundUpdateReceiverBindingConstants.DEWPOINT),
374 new QuantityType<>(18.9, ImperialUnits.FAHRENHEIT));
375 verify(callback).stateUpdated(
376 new ChannelUID(TEST_THING_UID, HUMIDITY_GROUP, WundergroundUpdateReceiverBindingConstants.HUMIDITY),
377 new QuantityType<>(74, Units.PERCENT));
378 verify(callback).stateUpdated(
379 new ChannelUID(TEST_THING_UID, POLLUTION_GROUP, WundergroundUpdateReceiverBindingConstants.AQ_NOX),
380 new QuantityType<>(21, Units.PARTS_PER_BILLION));
381 verify(callback, never()).stateUpdated(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
382 WundergroundUpdateReceiverBindingConstants.SOFTWARE_TYPE), StringType.valueOf("WH2600 V2.2.8"));
383 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
384 WundergroundUpdateReceiverBindingConstants.LAST_QUERY_STATE), StringType.valueOf(queryString));
385 verify(callback).stateUpdated(eq(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
386 WundergroundUpdateReceiverBindingConstants.LAST_RECEIVED)), any(DateTimeType.class));
387 verify(callback).channelTriggered(testThing, new ChannelUID(TEST_THING_UID, METADATA_GROUP,
388 WundergroundUpdateReceiverBindingConstants.LAST_QUERY_TRIGGER), queryString);
392 void aGetRequestWithIndexedParametresAreCorrectlyParsed() throws IOException {
394 ThingUID testThingUID = new ThingUID(WundergroundUpdateReceiverBindingConstants.THING_TYPE_UPDATE_RECEIVER,
396 final String queryString = "ID=dfggger&PASSWORD=XXXXXX&temp1f=26.1&humidity=74&temp2f=25.1&lowbatt=1&soilmoisture1=78&soilmoisture2=73&dateutc=2021-02-07%2014:04:03&softwaretype=WH2600%20V2.2.8&action=updateraw&realtime=1&rtfreq=5";
397 WundergroundUpdateReceiverServlet sut = new WundergroundUpdateReceiverServlet(discoveryService);
398 List<Channel> channels = List.of(
400 .create(new ChannelUID(testThingUID, METADATA_GROUP,
401 WundergroundUpdateReceiverBindingConstants.DATEUTC), "String")
402 .withKind(ChannelKind.STATE).build(),
404 .create(new ChannelUID(testThingUID, METADATA_GROUP,
405 WundergroundUpdateReceiverBindingConstants.REALTIME_FREQUENCY), "Number")
406 .withKind(ChannelKind.STATE).build(),
408 .create(new ChannelUID(testThingUID, METADATA_GROUP,
409 WundergroundUpdateReceiverBindingConstants.LOW_BATTERY), "Switch")
410 .withKind(ChannelKind.STATE).build(),
411 ChannelBuilder.create(new ChannelUID(testThingUID, TEMPERATURE_GROUP, "temp1f"), "Number:Temperature")
412 .withKind(ChannelKind.STATE).build(),
413 ChannelBuilder.create(new ChannelUID(testThingUID, TEMPERATURE_GROUP, "temp2f"), "Number:Temperature")
414 .withKind(ChannelKind.STATE).build(),
416 .create(new ChannelUID(testThingUID, HUMIDITY_GROUP, "soilmoisture1"), "Number:Dimensionless")
417 .withKind(ChannelKind.STATE).build(),
419 .create(new ChannelUID(testThingUID, HUMIDITY_GROUP, "soilmoisture2"), "Number:Dimensionless")
420 .withKind(ChannelKind.STATE).build(),
422 .create(new ChannelUID(testThingUID, HUMIDITY_GROUP,
423 WundergroundUpdateReceiverBindingConstants.HUMIDITY), "Number:Dimensionless")
424 .withKind(ChannelKind.STATE).build(),
426 .create(new ChannelUID(testThingUID, METADATA_GROUP,
427 WundergroundUpdateReceiverBindingConstants.LAST_QUERY_TRIGGER), "StringType")
428 .withKind(ChannelKind.TRIGGER).build());
430 Configuration config = new Configuration(Map.of("stationId", REQ_STATION_ID));
431 Thing testThing = ThingBuilder
432 .create(WundergroundUpdateReceiverBindingConstants.THING_TYPE_UPDATE_RECEIVER, testThingUID)
433 .withChannels(channels).withConfiguration(config).build();
434 ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
435 WundergroundUpdateReceiverHandler handler = new WundergroundUpdateReceiverHandler(testThing, sut,
436 discoveryService, new WundergroundUpdateReceiverUnknownChannelTypeProvider(), channelTypeRegistry,
437 managedThingProvider);
438 handler.setCallback(callback);
439 handler.initialize();
441 HttpChannel httpChannel = mock(HttpChannel.class);
442 MetaData.Request request = new MetaData.Request("GET",
443 new HttpURI("http://localhost" + WundergroundUpdateReceiverServlet.SERVLET_URL + "?" + queryString),
444 HttpVersion.HTTP_1_1, new HttpFields());
445 Request req = new Request(httpChannel, null);
446 req.setMetaData(request);
449 sut.doGet(req, mock(HttpServletResponse.class, Answers.RETURNS_MOCKS));
452 verify(callback).stateUpdated(
453 new ChannelUID(TEST_THING_UID, METADATA_GROUP, WundergroundUpdateReceiverBindingConstants.DATEUTC),
454 StringType.valueOf("2021-02-07 14:04:03"));
455 verify(callback).stateUpdated(
456 new ChannelUID(TEST_THING_UID, METADATA_GROUP, WundergroundUpdateReceiverBindingConstants.LOW_BATTERY),
458 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
459 WundergroundUpdateReceiverBindingConstants.REALTIME_FREQUENCY), new DecimalType(5));
460 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, TEMPERATURE_GROUP, "temp1f"),
461 new QuantityType<>(26.1, ImperialUnits.FAHRENHEIT));
462 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, TEMPERATURE_GROUP, "temp2f"),
463 new QuantityType<>(25.1, ImperialUnits.FAHRENHEIT));
464 verify(callback).stateUpdated(
465 new ChannelUID(TEST_THING_UID, HUMIDITY_GROUP, WundergroundUpdateReceiverBindingConstants.HUMIDITY),
466 new QuantityType<>(74, Units.PERCENT));
467 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, HUMIDITY_GROUP, "soilmoisture1"),
468 new QuantityType<>(78, Units.PERCENT));
469 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, HUMIDITY_GROUP, "soilmoisture2"),
470 new QuantityType<>(73, Units.PERCENT));
471 verify(callback, never()).stateUpdated(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
472 WundergroundUpdateReceiverBindingConstants.SOFTWARE_TYPE), StringType.valueOf("WH2600 V2.2.8"));
473 verify(callback).stateUpdated(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
474 WundergroundUpdateReceiverBindingConstants.LAST_QUERY_STATE), StringType.valueOf(queryString));
475 verify(callback).stateUpdated(eq(new ChannelUID(TEST_THING_UID, METADATA_GROUP,
476 WundergroundUpdateReceiverBindingConstants.LAST_RECEIVED)), any(DateTimeType.class));
477 verify(callback).channelTriggered(testThing, new ChannelUID(TEST_THING_UID, METADATA_GROUP,
478 WundergroundUpdateReceiverBindingConstants.LAST_QUERY_TRIGGER), queryString);