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.mielecloud.internal.handler;
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.*;
20 import java.util.Collections;
21 import java.util.Objects;
22 import java.util.Optional;
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;
50 * @author Björn Lange - Initial contribution
53 public class MieleHandlerFactoryTest extends JavaOSGiTest {
54 private static final String DEVICE_IDENTIFIER = "000124430016";
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,
60 private static final ThingUID HOB_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_HOB,
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,
66 private static final ThingUID COFFEE_DEVICE_TYPE = new ThingUID(MieleCloudBindingConstants.THING_TYPE_COFFEE_SYSTEM,
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,
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);
80 private ThingRegistry thingRegistry;
82 private ThingRegistry getThingRegistry() {
83 assertNotNull(thingRegistry);
84 return Objects.requireNonNull(thingRegistry);
88 public void setUp() throws Exception {
89 registerVolatileStorageService();
90 thingRegistry = getService(ThingRegistry.class, ThingRegistry.class);
91 assertNotNull(thingRegistry, "Thing registry is missing");
93 // Ensure the MieleWebservice is not initialized.
94 MieleHandlerFactory factory = getService(ThingHandlerFactory.class, MieleHandlerFactory.class);
95 assertNotNull(factory);
97 // Assume an access token has already been stored
98 AccessTokenResponse accessTokenResponse = new AccessTokenResponse();
99 accessTokenResponse.setAccessToken(ACCESS_TOKEN);
101 OAuthClientService oAuthClientService = mock(OAuthClientService.class);
102 when(oAuthClientService.getAccessTokenResponse()).thenReturn(accessTokenResponse);
104 OAuthFactory oAuthFactory = mock(OAuthFactory.class);
105 when(oAuthFactory.getOAuthClientService(MieleCloudBindingIntegrationTestConstants.EMAIL))
106 .thenReturn(oAuthClientService);
108 OpenHabOAuthTokenRefresher tokenRefresher = getService(OAuthTokenRefresher.class,
109 OpenHabOAuthTokenRefresher.class);
110 assertNotNull(tokenRefresher);
111 setPrivate(Objects.requireNonNull(tokenRefresher), "oauthFactory", oAuthFactory);
115 public void testHandlerCanBeCreatedForGenesisBridge() throws Exception {
117 Bridge bridge = BridgeBuilder
118 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
119 MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
121 new Configuration(Collections.singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
122 MieleCloudBindingIntegrationTestConstants.EMAIL)))
123 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
124 assertNotNull(bridge);
126 getThingRegistry().add(bridge);
129 waitForAssert(() -> {
130 assertNotNull(bridge.getHandler());
131 assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
134 MieleBridgeHandler handler = (MieleBridgeHandler) bridge.getHandler();
135 assertNotNull(handler);
139 public void testWebserviceIsInitializedOnHandlerInitialization() throws Exception {
141 Bridge bridge = BridgeBuilder
142 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
143 MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
145 new Configuration(Collections.singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
146 MieleCloudBindingIntegrationTestConstants.EMAIL)))
147 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
148 assertNotNull(bridge);
150 getThingRegistry().add(bridge);
152 waitForAssert(() -> {
153 assertNotNull(bridge.getHandler());
154 assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
157 MieleBridgeHandler handler = (MieleBridgeHandler) bridge.getHandler();
158 assertNotNull(handler);
161 handler.initialize();
164 assertEquals(ACCESS_TOKEN,
165 handler.getThing().getProperties().get(MieleCloudBindingConstants.PROPERTY_ACCESS_TOKEN));
167 MieleWebservice webservice = getPrivate(handler, "webService");
168 assertNotNull(webservice);
169 Optional<String> accessToken = getPrivate(webservice, "accessToken");
170 assertEquals(Optional.of(ACCESS_TOKEN), accessToken);
173 private void verifyHandlerCreation(MieleWebservice webservice, Thing thing,
174 Class<? extends ThingHandler> expectedHandlerClass)
175 throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
176 getThingRegistry().add(thing);
179 waitForAssert(() -> {
180 ThingHandler handler = thing.getHandler();
181 assertNotNull(handler);
182 assertTrue(expectedHandlerClass.isAssignableFrom(handler.getClass()), "Handler type is wrong");
186 private void testHandlerCanBeCreatedForMieleDevice(ThingTypeUID thingTypeUid, ThingUID thingUid, String label,
187 Class<? extends ThingHandler> expectedHandlerClass, String thingTypeVersion)
188 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
190 MieleWebservice webservice = mock(MieleWebservice.class);
192 MieleHandlerFactory factory = getService(ThingHandlerFactory.class, MieleHandlerFactory.class);
193 assertNotNull(factory);
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();
201 assertNotNull(device);
202 verifyHandlerCreation(webservice, device, expectedHandlerClass);
206 public void testHandlerCanBeCreatedForGenesisBridgeWithEmptyConfiguration() throws Exception {
208 Bridge bridge = BridgeBuilder
209 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
210 MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
212 new Configuration(Collections.singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
213 MieleCloudBindingIntegrationTestConstants.EMAIL)))
214 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
215 assertNotNull(bridge);
217 getThingRegistry().add(bridge);
220 waitForAssert(() -> {
221 assertNotNull(bridge.getHandler());
222 assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
304 * Registers a volatile storage service.
307 protected void registerVolatileStorageService() {
308 registerService(new VolatileStorageService());