]> git.basschouten.com Git - openhab-addons.git/blob
503f04f63513b0a7a85af7510b5ffc2a9d3254ef
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.deutschebahn.internal;
14
15 import static org.mockito.ArgumentMatchers.*;
16 import static org.mockito.Mockito.*;
17
18 import java.util.ArrayList;
19 import java.util.Calendar;
20 import java.util.GregorianCalendar;
21 import java.util.List;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.junit.jupiter.api.Disabled;
25 import org.junit.jupiter.api.Test;
26 import org.openhab.binding.deutschebahn.internal.timetable.TimeproviderStub;
27 import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiFactory;
28 import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ApiStub;
29 import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.HttpCallable;
30 import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1ImplTestHelper;
31 import org.openhab.binding.deutschebahn.internal.timetable.dto.Event;
32 import org.openhab.binding.deutschebahn.internal.timetable.dto.Timetable;
33 import org.openhab.binding.deutschebahn.internal.timetable.dto.TimetableStop;
34 import org.openhab.core.config.core.Configuration;
35 import org.openhab.core.thing.Bridge;
36 import org.openhab.core.thing.Channel;
37 import org.openhab.core.thing.Thing;
38 import org.openhab.core.thing.ThingStatus;
39 import org.openhab.core.thing.ThingUID;
40 import org.openhab.core.thing.binding.ThingHandlerCallback;
41 import org.openhab.core.types.State;
42 import org.openhab.core.types.UnDefType;
43
44 /**
45  * Tests for {@link DeutscheBahnTimetableHandler}.
46  *
47  * @author Sönke Küper - initial contribution.
48  */
49 @NonNullByDefault
50 @Disabled("https://github.com/openhab/openhab-addons/issues/12235")
51 public class DeutscheBahnTimetableHandlerTest implements TimetablesV1ImplTestHelper {
52
53     private static Configuration createConfig() {
54         final Configuration config = new Configuration();
55         config.put("accessToken", "letMeIn");
56         config.put("evaNo", "8000226");
57         config.put("trainFilter", "all");
58         return config;
59     }
60
61     private static Bridge mockBridge() {
62         final Bridge bridge = mock(Bridge.class);
63         when(bridge.getUID()).thenReturn(new ThingUID(DeutscheBahnBindingConstants.TIMETABLE_TYPE, "timetable"));
64         when(bridge.getConfiguration()).thenReturn(createConfig());
65
66         final List<Thing> things = new ArrayList<>();
67         things.add(DeutscheBahnTrainHandlerTest.mockThing(1));
68         things.add(DeutscheBahnTrainHandlerTest.mockThing(2));
69         things.add(DeutscheBahnTrainHandlerTest.mockThing(3));
70         when(things.get(0).getHandler()).thenReturn(mock(DeutscheBahnTrainHandler.class));
71         when(things.get(1).getHandler()).thenReturn(mock(DeutscheBahnTrainHandler.class));
72         when(things.get(2).getHandler()).thenReturn(mock(DeutscheBahnTrainHandler.class));
73
74         when(bridge.getThings()).thenReturn(things);
75
76         return bridge;
77     }
78
79     private DeutscheBahnTimetableHandler createAndInitHandler(final ThingHandlerCallback callback, final Bridge bridge)
80             throws Exception {
81         return createAndInitHandler(callback, bridge, createApiWithTestdata().getApiFactory());
82     }
83
84     private DeutscheBahnTimetableHandler createAndInitHandler( //
85             final ThingHandlerCallback callback, //
86             final Bridge bridge, //
87             final TimetablesV1ApiFactory apiFactory) throws Exception { //
88         final TimeproviderStub timeProvider = new TimeproviderStub();
89         timeProvider.time = new GregorianCalendar(2021, Calendar.AUGUST, 16, 9, 30);
90
91         final DeutscheBahnTimetableHandler handler = new DeutscheBahnTimetableHandler(bridge, apiFactory, timeProvider);
92         handler.setCallback(callback);
93         handler.initialize();
94         return handler;
95     }
96
97     @Test
98     public void testUpdateChannels() throws Exception {
99         final Bridge bridge = mockBridge();
100         final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
101
102         final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge);
103
104         try {
105             verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
106             verify(callback, timeout(1000)).statusUpdated(eq(bridge),
107                     argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE)));
108
109             verifyThingUpdated(bridge, 0, "-5296516961807204721-2108160906-5");
110             verifyThingUpdated(bridge, 1, "-8364795265993682073-2108160911-6");
111             verifyThingUpdated(bridge, 2, "-2949440726131702047-2108160858-10");
112         } finally {
113             handler.dispose();
114         }
115     }
116
117     private void verifyThingUpdated(final Bridge bridge, int offset, String stopId) {
118         final Thing train = bridge.getThings().get(offset);
119         final DeutscheBahnTrainHandler childHandler = (DeutscheBahnTrainHandler) train.getHandler();
120         verify(childHandler, timeout(1000))
121                 .updateChannels(argThat((TimetableStop stop) -> stop.getId().equals(stopId)));
122     }
123
124     @Test
125     public void testUpdateTrainsToUndefinedIfNoDataWasProvided() throws Exception {
126         final Bridge bridge = mockBridge();
127         final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
128
129         final TimetablesV1ApiStub stubWithError = TimetablesV1ApiStub.createWithException();
130
131         final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge,
132                 (String authToken, HttpCallable httpCallable) -> stubWithError);
133
134         try {
135             verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
136             verify(callback, timeout(1000)).statusUpdated(eq(bridge),
137                     argThat(arg -> arg.getStatus().equals(ThingStatus.OFFLINE)));
138
139             verifyChannelsUpdatedToUndef(bridge, 0, callback, UnDefType.UNDEF);
140             verifyChannelsUpdatedToUndef(bridge, 1, callback, UnDefType.UNDEF);
141             verifyChannelsUpdatedToUndef(bridge, 2, callback, UnDefType.UNDEF);
142
143         } finally {
144             handler.dispose();
145         }
146     }
147
148     private static void verifyChannelsUpdatedToUndef(Bridge bridge, int offset, ThingHandlerCallback callback,
149             State expectedState) {
150         final Thing thing = bridge.getThings().get(offset);
151         for (Channel channel : thing.getChannels()) {
152             verify(callback).stateUpdated(eq(channel.getUID()), eq(expectedState));
153         }
154     }
155
156     @Test
157     public void testUpdateTrainsToUndefinedIfNotEnoughDataWasProvided() throws Exception {
158         final Bridge bridge = mockBridge();
159         final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
160
161         // Bridge contains 3 trains, but Timetable contains only 1 items, so two trains has to be updated to undef
162         // value.
163         final Timetable timetable = new Timetable();
164         TimetableStop stop01 = new TimetableStop();
165         stop01.setId("stop01id");
166         Event dp = new Event();
167         dp.setPt("2108161000");
168         stop01.setDp(dp);
169         timetable.getS().add(stop01);
170
171         final TimetablesV1ApiStub stubWithData = TimetablesV1ApiStub.createWithResult(timetable);
172
173         final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge,
174                 (String authToken, HttpCallable httpCallable) -> stubWithData);
175
176         try {
177             verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
178             verify(callback, timeout(1000)).statusUpdated(eq(bridge),
179                     argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE)));
180
181             verifyThingUpdated(bridge, 0, stop01.getId());
182             verifyChannelsUpdatedToUndef(bridge, 1, callback, UnDefType.UNDEF);
183             verifyChannelsUpdatedToUndef(bridge, 2, callback, UnDefType.UNDEF);
184
185         } finally {
186             handler.dispose();
187         }
188     }
189 }