added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
27
itests/org.openhab.binding.hue.tests/.classpath
Normal file
27
itests/org.openhab.binding.hue.tests/.classpath
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
itests/org.openhab.binding.hue.tests/.project
Normal file
23
itests/org.openhab.binding.hue.tests/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.hue.tests</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
itests/org.openhab.binding.hue.tests/NOTICE
Normal file
13
itests/org.openhab.binding.hue.tests/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
67
itests/org.openhab.binding.hue.tests/itest.bndrun
Normal file
67
itests/org.openhab.binding.hue.tests/itest.bndrun
Normal file
@@ -0,0 +1,67 @@
|
||||
-include: ../itest-common.bndrun
|
||||
|
||||
Bundle-SymbolicName: ${project.artifactId}
|
||||
Fragment-Host: org.openhab.binding.hue
|
||||
|
||||
-runrequires: \
|
||||
bnd.identity;id='org.openhab.binding.hue.tests',\
|
||||
bnd.identity;id='org.openhab.core.binding.xml',\
|
||||
bnd.identity;id='org.openhab.core.thing.xml'
|
||||
|
||||
#
|
||||
# done
|
||||
#
|
||||
-runbundles: \
|
||||
ch.qos.logback.core;version='[1.2.3,1.2.4)',\
|
||||
com.google.gson;version='[2.8.2,2.8.3)',\
|
||||
javax.measure.unit-api;version='[1.0.0,1.0.1)',\
|
||||
org.apache.commons.exec;version='[1.1.0,1.1.1)',\
|
||||
org.apache.commons.io;version='[2.2.0,2.2.1)',\
|
||||
org.apache.commons.lang;version='[2.6.0,2.6.1)',\
|
||||
org.apache.felix.configadmin;version='[1.9.8,1.9.9)',\
|
||||
org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
|
||||
org.apache.felix.scr;version='[2.1.10,2.1.11)',\
|
||||
org.apache.xbean.bundleutils;version='[4.12.0,4.12.1)',\
|
||||
org.apache.xbean.finder;version='[4.12.0,4.12.1)',\
|
||||
org.eclipse.equinox.event;version='[1.4.300,1.4.301)',\
|
||||
org.jupnp;version='[2.5.2,2.5.3)',\
|
||||
org.openhab.core;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.config.core;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.config.discovery;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.config.discovery.upnp;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.io.console;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.io.net;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.test;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.thing;version='[2.5.0,2.5.1)',\
|
||||
org.osgi.service.event;version='[1.4.0,1.4.1)',\
|
||||
osgi.enroute.hamcrest.wrapper;version='[1.3.0,1.3.1)',\
|
||||
osgi.enroute.junit.wrapper;version='[4.12.0,4.12.1)',\
|
||||
slf4j.api;version='[1.7.25,1.7.26)',\
|
||||
org.apache.servicemix.bundles.xstream;version='[1.4.7,1.4.8)',\
|
||||
org.openhab.core.binding.xml;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.config.xml;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.thing.xml;version='[2.5.0,2.5.1)',\
|
||||
org.apache.servicemix.specs.activation-api-1.1;version='[2.9.0,2.9.1)',\
|
||||
org.apache.servicemix.specs.jaxb-api-2.2;version='[2.9.0,2.9.1)',\
|
||||
org.apache.servicemix.specs.stax-api-1.2;version='[2.9.0,2.9.1)',\
|
||||
tec.uom.lib.uom-lib-common;version='[1.0.3,1.0.4)',\
|
||||
tec.uom.se;version='[1.0.10,1.0.11)',\
|
||||
org.apache.servicemix.bundles.jaxb-impl;version='[2.2.11,2.2.12)',\
|
||||
org.objectweb.asm;version='[7.1.0,7.1.1)',\
|
||||
org.objectweb.asm.commons;version='[7.1.0,7.1.1)',\
|
||||
org.objectweb.asm.tree;version='[7.1.0,7.1.1)',\
|
||||
org.eclipse.jetty.client;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.http;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.io;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.security;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.server;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.servlet;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.util;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.websocket.api;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.websocket.client;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.websocket.common;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.xml;version='[9.4.20,9.4.21)',\
|
||||
org.ops4j.pax.web.pax-web-api;version='[7.2.11,7.2.12)',\
|
||||
ch.qos.logback.classic;version='[1.2.3,1.2.4)',\
|
||||
org.openhab.binding.hue;version='[2.5.9,2.5.10)',\
|
||||
org.openhab.binding.hue.tests;version='[2.5.9,2.5.10)'
|
||||
25
itests/org.openhab.binding.hue.tests/pom.xml
Normal file
25
itests/org.openhab.binding.hue.tests/pom.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.itests</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.itests</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.hue.tests</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Integration Tests :: hue Binding Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.hue</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
25
itests/org.openhab.binding.hue.tests/pom.xml.versionsBackup
Normal file
25
itests/org.openhab.binding.hue.tests/pom.xml.versionsBackup
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.itests</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.itests</artifactId>
|
||||
<version>2.5.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.hue.tests</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Integration Tests :: hue Binding Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.hue</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hue.internal;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.test.java.JavaOSGiTest;
|
||||
|
||||
/**
|
||||
* @author Markus Rathgeb - migrated to plain Java test
|
||||
*/
|
||||
public class AbstractHueOSGiTestParent extends JavaOSGiTest {
|
||||
|
||||
/**
|
||||
* Gets the handler of a thing if it fits to a specific type.
|
||||
*
|
||||
* @param thing the thing
|
||||
* @param clazz type of thing handler
|
||||
* @return the thing handler
|
||||
*/
|
||||
protected <T extends ThingHandler> T getThingHandler(Thing thing, Class<T> clazz) {
|
||||
return waitForAssert(() -> {
|
||||
final ThingHandler tmp = thing.getHandler();
|
||||
if (clazz.isInstance(tmp)) {
|
||||
return clazz.cast(tmp);
|
||||
} else {
|
||||
assertNotNull(tmp);
|
||||
assertEquals(clazz, tmp.getClass());
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hue.internal;
|
||||
|
||||
import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.config.discovery.DiscoveryListener;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultFlag;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.hue.internal.discovery.HueLightDiscoveryService;
|
||||
import org.openhab.binding.hue.internal.handler.HueBridgeHandler;
|
||||
|
||||
/**
|
||||
* Tests for {@link HueLightDiscoveryService}.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Andre Fuechsel - added test 'assert start search is called()'
|
||||
* - modified tests after introducing the generic thing types
|
||||
* @author Denis Dudnik - switched to internally integrated source of Jue library
|
||||
* @author Markus Rathgeb - migrated to plain Java test
|
||||
*/
|
||||
public class HueLightDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent {
|
||||
|
||||
protected HueThingHandlerFactory hueThingHandlerFactory;
|
||||
protected DiscoveryListener discoveryListener;
|
||||
protected ThingRegistry thingRegistry;
|
||||
protected Bridge hueBridge;
|
||||
protected HueBridgeHandler hueBridgeHandler;
|
||||
protected HueLightDiscoveryService discoveryService;
|
||||
|
||||
protected final ThingTypeUID BRIDGE_THING_TYPE_UID = new ThingTypeUID("hue", "bridge");
|
||||
protected final ThingUID BRIDGE_THING_UID = new ThingUID(BRIDGE_THING_TYPE_UID, "testBridge");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
registerVolatileStorageService();
|
||||
|
||||
thingRegistry = getService(ThingRegistry.class, ThingRegistry.class);
|
||||
assertThat(thingRegistry, is(notNullValue()));
|
||||
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, "1.2.3.4");
|
||||
configuration.put(USER_NAME, "testUserName");
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
|
||||
hueBridge = (Bridge) thingRegistry.createThingOfType(BRIDGE_THING_TYPE_UID, BRIDGE_THING_UID, null, "Bridge",
|
||||
configuration);
|
||||
|
||||
assertThat(hueBridge, is(notNullValue()));
|
||||
thingRegistry.add(hueBridge);
|
||||
|
||||
hueBridgeHandler = getThingHandler(hueBridge, HueBridgeHandler.class);
|
||||
assertThat(hueBridgeHandler, is(notNullValue()));
|
||||
|
||||
discoveryService = getService(DiscoveryService.class, HueLightDiscoveryService.class);
|
||||
assertThat(discoveryService, is(notNullValue()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
thingRegistry.remove(BRIDGE_THING_UID);
|
||||
waitForAssert(() -> {
|
||||
assertNull(getService(DiscoveryService.class, HueLightDiscoveryService.class));
|
||||
});
|
||||
}
|
||||
|
||||
private void registerDiscoveryListener(DiscoveryListener discoveryListener) {
|
||||
unregisterCurrentDiscoveryListener();
|
||||
this.discoveryListener = discoveryListener;
|
||||
discoveryService.addDiscoveryListener(this.discoveryListener);
|
||||
}
|
||||
|
||||
private void unregisterCurrentDiscoveryListener() {
|
||||
if (this.discoveryListener != null) {
|
||||
discoveryService.removeDiscoveryListener(this.discoveryListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hueLightRegistration() {
|
||||
FullLight light = new FullLight();
|
||||
light.setId("1");
|
||||
light.setModelID("LCT001");
|
||||
light.setType("Extended color light");
|
||||
|
||||
AtomicReference<DiscoveryResult> resultWrapper = new AtomicReference<>();
|
||||
|
||||
registerDiscoveryListener(new DiscoveryListener() {
|
||||
@Override
|
||||
public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
|
||||
resultWrapper.set(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thingRemoved(DiscoveryService source, ThingUID thingUID) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ThingUID> removeOlderResults(DiscoveryService source, long timestamp,
|
||||
Collection<ThingTypeUID> thingTypeUIDs, ThingUID bridgeUID) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
discoveryService.addLightDiscovery(light);
|
||||
waitForAssert(() -> {
|
||||
assertTrue(resultWrapper.get() != null);
|
||||
});
|
||||
|
||||
final DiscoveryResult result = resultWrapper.get();
|
||||
assertThat(result.getFlag(), is(DiscoveryResultFlag.NEW));
|
||||
assertThat(result.getThingUID().toString(), is("hue:0210:testBridge:" + light.getId()));
|
||||
assertThat(result.getThingTypeUID(), is(THING_TYPE_EXTENDED_COLOR_LIGHT));
|
||||
assertThat(result.getBridgeUID(), is(hueBridge.getUID()));
|
||||
assertThat(result.getProperties().get(LIGHT_ID), is(light.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startSearchIsCalled() {
|
||||
final AtomicBoolean searchHasBeenTriggered = new AtomicBoolean(false);
|
||||
|
||||
MockedHttpClient mockedHttpClient = new MockedHttpClient() {
|
||||
|
||||
@Override
|
||||
public Result put(String address, String body) throws IOException {
|
||||
return new Result("", 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result get(String address) throws IOException {
|
||||
if (address.endsWith("testUserName")) {
|
||||
String body = "{\"lights\":{}}";
|
||||
return new Result(body, 200);
|
||||
} else if (address.endsWith("lights") || address.endsWith("sensors")) {
|
||||
String body = "{}";
|
||||
return new Result(body, 200);
|
||||
} else if (address.endsWith("testUserName/config")) {
|
||||
String body = "{ \"apiversion\": \"1.26.0\"}";
|
||||
return new Result(body, 200);
|
||||
} else {
|
||||
return new Result("", 404);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result post(String address, String body) throws IOException {
|
||||
if (address.endsWith("lights")) {
|
||||
String bodyReturn = "{\"success\": {\"/lights\": \"Searching for new devices\"}}";
|
||||
searchHasBeenTriggered.set(true);
|
||||
return new Result(bodyReturn, 200);
|
||||
} else {
|
||||
return new Result("", 404);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
installHttpClientMock(hueBridgeHandler, mockedHttpClient);
|
||||
|
||||
ThingStatusInfo online = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
|
||||
waitForAssert(() -> {
|
||||
assertThat(hueBridge.getStatusInfo(), is(online));
|
||||
});
|
||||
|
||||
discoveryService.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertTrue(searchHasBeenTriggered.get());
|
||||
});
|
||||
}
|
||||
|
||||
private void installHttpClientMock(HueBridgeHandler hueBridgeHandler, MockedHttpClient mockedHttpClient) {
|
||||
waitForAssert(() -> {
|
||||
try {
|
||||
// mock HttpClient
|
||||
final Field hueBridgeField = HueBridgeHandler.class.getDeclaredField("hueBridge");
|
||||
hueBridgeField.setAccessible(true);
|
||||
final Object hueBridgeValue = hueBridgeField.get(hueBridgeHandler);
|
||||
assertThat(hueBridgeValue, is(notNullValue()));
|
||||
|
||||
final Field httpClientField = HueBridge.class.getDeclaredField("http");
|
||||
httpClientField.setAccessible(true);
|
||||
httpClientField.set(hueBridgeValue, mockedHttpClient);
|
||||
|
||||
final Field usernameField = HueBridge.class.getDeclaredField("username");
|
||||
usernameField.setAccessible(true);
|
||||
usernameField.set(hueBridgeValue, hueBridgeHandler.getThing().getConfiguration().get(USER_NAME));
|
||||
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
Assert.fail("Reflection usage error");
|
||||
}
|
||||
});
|
||||
hueBridgeHandler.initialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hue.internal;
|
||||
|
||||
/**
|
||||
* @author Denis Dudnik - Initial contribution
|
||||
*/
|
||||
public class MockedHttpClient extends HttpClient {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hue.internal.discovery;
|
||||
|
||||
import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultFlag;
|
||||
import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.test.java.JavaOSGiTest;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.jupnp.model.ValidationException;
|
||||
import org.jupnp.model.meta.DeviceDetails;
|
||||
import org.jupnp.model.meta.ManufacturerDetails;
|
||||
import org.jupnp.model.meta.ModelDetails;
|
||||
import org.jupnp.model.meta.RemoteDevice;
|
||||
import org.jupnp.model.meta.RemoteDeviceIdentity;
|
||||
import org.jupnp.model.meta.RemoteService;
|
||||
import org.jupnp.model.types.DeviceType;
|
||||
import org.jupnp.model.types.UDN;
|
||||
|
||||
/**
|
||||
* Tests for {@link org.openhab.binding.hue.internal.discovery.HueBridgeDiscoveryParticipant}.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Thomas Höfer - Added representation
|
||||
* @author Markus Rathgeb - migrated to plain Java test
|
||||
*/
|
||||
public class HueBridgeDiscoveryParticipantOSGITest extends JavaOSGiTest {
|
||||
|
||||
UpnpDiscoveryParticipant discoveryParticipant;
|
||||
|
||||
RemoteDevice hueDevice;
|
||||
RemoteDevice otherDevice;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
discoveryParticipant = getService(UpnpDiscoveryParticipant.class, HueBridgeDiscoveryParticipant.class);
|
||||
assertThat(discoveryParticipant, is(notNullValue()));
|
||||
|
||||
try {
|
||||
final RemoteService remoteService = null;
|
||||
|
||||
hueDevice = new RemoteDevice(
|
||||
new RemoteDeviceIdentity(new UDN("123"), 60, new URL("http://hue"), null, null),
|
||||
new DeviceType("namespace", "type"),
|
||||
new DeviceDetails(new URL("http://1.2.3.4/"), "Hue Bridge", new ManufacturerDetails("Philips"),
|
||||
new ModelDetails("Philips hue bridge"), "serial123", "upc", null),
|
||||
remoteService);
|
||||
|
||||
otherDevice = new RemoteDevice(
|
||||
new RemoteDeviceIdentity(new UDN("567"), 60, new URL("http://acme"), null, null),
|
||||
new DeviceType("namespace", "type"), new DeviceDetails("Some Device",
|
||||
new ManufacturerDetails("Taiwan"), new ModelDetails("$%&/"), "serial567", "upc"),
|
||||
remoteService);
|
||||
} catch (final ValidationException | MalformedURLException ex) {
|
||||
Assert.fail("Internal test error.");
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctSupportedTypes() {
|
||||
assertThat(discoveryParticipant.getSupportedThingTypeUIDs().size(), is(1));
|
||||
assertThat(discoveryParticipant.getSupportedThingTypeUIDs().iterator().next(), is(THING_TYPE_BRIDGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctThingUID() {
|
||||
assertThat(discoveryParticipant.getThingUID(hueDevice), is(new ThingUID("hue:bridge:serial123")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validDiscoveryResult() {
|
||||
final DiscoveryResult result = discoveryParticipant.createResult(hueDevice);
|
||||
assertThat(result.getFlag(), is(DiscoveryResultFlag.NEW));
|
||||
assertThat(result.getThingUID(), is(new ThingUID("hue:bridge:serial123")));
|
||||
assertThat(result.getThingTypeUID(), is(THING_TYPE_BRIDGE));
|
||||
assertThat(result.getBridgeUID(), is(nullValue()));
|
||||
assertThat(result.getProperties().get(HOST), is("1.2.3.4"));
|
||||
assertThat(result.getProperties().get(PROPERTY_SERIAL_NUMBER), is("serial123"));
|
||||
assertThat(result.getRepresentationProperty(), is(PROPERTY_SERIAL_NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noThingUIDForUnknownDevice() {
|
||||
assertThat(discoveryParticipant.getThingUID(otherDevice), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noDiscoveryResultForUnknownDevice() {
|
||||
assertThat(discoveryParticipant.createResult(otherDevice), is(nullValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hue.internal.discovery;
|
||||
|
||||
import static org.openhab.core.config.discovery.inbox.InboxPredicates.forThingTypeUID;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.openhab.binding.hue.internal.HueBindingConstants.THING_TYPE_BRIDGE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.openhab.core.config.discovery.DiscoveryListener;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.config.discovery.inbox.Inbox;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.test.java.JavaOSGiTest;
|
||||
import org.openhab.core.test.storage.VolatileStorageService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Christoph Knauf - Initial contribution
|
||||
* @author Markus Rathgeb - migrated to plain Java test
|
||||
*/
|
||||
public class HueBridgeNupnpDiscoveryOSGITest extends JavaOSGiTest {
|
||||
|
||||
HueBridgeNupnpDiscovery sut;
|
||||
VolatileStorageService volatileStorageService = new VolatileStorageService();
|
||||
DiscoveryListener discoveryListener;
|
||||
Inbox inbox;
|
||||
|
||||
final ThingTypeUID BRIDGE_THING_TYPE_UID = new ThingTypeUID("hue", "bridge");
|
||||
final String ip1 = "192.168.31.17";
|
||||
final String ip2 = "192.168.30.28";
|
||||
final String sn1 = "00178820057f";
|
||||
final String sn2 = "001788141b41";
|
||||
final ThingUID BRIDGE_THING_UID_1 = new ThingUID(BRIDGE_THING_TYPE_UID, sn1);
|
||||
final ThingUID BRIDGE_THING_UID_2 = new ThingUID(BRIDGE_THING_TYPE_UID, sn2);
|
||||
final String validBridgeDiscoveryResult = "[{\"id\":\"001788fffe20057f\",\"internalipaddress\":" + ip1
|
||||
+ "},{\"id\":\"001788fffe141b41\",\"internalipaddress\":" + ip2 + "}]";
|
||||
String discoveryResult;
|
||||
String expBridgeDescription = "" + //
|
||||
"<?xml version=\"1.0\"?>" + //
|
||||
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">" + //
|
||||
" <specVersion>" + //
|
||||
" <major>1</major>" + //
|
||||
" <minor>0</minor>" + //
|
||||
" </specVersion>" + //
|
||||
" <URLBase>http://$IP:80/</URLBase>" + //
|
||||
" <device>" + //
|
||||
" <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>" + //
|
||||
" <friendlyName>Philips hue ($IP)</friendlyName>" + //
|
||||
" <manufacturer>Royal Philips Electronics</manufacturer>" + //
|
||||
" <manufacturerURL>http://www.philips.com</manufacturerURL>" + //
|
||||
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>" + //
|
||||
"<modelName>Philips hue bridge 2012</modelName>" + //
|
||||
"<modelNumber>1000000000000</modelNumber>" + //
|
||||
"<modelURL>http://www.meethue.com</modelURL>" + //
|
||||
" <serialNumber>93eadbeef13</serialNumber>" + //
|
||||
" <UDN>uuid:01234567-89ab-cdef-0123-456789abcdef</UDN>" + //
|
||||
" <serviceList>" + //
|
||||
" <service>" + //
|
||||
" <serviceType>(null)</serviceType>" + //
|
||||
" <serviceId>(null)</serviceId>" + //
|
||||
" <controlURL>(null)</controlURL>" + //
|
||||
" <eventSubURL>(null)</eventSubURL>" + //
|
||||
" <SCPDURL>(null)</SCPDURL>" + //
|
||||
" </service>" + //
|
||||
" </serviceList>" + //
|
||||
" <presentationURL>index.html</presentationURL>" + //
|
||||
" <iconList>" + //
|
||||
" <icon>" + //
|
||||
" <mimetype>image/png</mimetype>" + //
|
||||
" <height>48</height>" + //
|
||||
" <width>48</width>" + //
|
||||
" <depth>24</depth>" + //
|
||||
" <url>hue_logo_0.png</url>" + //
|
||||
" </icon>" + //
|
||||
" <icon>" + //
|
||||
" <mimetype>image/png</mimetype>" + //
|
||||
" <height>120</height>" + //
|
||||
" <width>120</width>" + //
|
||||
" <depth>24</depth>" + //
|
||||
" <url>hue_logo_3.png</url>" + //
|
||||
" </icon>" + //
|
||||
" </iconList>" + //
|
||||
" </device>" + //
|
||||
"</root>";
|
||||
|
||||
private void checkDiscoveryResult(DiscoveryResult result, String expIp, String expSn) {
|
||||
assertThat(result.getBridgeUID(), nullValue());
|
||||
assertThat(result.getLabel(), is(HueBridgeNupnpDiscovery.LABEL_PATTERN.replace("IP", expIp)));
|
||||
assertThat(result.getProperties().get("ipAddress"), is(expIp));
|
||||
assertThat(result.getProperties().get("serialNumber"), is(expSn));
|
||||
}
|
||||
|
||||
private void registerDiscoveryListener(DiscoveryListener discoveryListener) {
|
||||
unregisterCurrentDiscoveryListener();
|
||||
this.discoveryListener = discoveryListener;
|
||||
sut.addDiscoveryListener(this.discoveryListener);
|
||||
}
|
||||
|
||||
private void unregisterCurrentDiscoveryListener() {
|
||||
if (this.discoveryListener != null) {
|
||||
sut.removeDiscoveryListener(this.discoveryListener);
|
||||
}
|
||||
}
|
||||
|
||||
// Mock class which only overrides the doGetRequest method in order to make the class testable
|
||||
class ConfigurableBridgeNupnpDiscoveryMock extends HueBridgeNupnpDiscovery {
|
||||
@Override
|
||||
protected String doGetRequest(String url) throws IOException {
|
||||
if (url.contains("meethue")) {
|
||||
return discoveryResult;
|
||||
} else if (url.contains(ip1)) {
|
||||
return expBridgeDescription.replaceAll("$IP", ip1);
|
||||
} else if (url.contains(ip2)) {
|
||||
return expBridgeDescription.replaceAll("$IP", ip2);
|
||||
}
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
registerService(volatileStorageService);
|
||||
|
||||
sut = getService(DiscoveryService.class, HueBridgeNupnpDiscovery.class);
|
||||
assertThat(sut, is(notNullValue()));
|
||||
|
||||
inbox = getService(Inbox.class);
|
||||
assertThat(inbox, is(notNullValue()));
|
||||
|
||||
unregisterCurrentDiscoveryListener();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bridgeThingTypeIsSupported() {
|
||||
assertThat(sut.getSupportedThingTypes().size(), is(1));
|
||||
assertThat(sut.getSupportedThingTypes().iterator().next(), is(THING_TYPE_BRIDGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validBridgesAreDiscovered() {
|
||||
List<DiscoveryResult> oldResults = inbox.stream().filter(forThingTypeUID(BRIDGE_THING_TYPE_UID))
|
||||
.collect(Collectors.toList());
|
||||
for (final DiscoveryResult oldResult : oldResults) {
|
||||
inbox.remove(oldResult.getThingUID());
|
||||
}
|
||||
|
||||
sut = new ConfigurableBridgeNupnpDiscoveryMock();
|
||||
registerService(sut, DiscoveryService.class.getName());
|
||||
discoveryResult = validBridgeDiscoveryResult;
|
||||
final Map<ThingUID, DiscoveryResult> results = new HashMap<>();
|
||||
registerDiscoveryListener(new DiscoveryListener() {
|
||||
@Override
|
||||
public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
|
||||
results.put(result.getThingUID(), result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thingRemoved(DiscoveryService source, ThingUID thingUID) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ThingUID> removeOlderResults(DiscoveryService source, long timestamp,
|
||||
Collection<ThingTypeUID> thingTypeUIDs, ThingUID bridgeUID) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
sut.startScan();
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(2));
|
||||
assertThat(results.get(BRIDGE_THING_UID_1), is(notNullValue()));
|
||||
checkDiscoveryResult(results.get(BRIDGE_THING_UID_1), ip1, sn1);
|
||||
assertThat(results.get(BRIDGE_THING_UID_2), is(notNullValue()));
|
||||
checkDiscoveryResult(results.get(BRIDGE_THING_UID_2), ip2, sn2);
|
||||
|
||||
final List<DiscoveryResult> inboxResults = inbox.stream().filter(forThingTypeUID(BRIDGE_THING_TYPE_UID))
|
||||
.collect(Collectors.toList());
|
||||
assertTrue(inboxResults.size() >= 2);
|
||||
|
||||
assertThat(inboxResults.stream().filter(result -> result.getThingUID().equals(BRIDGE_THING_UID_1))
|
||||
.findFirst().orElse(null), is(notNullValue()));
|
||||
assertThat(inboxResults.stream().filter(result -> result.getThingUID().equals(BRIDGE_THING_UID_2))
|
||||
.findFirst().orElse(null), is(notNullValue()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidBridgesAreNotDiscovered() {
|
||||
List<DiscoveryResult> oldResults = inbox.stream().filter(forThingTypeUID(BRIDGE_THING_TYPE_UID))
|
||||
.collect(Collectors.toList());
|
||||
for (final DiscoveryResult oldResult : oldResults) {
|
||||
inbox.remove(oldResult.getThingUID());
|
||||
}
|
||||
|
||||
sut = new ConfigurableBridgeNupnpDiscoveryMock();
|
||||
registerService(sut, DiscoveryService.class.getName());
|
||||
final Map<ThingUID, DiscoveryResult> results = new HashMap<>();
|
||||
registerDiscoveryListener(new DiscoveryListener() {
|
||||
@Override
|
||||
public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
|
||||
results.put(result.getThingUID(), result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thingRemoved(DiscoveryService source, ThingUID thingUID) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ThingUID> removeOlderResults(DiscoveryService source, long timestamp,
|
||||
Collection<ThingTypeUID> thingTypeUIDs, ThingUID bridgeUID) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// missing ip
|
||||
discoveryResult = "[{\"id\":\"001788fffe20057f\",\"internalipaddress\":}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// missing id
|
||||
discoveryResult = "[{\"id\":\"\",\"internalipaddress\":192.168.30.22}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// id < 10
|
||||
discoveryResult = "[{\"id\":\"012345678\",\"internalipaddress\":192.168.30.22}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// bridge indicator not part of id
|
||||
discoveryResult = "[{\"id\":\"0123456789\",\"internalipaddress\":192.168.30.22}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// bridge indicator at wrong position (-1)
|
||||
discoveryResult = "[{\"id\":\"01234" + HueBridgeNupnpDiscovery.BRIDGE_INDICATOR
|
||||
+ "7891\",\"internalipaddress\":192.168.30.22}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// bridge indicator at wrong position (+1)
|
||||
discoveryResult = "[{\"id\":\"0123456" + HueBridgeNupnpDiscovery.BRIDGE_INDICATOR
|
||||
+ "7891\",\"internalipaddress\":192.168.30.22}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// bridge not reachable
|
||||
discoveryResult = "[{\"id\":\"001788fffe20057f\",\"internalipaddress\":192.168.30.1}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
// invalid bridge description
|
||||
expBridgeDescription = "";
|
||||
discoveryResult = "[{\"id\":\"001788fffe20057f\",\"internalipaddress\":" + ip1 + "}]";
|
||||
sut.startScan();
|
||||
waitForAssert(() -> {
|
||||
assertThat(results.size(), is(0));
|
||||
});
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertThat(
|
||||
inbox.stream().filter(forThingTypeUID(BRIDGE_THING_TYPE_UID)).collect(Collectors.toList()).size(),
|
||||
is(0));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.hue.internal.handler;
|
||||
|
||||
import static org.openhab.core.thing.Thing.PROPERTY_SERIAL_NUMBER;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.openhab.binding.hue.internal.HueBindingConstants.*;
|
||||
import static org.openhab.binding.hue.internal.config.HueBridgeConfig.HTTP;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.config.core.status.ConfigStatusMessage;
|
||||
import org.openhab.core.common.ThreadPoolManager;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.hue.internal.AbstractHueOSGiTestParent;
|
||||
import org.openhab.binding.hue.internal.HueBridge;
|
||||
import org.openhab.binding.hue.internal.HueConfigStatusMessage;
|
||||
import org.openhab.binding.hue.internal.exceptions.ApiException;
|
||||
import org.openhab.binding.hue.internal.exceptions.LinkButtonException;
|
||||
import org.openhab.binding.hue.internal.exceptions.UnauthorizedException;
|
||||
|
||||
/**
|
||||
* Tests for {@link HueBridgeHandler}.
|
||||
*
|
||||
* @author Oliver Libutzki - Initial contribution
|
||||
* @author Michael Grammling - Initial contribution
|
||||
* @author Denis Dudnik - switched to internally integrated source of Jue library
|
||||
*/
|
||||
public class HueBridgeHandlerOSGiTest extends AbstractHueOSGiTestParent {
|
||||
|
||||
private final ThingTypeUID BRIDGE_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "bridge");
|
||||
private static final String TEST_USER_NAME = "eshTestUser";
|
||||
private static final String DUMMY_HOST = "1.2.3.4";
|
||||
|
||||
private ThingRegistry thingRegistry;
|
||||
|
||||
private ScheduledExecutorService scheduler;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
registerVolatileStorageService();
|
||||
thingRegistry = getService(ThingRegistry.class, ThingRegistry.class);
|
||||
assertNotNull(thingRegistry);
|
||||
|
||||
scheduler = ThreadPoolManager.getScheduledPool("hueBridgeTest");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertThatANewUserIsAddedToConfigIfNotExistingYet() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, DUMMY_HOST);
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
hueBridgeHandler.thingUpdated(bridge);
|
||||
|
||||
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
|
||||
@Override
|
||||
public String link(String deviceType) throws IOException, ApiException {
|
||||
return TEST_USER_NAME;
|
||||
}
|
||||
});
|
||||
|
||||
hueBridgeHandler.onNotAuthenticated();
|
||||
|
||||
assertThat(bridge.getConfiguration().get(USER_NAME), equalTo(TEST_USER_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertThatAnExistingUserIsUsedIfAuthenticationWasSuccessful() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, DUMMY_HOST);
|
||||
configuration.put(USER_NAME, TEST_USER_NAME);
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
hueBridgeHandler.thingUpdated(bridge);
|
||||
|
||||
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
|
||||
@Override
|
||||
public void authenticate(String userName) throws IOException, ApiException {
|
||||
}
|
||||
});
|
||||
|
||||
hueBridgeHandler.onNotAuthenticated();
|
||||
|
||||
assertThat(bridge.getConfiguration().get(USER_NAME), equalTo(TEST_USER_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertCorrectStatusIfAuthenticationFailedForOldUser() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, DUMMY_HOST);
|
||||
configuration.put(USER_NAME, "notAuthenticatedUser");
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
hueBridgeHandler.thingUpdated(bridge);
|
||||
|
||||
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
|
||||
@Override
|
||||
public void authenticate(String userName) throws IOException, ApiException {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
});
|
||||
|
||||
hueBridgeHandler.onNotAuthenticated();
|
||||
|
||||
assertEquals("notAuthenticatedUser", bridge.getConfiguration().get(USER_NAME));
|
||||
assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
|
||||
assertEquals(ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, bridge.getStatusInfo().getStatusDetail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyStatusIfLinkButtonIsNotPressed() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, DUMMY_HOST);
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
hueBridgeHandler.thingUpdated(bridge);
|
||||
|
||||
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
|
||||
@Override
|
||||
public String link(String deviceType) throws IOException, ApiException {
|
||||
throw new LinkButtonException();
|
||||
}
|
||||
});
|
||||
|
||||
hueBridgeHandler.onNotAuthenticated();
|
||||
|
||||
assertNull(bridge.getConfiguration().get(USER_NAME));
|
||||
assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
|
||||
assertEquals(ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, bridge.getStatusInfo().getStatusDetail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyStatusIfNewUserCannotBeCreated() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, DUMMY_HOST);
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
hueBridgeHandler.thingUpdated(bridge);
|
||||
|
||||
injectBridge(hueBridgeHandler, new HueBridge(DUMMY_HOST, 80, HTTP, scheduler) {
|
||||
@Override
|
||||
public String link(String deviceType) throws IOException, ApiException {
|
||||
throw new ApiException();
|
||||
}
|
||||
});
|
||||
|
||||
hueBridgeHandler.onNotAuthenticated();
|
||||
|
||||
assertNull(bridge.getConfiguration().get(USER_NAME));
|
||||
assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
|
||||
assertEquals(ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, bridge.getStatusInfo().getStatusDetail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyOfflineIsSetWithoutBridgeOfflineStatus() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, DUMMY_HOST);
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
hueBridgeHandler.thingUpdated(bridge);
|
||||
|
||||
hueBridgeHandler.onConnectionLost();
|
||||
|
||||
assertEquals(ThingStatus.OFFLINE, bridge.getStatus());
|
||||
assertNotEquals(ThingStatusDetail.BRIDGE_OFFLINE, bridge.getStatusInfo().getStatusDetail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertThatAStatusConfigurationMessageForMissingBridgeIPIsProperlyReturnedIPIsNull() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, null);
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
|
||||
ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST)
|
||||
.withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build();
|
||||
|
||||
waitForAssert(() -> assertEquals(expected, hueBridgeHandler.getConfigStatus().iterator().next()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertThatAStatusConfigurationMessageForMissingBridgeIPIsProperlyReturnedIPIsAnEmptyString() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put(HOST, "");
|
||||
configuration.put(PROPERTY_SERIAL_NUMBER, "testSerialNumber");
|
||||
|
||||
Bridge bridge = createBridgeThing(configuration);
|
||||
|
||||
HueBridgeHandler hueBridgeHandler = getThingHandler(bridge, HueBridgeHandler.class);
|
||||
|
||||
ConfigStatusMessage expected = ConfigStatusMessage.Builder.error(HOST)
|
||||
.withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build();
|
||||
|
||||
waitForAssert(() -> assertEquals(expected, hueBridgeHandler.getConfigStatus().iterator().next()));
|
||||
}
|
||||
|
||||
private Bridge createBridgeThing(Configuration configuration) {
|
||||
Bridge bridge = (Bridge) thingRegistry.createThingOfType(BRIDGE_THING_TYPE_UID,
|
||||
new ThingUID(BRIDGE_THING_TYPE_UID, "testBridge"), null, "Bridge", configuration);
|
||||
|
||||
assertNotNull(bridge);
|
||||
thingRegistry.add(bridge);
|
||||
return bridge;
|
||||
}
|
||||
|
||||
private void injectBridge(HueBridgeHandler hueBridgeHandler, HueBridge bridge) {
|
||||
try {
|
||||
Field hueBridgeField = hueBridgeHandler.getClass().getDeclaredField("hueBridge");
|
||||
hueBridgeField.setAccessible(true);
|
||||
hueBridgeField.set(hueBridgeHandler, bridge);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user