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.*;
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)
120 .withConfiguration(new Configuration(Map.of(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
121 MieleCloudBindingIntegrationTestConstants.EMAIL)))
122 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
123 assertNotNull(bridge);
125 getThingRegistry().add(bridge);
128 waitForAssert(() -> {
129 assertNotNull(bridge.getHandler());
130 assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
133 MieleBridgeHandler handler = (MieleBridgeHandler) bridge.getHandler();
134 assertNotNull(handler);
138 public void testWebserviceIsInitializedOnHandlerInitialization() throws Exception {
140 Bridge bridge = BridgeBuilder
141 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
142 MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
143 .withConfiguration(new Configuration(Map.of(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
144 MieleCloudBindingIntegrationTestConstants.EMAIL)))
145 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
146 assertNotNull(bridge);
148 getThingRegistry().add(bridge);
150 waitForAssert(() -> {
151 assertNotNull(bridge.getHandler());
152 assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
155 MieleBridgeHandler handler = (MieleBridgeHandler) bridge.getHandler();
156 assertNotNull(handler);
159 handler.initialize();
162 assertEquals(ACCESS_TOKEN,
163 handler.getThing().getProperties().get(MieleCloudBindingConstants.PROPERTY_ACCESS_TOKEN));
165 MieleWebservice webservice = getPrivate(handler, "webService");
166 assertNotNull(webservice);
167 Optional<String> accessToken = getPrivate(webservice, "accessToken");
168 assertEquals(Optional.of(ACCESS_TOKEN), accessToken);
171 private void verifyHandlerCreation(MieleWebservice webservice, Thing thing,
172 Class<? extends ThingHandler> expectedHandlerClass)
173 throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
174 getThingRegistry().add(thing);
177 waitForAssert(() -> {
178 ThingHandler handler = thing.getHandler();
179 assertNotNull(handler);
180 assertTrue(expectedHandlerClass.isAssignableFrom(handler.getClass()), "Handler type is wrong");
184 private void testHandlerCanBeCreatedForMieleDevice(ThingTypeUID thingTypeUid, ThingUID thingUid, String label,
185 Class<? extends ThingHandler> expectedHandlerClass, String thingTypeVersion)
186 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
188 MieleWebservice webservice = mock(MieleWebservice.class);
190 MieleHandlerFactory factory = getService(ThingHandlerFactory.class, MieleHandlerFactory.class);
191 assertNotNull(factory);
194 Thing device = ThingBuilder.create(thingTypeUid, thingUid)
195 .withConfiguration(new Configuration(
196 Map.of(MieleCloudBindingConstants.CONFIG_PARAM_DEVICE_IDENTIFIER, DEVICE_IDENTIFIER)))
197 .withLabel(label).withProperty("thingTypeVersion", thingTypeVersion).build();
199 assertNotNull(device);
200 verifyHandlerCreation(webservice, device, expectedHandlerClass);
204 public void testHandlerCanBeCreatedForGenesisBridgeWithEmptyConfiguration() throws Exception {
206 Bridge bridge = BridgeBuilder
207 .create(MieleCloudBindingConstants.THING_TYPE_BRIDGE,
208 MieleCloudBindingIntegrationTestConstants.BRIDGE_THING_UID)
209 .withConfiguration(new Configuration(Map.of(MieleCloudBindingConstants.CONFIG_PARAM_EMAIL,
210 MieleCloudBindingIntegrationTestConstants.EMAIL)))
211 .withLabel(MIELE_CLOUD_ACCOUNT_LABEL).build();
212 assertNotNull(bridge);
214 getThingRegistry().add(bridge);
217 waitForAssert(() -> {
218 assertNotNull(bridge.getHandler());
219 assertTrue(bridge.getHandler() instanceof MieleBridgeHandler, "Handler type is wrong");
224 public void testHandlerCanBeCreatedForWashingDevice()
225 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
226 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_WASHING_MACHINE,
227 WASHING_MACHINE_TYPE, "DA-6996", WashingDeviceThingHandler.class, "1");
231 public void testHandlerCanBeCreatedForOvenDevice()
232 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
233 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_OVEN, OVEN_DEVICE_TYPE, "OV-6887",
234 OvenDeviceThingHandler.class, "0");
238 public void testHandlerCanBeCreatedForHobDevice()
239 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
240 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_HOB, HOB_DEVICE_TYPE, "HB-3887",
241 HobDeviceThingHandler.class, "0");
245 public void testHandlerCanBeCreatedForFridgeFreezerDevice()
246 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
247 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_FRIDGE_FREEZER,
248 FRIDGE_FREEZER_DEVICE_TYPE, "CD-6097", CoolingDeviceThingHandler.class, "0");
252 public void testHandlerCanBeCreatedForHoodDevice()
253 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
254 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_HOOD, HOOD_DEVICE_TYPE, "HD-2097",
255 HoodDeviceThingHandler.class, "0");
259 public void testHandlerCanBeCreatedForCoffeeDevice()
260 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
261 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_COFFEE_SYSTEM, COFFEE_DEVICE_TYPE,
262 "DA-6997", CoffeeSystemThingHandler.class, "0");
266 public void testHandlerCanBeCreatedForWineStorageDevice()
267 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
268 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_WINE_STORAGE,
269 WINE_STORAGE_DEVICE_TYPE, "WS-6907", WineStorageDeviceThingHandler.class, "0");
273 public void testHandlerCanBeCreatedForDryerDevice()
274 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
275 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DRYER, DRYER_DEVICE_TYPE, "DR-0907",
276 DryerDeviceThingHandler.class, "1");
280 public void testHandlerCanBeCreatedForDishwasherDevice()
281 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
282 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DISHWASHER, DISHWASHER_DEVICE_TYPE,
283 "DR-0907", DishwasherDeviceThingHandler.class, "1");
287 public void testHandlerCanBeCreatedForDishWarmerDevice()
288 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
289 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DISH_WARMER,
290 DISH_WARMER_DEVICE_TYPE, "DW-0907", DishWarmerDeviceThingHandler.class, "0");
294 public void testHandlerCanBeCreatedForRoboticVacuumCleanerDevice()
295 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
296 testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_ROBOTIC_VACUUM_CLEANER,
297 ROBOTIC_VACUUM_CLEANER_DEVICE_TYPE, "RVC-0907", RoboticVacuumCleanerDeviceThingHandler.class, "0");
301 * Registers a volatile storage service.
304 protected void registerVolatileStorageService() {
305 registerService(new VolatileStorageService());