]> git.basschouten.com Git - openhab-addons.git/blob
5a76b1deb60f1d6518dab9367227a21f4ebef15e
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.hue.internal.handler;
14
15 import static org.hamcrest.CoreMatchers.equalTo;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.junit.jupiter.api.Assertions.*;
18 import static org.openhab.binding.hue.internal.HueBindingConstants.*;
19 import static org.openhab.binding.hue.internal.config.HueBridgeConfig.HTTP;
20 import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
21
22 import java.io.IOException;
23 import java.lang.reflect.Field;
24 import java.util.concurrent.ScheduledExecutorService;
25
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.Test;
28 import org.openhab.binding.hue.internal.AbstractHueOSGiTestParent;
29 import org.openhab.binding.hue.internal.HueBridge;
30 import org.openhab.binding.hue.internal.HueConfigStatusMessage;
31 import org.openhab.binding.hue.internal.exceptions.ApiException;
32 import org.openhab.binding.hue.internal.exceptions.LinkButtonException;
33 import org.openhab.binding.hue.internal.exceptions.UnauthorizedException;
34 import org.openhab.core.common.ThreadPoolManager;
35 import org.openhab.core.config.core.Configuration;
36 import org.openhab.core.config.core.status.ConfigStatusMessage;
37 import org.openhab.core.thing.Bridge;
38 import org.openhab.core.thing.ThingRegistry;
39 import org.openhab.core.thing.ThingStatus;
40 import org.openhab.core.thing.ThingStatusDetail;
41 import org.openhab.core.thing.ThingTypeUID;
42 import org.openhab.core.thing.ThingUID;
43
44 /**
45  * Tests for {@link HueBridgeHandler}.
46  *
47  * @author Oliver Libutzki - Initial contribution
48  * @author Michael Grammling - Initial contribution
49  * @author Denis Dudnik - switched to internally integrated source of Jue library
50  */
51 public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
52
53     private final ThingTypeUID BRIDGE_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "bridge");
54     private static final String TEST_USER_NAME = "eshTestUser";
55     private static final String DUMMY_HOST = "1.2.3.4";
56
57     private ThingRegistry thingRegistry;
58
59     private ScheduledExecutorService scheduler;
60
61     @BeforeEach
62     public void setUp() {
63         registerVolatileStorageService();
64         thingRegistry = getService(ThingRegistry.class, ThingRegistry.class);
65         assertNotNull(thingRegistry);
66
67         scheduler = ThreadPoolManager.getScheduledPool("hueBridgeTest");
68     }
69
70     @Test
71     public void assertThatANewUserIsAddedToConfigIfNotExistingYet() {
72         Configuration configuration = new Configuration();
73         configuration.put(HOST, DUMMY_HOST);
74         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
75         Bridge bridge = createBridgeThing(configuration);
76
77         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
78         hueBridgeHandler.thingUpdated(bridge);
79
80         injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
81             @Override
82             public String link(String deviceType) throws IOException, ApiException {
83                 return TEST_USER_NAME;
84             }
85         });
86
87         hueBridgeHandler.onNotAuthenticated();
88
89         assertThat(bridge.getConfiguration().get(USER_NAME), equalTo(TEST_USER_NAME));
90     }
91
92     @Test
93     public void assertThatAnExistingUserIsUsedIfAuthenticationWasSuccessful() {
94         Configuration configuration = new Configuration();
95         configuration.put(HOST, DUMMY_HOST);
96         configuration.put(USER_NAME, TEST_USER_NAME);
97         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
98         Bridge bridge = createBridgeThing(configuration);
99
100         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
101         hueBridgeHandler.thingUpdated(bridge);
102
103         injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
104             @Override
105             public void authenticate(String userName) throws IOException, ApiException {
106             }
107         });
108
109         hueBridgeHandler.onNotAuthenticated();
110
111         assertThat(bridge.getConfiguration().get(USER_NAME), equalTo(TEST_USER_NAME));
112     }
113
114     @Test
115     public void assertCorrectStatusIfAuthenticationFailedForOldUser() {
116         Configuration configuration = new Configuration();
117         configuration.put(HOST, DUMMY_HOST);
118         configuration.put(USER_NAME, "notAuthenticatedUser");
119         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
120         Bridge bridge = createBridgeThing(configuration);
121
122         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
123         hueBridgeHandler.thingUpdated(bridge);
124
125         injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
126             @Override
127             public void authenticate(String userName) throws IOException, ApiException {
128                 throw new UnauthorizedException();
129             }
130         });
131
132         hueBridgeHandler.onNotAuthenticated();
133
134         assertEquals("notAuthenticatedUser", bridge.getConfiguration().get(USER_NAME));
135         assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
136         assertEquals(ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, bridge.getStatusInfo().getStatusDetail());
137     }
138
139     @Test
140     public void verifyStatusIfLinkButtonIsNotPressed() {
141         Configuration configuration = new Configuration();
142         configuration.put(HOST, DUMMY_HOST);
143         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
144         Bridge bridge = createBridgeThing(configuration);
145
146         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
147         hueBridgeHandler.thingUpdated(bridge);
148
149         injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
150             @Override
151             public String link(String deviceType) throws IOException, ApiException {
152                 throw new LinkButtonException();
153             }
154         });
155
156         hueBridgeHandler.onNotAuthenticated();
157
158         assertNull(bridge.getConfiguration().get(USER_NAME));
159         assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
160         assertEquals(ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, bridge.getStatusInfo().getStatusDetail());
161     }
162
163     @Test
164     public void verifyStatusIfNewUserCannotBeCreated() {
165         Configuration configuration = new Configuration();
166         configuration.put(HOST, DUMMY_HOST);
167         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
168         Bridge bridge = createBridgeThing(configuration);
169
170         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
171         hueBridgeHandler.thingUpdated(bridge);
172
173         injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
174             @Override
175             public String link(String deviceType) throws IOException, ApiException {
176                 throw new ApiException();
177             }
178         });
179
180         hueBridgeHandler.onNotAuthenticated();
181
182         assertNull(bridge.getConfiguration().get(USER_NAME));
183         assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
184         assertEquals(ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, bridge.getStatusInfo().getStatusDetail());
185     }
186
187     @Test
188     public void verifyOfflineIsSetWithoutBridgeOfflineStatus() {
189         Configuration configuration = new Configuration();
190         configuration.put(HOST, DUMMY_HOST);
191         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
192         Bridge bridge = createBridgeThing(configuration);
193
194         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
195         hueBridgeHandler.thingUpdated(bridge);
196
197         hueBridgeHandler.onConnectionLost();
198
199         assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
200         assertNotEquals(ThingStatusDetail.BRIDGE_OFFLINE, bridge.getStatusInfo().getStatusDetail());
201     }
202
203     @Test
204     public void assertThatAStatusConfigurationMessageForMissingBridgeIPIsProperlyReturnedIPIsNull() {
205         Configuration configuration = new Configuration();
206         configuration.put(HOST, null);
207         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
208
209         Bridge bridge = createBridgeThing(configuration);
210
211         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
212
213         ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST)
214                 .withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build();
215
216         waitForAssert(() -> assertEquals(expected, hueBridgeHandler.getConfigStatus().iterator().next()));
217     }
218
219     @Test
220     public void assertThatAStatusConfigurationMessageForMissingBridgeIPIsProperlyReturnedIPIsAnEmptyString() {
221         Configuration configuration = new Configuration();
222         configuration.put(HOST, "");
223         configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
224
225         Bridge bridge = createBridgeThing(configuration);
226
227         HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
228
229         ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST)
230                 .withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build();
231
232         waitForAssert(() -> assertEquals(expected, hueBridgeHandler.getConfigStatus().iterator().next()));
233     }
234
235     private Bridge createBridgeThing(Configuration configuration) {
236         Bridge bridge = (Bridge) thingRegistry.createThingOfType(BRIDGE_THING_TYPE_UID,
237                 new ThingUID(BRIDGE_THING_TYPE_UID, "testBridge"), null, "Bridge", configuration);
238
239         assertNotNull(bridge);
240         thingRegistry.add(bridge);
241         return bridge;
242     }
243
244     private void injectBridge(HueBridgeHandler hueBridgeHandler, HueBridge bridge) {
245         try {
246             Field hueBridgeField = hueBridgeHandler.getClass().getDeclaredField("hueBridge");
247             hueBridgeField.setAccessible(true);
248             hueBridgeField.set(hueBridgeHandler, bridge);
249         } catch (Exception e) {
250             throw new AssertionError(e);
251         }
252     }
253 }