]> git.basschouten.com Git - openhab-addons.git/blob
ac7ed386a7451cab9940a2cd58d3b4e79c6a2a80
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.mielecloud.internal.handler;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.Mockito.*;
17 import static org.openhab.binding.mielecloud.internal.util.MieleCloudBindingIntegrationTestConstants.*;
18 import static org.openhab.binding.mielecloud.internal.util.ReflectionUtil.*;
19
20 import java.util.Collections;
21 import java.util.Objects;
22 import java.util.Optional;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.Test;
28 import org.openhab.binding.mielecloud.internal.MieleCloudBindingConstants;
29 import org.openhab.binding.mielecloud.internal.auth.OAuthTokenRefresher;
30 import org.openhab.binding.mielecloud.internal.auth.OpenHabOAuthTokenRefresher;
31 import org.openhab.binding.mielecloud.internal.util.MieleCloudBindingIntegrationTestConstants;
32 import org.openhab.binding.mielecloud.internal.webservice.MieleWebservice;
33 import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
34 import org.openhab.core.auth.client.oauth2.OAuthClientService;
35 import org.openhab.core.auth.client.oauth2.OAuthFactory;
36 import org.openhab.core.config.core.Configuration;
37 import org.openhab.core.test.java.JavaOSGiTest;
38 import org.openhab.core.test.storage.VolatileStorageService;
39 import org.openhab.core.thing.Bridge;
40 import org.openhab.core.thing.Thing;
41 import org.openhab.core.thing.ThingRegistry;
42 import org.openhab.core.thing.ThingTypeUID;
43 import org.openhab.core.thing.ThingUID;
44 import org.openhab.core.thing.binding.ThingHandler;
45 import org.openhab.core.thing.binding.ThingHandlerFactory;
46 import org.openhab.core.thing.binding.builder.BridgeBuilder;
47 import org.openhab.core.thing.binding.builder.ThingBuilder;
48
49 /**
50  * @author Björn Lange - Initial contribution
51  */
52 @NonNullByDefault
53 public class MieleHandlerFactoryTest extends JavaOSGiTest {
54     private static final String DEVICE_IDENTIFIER = "000124430016";
55
56     private static final ThingUID WASHING_MACHINE_TYPE = new ThingUID(
57             MieleCloudBindingConstants.THING_TYPE_WASHING_MACHINE, DEVICE_IDENTIFIER);
58     private static final ThingUID OVEN_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_OVEN,
59             DEVICE_IDENTIFIER);
60     private static final ThingUID HOB_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_HOB,
61             DEVICE_IDENTIFIER);
62     private static final ThingUID FRIDGE_FREEZER_DEVICE_TYPE = new ThingUID(
63             MieleCloudBindingConstants.THING_TYPE_FRIDGE_FREEZER, DEVICE_IDENTIFIER);
64     private static final ThingUID HOOD_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_HOOD,
65             DEVICE_IDENTIFIER);
66     private static final ThingUID COFFEE_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_COFFEE_SYSTEM,
67             DEVICE_IDENTIFIER);
68     private static final ThingUID WINE_STORAGE_DEVICE_TYPE = new ThingUID(
69             MieleCloudBindingConstants.THING_TYPE_WINE_STORAGE, DEVICE_IDENTIFIER);
70     private static final ThingUID DRYER_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_DRYER,
71             DEVICE_IDENTIFIER);
72     private static final ThingUID DISHWASHER_DEVICE_TYPE = new ThingUID(
73             MieleCloudBindingConstants.THING_TYPE_DISHWASHER, DEVICE_IDENTIFIER);
74     private static final ThingUID DISH_WARMER_DEVICE_TYPE = new ThingUID(
75             MieleCloudBindingConstants.THING_TYPE_DISH_WARMER, DEVICE_IDENTIFIER);
76     private static final ThingUID ROBOTIC_VACUUM_CLEANER_DEVICE_TYPE = new ThingUID(
77             MieleCloudBindingConstants.THING_TYPE_ROBOTIC_VACUUM_CLEANER, DEVICE_IDENTIFIER);
78
79     @Nullable
80     private ThingRegistry thingRegistry;
81
82     private ThingRegistry getThingRegistry() {
83         assertNotNull(thingRegistry);
84         return Objects.requireNonNull(thingRegistry);
85     }
86
87     @BeforeEach
88     public void setUp() throws Exception {
89         registerVolatileStorageService();
90         thingRegistry = getService(ThingRegistry.class, ThingRegistry.class);
91         assertNotNull(thingRegistry, "Thing registry is missing");
92
93         // Ensure the MieleWebservice is not initialized.
94         MieleHandlerFactory factory = getService(ThingHandlerFactory.class, MieleHandlerFactory.class);
95         assertNotNull(factory);
96
97         // Assume an access token has already been stored
98         AccessTokenResponse accessTokenResponse = new AccessTokenResponse();
99         accessTokenResponse.setAccessToken(ACCESS_TOKEN);
100
101         OAuthClientService oAuthClientService = mock(OAuthClientService.class);
102         when(oAuthClientService.getAccessTokenResponse()).thenReturn(accessTokenResponse);
103
104         OAuthFactory oAuthFactory = mock(OAuthFactory.class);
105         when(oAuthFactory.getOAuthClientService(MieleCloudBindingIntegrationTestConstants.EMAIL))
106                 .thenReturn(oAuthClientService);
107
108         OpenHabOAuthTokenRefresher tokenRefresher = getService(OAuthTokenRefresher.class,
109                 OpenHabOAuthTokenRefresher.class);
110         assertNotNull(tokenRefresher);
111         setPrivate(Objects.requireNonNull(tokenRefresher), "oauthFactory", oAuthFactory);
112     }
113
114     @Test
115     public void testHandlerCanBeCreatedForGenesisBridge() throws Exception {
116         // when:
117         Bridge bridge = BridgeBuilder
118                 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
119                         MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
120                 .withConfiguration(
121                         new Configuration(Collections.singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
122                                 MieleCloudBindingIntegrationTestConstants.EMAIL)))
123                 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
124         assertNotNull(bridge);
125
126         getThingRegistry().add(bridge);
127
128         // then:
129         waitForAssert(() -> {
130             assertNotNull(bridge.getHandler());
131             assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
132         });
133
134         MieleBridgeHandler handler = (MieleBridgeHandler) bridge.getHandler();
135         assertNotNull(handler);
136     }
137
138     @Test
139     public void testWebserviceIsInitializedOnHandlerInitialization() throws Exception {
140         // given:
141         Bridge bridge = BridgeBuilder
142                 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
143                         MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
144                 .withConfiguration(
145                         new Configuration(Collections.singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
146                                 MieleCloudBindingIntegrationTestConstants.EMAIL)))
147                 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
148         assertNotNull(bridge);
149
150         getThingRegistry().add(bridge);
151
152         waitForAssert(() -> {
153             assertNotNull(bridge.getHandler());
154             assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
155         });
156
157         MieleBridgeHandler handler = (MieleBridgeHandler) bridge.getHandler();
158         assertNotNull(handler);
159
160         // when:
161         handler.initialize();
162
163         // then:
164         assertEquals(ACCESS_TOKEN,
165                 handler.getThing().getProperties().get(MieleCloudBindingConstants.PROPERTY_ACCESS_TOKEN));
166
167         MieleWebservice webservice = getPrivate(handler, "webService");
168         assertNotNull(webservice);
169         Optional<String> accessToken = getPrivate(webservice, "accessToken");
170         assertEquals(Optional.of(ACCESS_TOKEN), accessToken);
171     }
172
173     private void verifyHandlerCreation(MieleWebservice webservice, Thing thing,
174             Class<? extends ThingHandler> expectedHandlerClass)
175             throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
176         getThingRegistry().add(thing);
177
178         // then:
179         waitForAssert(() -> {
180             ThingHandler handler = thing.getHandler();
181             assertNotNull(handler);
182             assertTrue(expectedHandlerClass.isAssignableFrom(handler.getClass()), "Handler type is wrong");
183         });
184     }
185
186     private void testHandlerCanBeCreatedForMieleDevice(ThingTypeUID thingTypeUid, ThingUID thingUid, String label,
187             Class<? extends ThingHandler> expectedHandlerClass, String thingTypeVersion)
188             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
189         // given:
190         MieleWebservice webservice = mock(MieleWebservice.class);
191
192         MieleHandlerFactory factory = getService(ThingHandlerFactory.class, MieleHandlerFactory.class);
193         assertNotNull(factory);
194
195         // when:
196         Thing device = ThingBuilder.create(thingTypeUid, thingUid)
197                 .withConfiguration(new Configuration(Collections
198                         .singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_DEVICE_IDENTIFIER, DEVICE_IDENTIFIER)))
199                 .withLabel(label).withProperty("thingTypeVersion", thingTypeVersion).build();
200
201         assertNotNull(device);
202         verifyHandlerCreation(webservice, device, expectedHandlerClass);
203     }
204
205     @Test
206     public void testHandlerCanBeCreatedForGenesisBridgeWithEmptyConfiguration() throws Exception {
207         // when:
208         Bridge bridge = BridgeBuilder
209                 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
210                         MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
211                 .withConfiguration(
212                         new Configuration(Collections.singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
213                                 MieleCloudBindingIntegrationTestConstants.EMAIL)))
214                 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
215         assertNotNull(bridge);
216
217         getThingRegistry().add(bridge);
218
219         // then:
220         waitForAssert(() -> {
221             assertNotNull(bridge.getHandler());
222             assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
223         });
224     }
225
226     @Test
227     public void testHandlerCanBeCreatedForWashingDevice()
228             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
229         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_WASHING_MACHINE,
230                 WASHING_MACHINE_TYPE, "DA-6996", WashingDeviceThingHandler.class, "1");
231     }
232
233     @Test
234     public void testHandlerCanBeCreatedForOvenDevice()
235             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
236         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_OVEN, OVEN_DEVICE_TYPE, "OV-6887",
237                 OvenDeviceThingHandler.class, "0");
238     }
239
240     @Test
241     public void testHandlerCanBeCreatedForHobDevice()
242             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
243         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_HOB, HOB_DEVICE_TYPE, "HB-3887",
244                 HobDeviceThingHandler.class, "0");
245     }
246
247     @Test
248     public void testHandlerCanBeCreatedForFridgeFreezerDevice()
249             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
250         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_FRIDGE_FREEZER,
251                 FRIDGE_FREEZER_DEVICE_TYPE, "CD-6097", CoolingDeviceThingHandler.class, "0");
252     }
253
254     @Test
255     public void testHandlerCanBeCreatedForHoodDevice()
256             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
257         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_HOOD, HOOD_DEVICE_TYPE, "HD-2097",
258                 HoodDeviceThingHandler.class, "0");
259     }
260
261     @Test
262     public void testHandlerCanBeCreatedForCoffeeDevice()
263             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
264         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_COFFEE_SYSTEM, COFFEE_DEVICE_TYPE,
265                 "DA-6997", CoffeeSystemThingHandler.class, "0");
266     }
267
268     @Test
269     public void testHandlerCanBeCreatedForWineStorageDevice()
270             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
271         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_WINE_STORAGE,
272                 WINE_STORAGE_DEVICE_TYPE, "WS-6907", WineStorageDeviceThingHandler.class, "0");
273     }
274
275     @Test
276     public void testHandlerCanBeCreatedForDryerDevice()
277             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
278         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DRYER, DRYER_DEVICE_TYPE, "DR-0907",
279                 DryerDeviceThingHandler.class, "1");
280     }
281
282     @Test
283     public void testHandlerCanBeCreatedForDishwasherDevice()
284             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
285         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DISHWASHER, DISHWASHER_DEVICE_TYPE,
286                 "DR-0907", DishwasherDeviceThingHandler.class, "1");
287     }
288
289     @Test
290     public void testHandlerCanBeCreatedForDishWarmerDevice()
291             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
292         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DISH_WARMER,
293                 DISH_WARMER_DEVICE_TYPE, "DW-0907", DishWarmerDeviceThingHandler.class, "0");
294     }
295
296     @Test
297     public void testHandlerCanBeCreatedForRoboticVacuumCleanerDevice()
298             throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
299         testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_ROBOTIC_VACUUM_CLEANER,
300                 ROBOTIC_VACUUM_CLEANER_DEVICE_TYPE, "RVC-0907", RoboticVacuumCleanerDeviceThingHandler.class, "0");
301     }
302
303     /**
304      * Registers a volatile storage service.
305      */
306     @Override
307     protected void registerVolatileStorageService() {
308         registerService(new VolatileStorageService());
309     }
310 }