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