mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[boschshc] Boost unit test coverage (#16500)
Boosts the unit test coverage for the `boschshc` binding in `src/main/java` to 94%. Signed-off-by: David Pace <dev@davidpace.de> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
597fa78b34
commit
e99d5e1ffc
@ -657,7 +657,7 @@ public class BridgeHandler extends BaseBridgeHandler {
|
||||
*
|
||||
* @param e error during long polling
|
||||
*/
|
||||
private void handleLongPollFailure(Throwable e) {
|
||||
void handleLongPollFailure(Throwable e) {
|
||||
logger.warn("Long polling failed, will try to reconnect", e);
|
||||
@Nullable
|
||||
BoschHttpClient localHttpClient = this.httpClient;
|
||||
@ -722,7 +722,7 @@ public class BridgeHandler extends BaseBridgeHandler {
|
||||
return new BoschSHCException("@text/offline.conf-error.invalid-state-id");
|
||||
} else {
|
||||
return new BoschSHCException(String.format(
|
||||
"Request for info of user-defines state %s failed with status code %d and error code %s",
|
||||
"Request for info of user-defined state %s failed with status code %d and error code %s",
|
||||
stateId, errorResponse.statusCode, errorResponse.errorCode));
|
||||
}
|
||||
} else {
|
||||
|
@ -96,7 +96,7 @@ public class ScenarioHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private String prettyLogScenarios(final Scenario[] scenarios) {
|
||||
String prettyLogScenarios(final Scenario[] scenarios) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("[");
|
||||
for (Scenario scenario : scenarios) {
|
||||
|
@ -17,7 +17,12 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@ -35,6 +40,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.BridgeHandler;
|
||||
@ -89,6 +96,24 @@ class BoschShcCommandExtensionTest {
|
||||
verify(consoleMock, atLeastOnce()).print(any());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getBoschShcAndExecutionAndTimeoutExceptionArguments()")
|
||||
void executeHandleExceptions(Exception exception)
|
||||
throws InterruptedException, BoschSHCException, ExecutionException, TimeoutException {
|
||||
Console console = mock(Console.class);
|
||||
Bridge bridge = mock(Bridge.class);
|
||||
BridgeHandler bridgeHandler = mock(BridgeHandler.class);
|
||||
when(bridgeHandler.getThing()).thenReturn(bridge);
|
||||
when(bridgeHandler.getPublicInformation()).thenThrow(exception);
|
||||
when(bridge.getHandler()).thenReturn(bridgeHandler);
|
||||
List<Thing> things = List.of(bridge);
|
||||
when(thingRegistry.getAll()).thenReturn(things);
|
||||
|
||||
fixture.execute(new String[] { BoschShcCommandExtension.GET_BRIDGEINFO }, console);
|
||||
|
||||
verify(console).print(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCompleter() {
|
||||
assertThat(fixture.getCompleter(), is(fixture));
|
||||
|
@ -46,13 +46,13 @@ public abstract class AbstractBatteryPoweredDeviceHandlerTest<T extends Abstract
|
||||
@BeforeEach
|
||||
@Override
|
||||
public void beforeEach() throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
super.beforeEach();
|
||||
|
||||
DeviceServiceData deviceServiceData = new DeviceServiceData();
|
||||
deviceServiceData.path = "/devices/hdm:ZigBee:000d6f0004b93361/services/BatteryLevel";
|
||||
deviceServiceData.id = "BatteryLevel";
|
||||
deviceServiceData.deviceId = "hdm:ZigBee:000d6f0004b93361";
|
||||
lenient().when(bridgeHandler.getServiceData(anyString(), anyString())).thenReturn(deviceServiceData);
|
||||
when(getBridgeHandler().getServiceData(anyString(), anyString())).thenReturn(deviceServiceData);
|
||||
|
||||
super.beforeEach();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -137,10 +137,11 @@ public abstract class AbstractBatteryPoweredDeviceHandlerTest<T extends Abstract
|
||||
"deviceId":"hdm:ZigBee:000d6f0004b93361" }\
|
||||
""");
|
||||
getFixture().processUpdate("BatteryLevel", deviceServiceData);
|
||||
verify(getCallback()).stateUpdated(
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_BATTERY_LEVEL),
|
||||
new DecimalType(100));
|
||||
verify(getCallback()).stateUpdated(
|
||||
verify(getCallback(), times(2)).stateUpdated(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_LOW_BATTERY), OnOffType.OFF);
|
||||
}
|
||||
|
||||
@ -165,19 +166,24 @@ public abstract class AbstractBatteryPoweredDeviceHandlerTest<T extends Abstract
|
||||
getFixture().processUpdate("BatteryLevel", deviceServiceData);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_BATTERY_LEVEL),
|
||||
UnDefType.UNDEF);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_LOW_BATTERY), OnOffType.OFF);
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_LOW_BATTERY),
|
||||
OnOffType.OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleCommandRefreshBatteryLevelChannel() {
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_BATTERY_LEVEL), RefreshType.REFRESH);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_BATTERY_LEVEL),
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_BATTERY_LEVEL),
|
||||
new DecimalType(100));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleCommandRefreshLowBatteryChannel() {
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_LOW_BATTERY), RefreshType.REFRESH);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_LOW_BATTERY), OnOffType.OFF);
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_LOW_BATTERY),
|
||||
OnOffType.OFF);
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,23 @@
|
||||
*/
|
||||
package org.openhab.binding.boschshc.internal.devices;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.Device;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
|
||||
/**
|
||||
* Abstract unit test implementation for device handlers.
|
||||
@ -42,4 +56,27 @@ public abstract class AbstractBoschSHCDeviceHandlerTest<T extends BoschSHCDevice
|
||||
}
|
||||
|
||||
protected abstract String getDeviceID();
|
||||
|
||||
@Test
|
||||
void initializeInvalidDeviceId() {
|
||||
getFixture().getThing().getConfiguration().remove("id");
|
||||
getFixture().initialize();
|
||||
|
||||
verify(getCallback()).statusUpdated(eq(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.CONFIGURATION_ERROR)));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionExceptionAndInterruptedExceptionArguments()")
|
||||
void initializeHandleExceptionDuringDeviceInfoRestCall(Exception exception)
|
||||
throws BoschSHCException, InterruptedException, TimeoutException, ExecutionException {
|
||||
when(getBridgeHandler().getDeviceInfo(getDeviceID())).thenThrow(exception);
|
||||
|
||||
getFixture().initialize();
|
||||
|
||||
verify(getCallback()).statusUpdated(eq(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.CONFIGURATION_ERROR)));
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@
|
||||
*/
|
||||
package org.openhab.binding.boschshc.internal.devices;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@ -60,7 +63,7 @@ public abstract class AbstractBoschSHCHandlerTest<T extends BoschSHCHandler> {
|
||||
|
||||
private @Mock @NonNullByDefault({}) Bridge bridge;
|
||||
|
||||
protected @Mock @NonNullByDefault({}) BridgeHandler bridgeHandler;
|
||||
private @Mock @NonNullByDefault({}) BridgeHandler bridgeHandler;
|
||||
|
||||
private @Mock @NonNullByDefault({}) ThingHandlerCallback callback;
|
||||
|
||||
@ -128,8 +131,25 @@ public abstract class AbstractBoschSHCHandlerTest<T extends BoschSHCHandler> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialize() {
|
||||
void testInitialize() {
|
||||
ThingStatusInfo expectedStatusInfo = new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
|
||||
verify(callback).statusUpdated(same(thing), eq(expectedStatusInfo));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetBridgeHandler() throws BoschSHCException {
|
||||
assertThat(fixture.getBridgeHandler(), sameInstance(bridgeHandler));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetBridgeHandlerThrowExceptionIfBridgeIsNull() throws BoschSHCException {
|
||||
when(callback.getBridge(any())).thenReturn(null);
|
||||
assertThrows(BoschSHCException.class, () -> fixture.getBridgeHandler());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetBridgeHandlerThrowExceptionIfBridgeHandlerIsNull() throws BoschSHCException {
|
||||
when(bridge.getHandler()).thenReturn(null);
|
||||
assertThrows(BoschSHCException.class, () -> fixture.getBridgeHandler());
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,14 @@
|
||||
package org.openhab.binding.boschshc.internal.devices;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@ -26,12 +28,16 @@ import java.util.concurrent.TimeoutException;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.PowerSwitchState;
|
||||
import org.openhab.binding.boschshc.internal.services.powerswitch.dto.PowerSwitchServiceState;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
@ -53,12 +59,12 @@ public abstract class AbstractPowerSwitchHandlerTest<T extends AbstractPowerSwit
|
||||
@BeforeEach
|
||||
@Override
|
||||
public void beforeEach() throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
super.beforeEach();
|
||||
|
||||
PowerSwitchServiceState powerSwitchServiceState = new PowerSwitchServiceState();
|
||||
powerSwitchServiceState.switchState = PowerSwitchState.ON;
|
||||
lenient().when(bridgeHandler.getState(anyString(), eq("PowerSwitch"), same(PowerSwitchServiceState.class)))
|
||||
when(getBridgeHandler().getState(anyString(), eq("PowerSwitch"), same(PowerSwitchServiceState.class)))
|
||||
.thenReturn(powerSwitchServiceState);
|
||||
|
||||
super.beforeEach();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -76,22 +82,58 @@ public abstract class AbstractPowerSwitchHandlerTest<T extends AbstractPowerSwit
|
||||
assertSame(PowerSwitchState.OFF, state.switchState);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionAndTimeoutAndInterruptedExceptionArguments()")
|
||||
public void testHandleCommandPowerSwitchChannelHandleExceptions(Exception e)
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
when(getBridgeHandler().putState(any(), any(), any())).thenThrow(e);
|
||||
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.ON);
|
||||
|
||||
verify(getCallback()).statusUpdated(same(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.COMMUNICATION_ERROR)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannelPowerSwitchState() {
|
||||
JsonElement jsonObject = JsonParser
|
||||
.parseString("{\n" + " \"@type\": \"powerSwitchState\",\n" + " \"switchState\": \"ON\"\n" + "}");
|
||||
|
||||
getFixture().processUpdate("PowerSwitch", jsonObject);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.ON);
|
||||
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH),
|
||||
OnOffType.ON);
|
||||
|
||||
jsonObject = JsonParser
|
||||
.parseString("{\n" + " \"@type\": \"powerSwitchState\",\n" + " \"switchState\": \"OFF\"\n" + "}");
|
||||
|
||||
getFixture().processUpdate("PowerSwitch", jsonObject);
|
||||
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleCommandRefreshPowerSwitchChannel() {
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), RefreshType.REFRESH);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), OnOffType.ON);
|
||||
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH),
|
||||
OnOffType.ON);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getBoschShcAndExecutionAndTimeoutAndInterruptedExceptionArguments()")
|
||||
public void testHandleCommandRefreshPowerSwitchChannelHandleExceptions(Exception e)
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
when(getBridgeHandler().getState(anyString(), eq("PowerSwitch"), same(PowerSwitchServiceState.class)))
|
||||
.thenThrow(e);
|
||||
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH), RefreshType.REFRESH);
|
||||
|
||||
verify(getCallback()).statusUpdated(same(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.COMMUNICATION_ERROR)));
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -56,13 +57,13 @@ public abstract class AbstractPowerSwitchHandlerWithPowerMeterTest<T extends Abs
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
super.beforeEach();
|
||||
|
||||
PowerMeterServiceState powerMeterServiceState = new PowerMeterServiceState();
|
||||
powerMeterServiceState.powerConsumption = 12.34d;
|
||||
powerMeterServiceState.energyConsumption = 56.78d;
|
||||
lenient().when(bridgeHandler.getState(anyString(), eq("PowerMeter"), same(PowerMeterServiceState.class)))
|
||||
lenient().when(getBridgeHandler().getState(anyString(), eq("PowerMeter"), same(PowerMeterServiceState.class)))
|
||||
.thenReturn(powerMeterServiceState);
|
||||
|
||||
super.beforeEach();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -76,13 +77,15 @@ public abstract class AbstractPowerSwitchHandlerWithPowerMeterTest<T extends Abs
|
||||
""");
|
||||
getFixture().processUpdate("PowerMeter", jsonObject);
|
||||
|
||||
verify(getCallback()).stateUpdated(eq(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_CONSUMPTION)),
|
||||
powerCaptor.capture());
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(
|
||||
eq(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_CONSUMPTION)), powerCaptor.capture());
|
||||
QuantityType<Power> powerValue = powerCaptor.getValue();
|
||||
assertEquals(23, powerValue.intValue());
|
||||
|
||||
verify(getCallback()).stateUpdated(eq(getChannelUID(BoschSHCBindingConstants.CHANNEL_ENERGY_CONSUMPTION)),
|
||||
energyCaptor.capture());
|
||||
// state is updated twice: via short poll in initialize() and via long poll result in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(
|
||||
eq(getChannelUID(BoschSHCBindingConstants.CHANNEL_ENERGY_CONSUMPTION)), energyCaptor.capture());
|
||||
QuantityType<Energy> energyValue = energyCaptor.getValue();
|
||||
assertEquals(42, energyValue.intValue());
|
||||
}
|
||||
@ -91,7 +94,9 @@ public abstract class AbstractPowerSwitchHandlerWithPowerMeterTest<T extends Abs
|
||||
public void testHandleCommandRefreshPowerConsumptionChannel() {
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_CONSUMPTION),
|
||||
RefreshType.REFRESH);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_CONSUMPTION),
|
||||
|
||||
// state is updated twice: via short poll in initialize() and via refresh command in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_POWER_CONSUMPTION),
|
||||
new QuantityType<>(12.34d, Units.WATT));
|
||||
}
|
||||
|
||||
@ -99,7 +104,9 @@ public abstract class AbstractPowerSwitchHandlerWithPowerMeterTest<T extends Abs
|
||||
public void testHandleCommandRefreshEnergyConsumptionChannel() {
|
||||
getFixture().handleCommand(getChannelUID(BoschSHCBindingConstants.CHANNEL_ENERGY_CONSUMPTION),
|
||||
RefreshType.REFRESH);
|
||||
verify(getCallback()).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_ENERGY_CONSUMPTION),
|
||||
|
||||
// state is updated twice: via short poll in initialize() and via refresh command in this test
|
||||
verify(getCallback(), times(2)).stateUpdated(getChannelUID(BoschSHCBindingConstants.CHANNEL_ENERGY_CONSUMPTION),
|
||||
new QuantityType<>(56.78d, Units.WATT_HOUR));
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,10 @@
|
||||
*/
|
||||
package org.openhab.binding.boschshc.internal.devices.bridge;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@ -22,9 +25,11 @@ import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ -50,16 +55,23 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
|
||||
import org.openhab.binding.boschshc.internal.devices.BoschSHCHandler;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.Device;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.DeviceServiceData;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.DeviceTest;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.Faults;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.LongPollResult;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.PublicInformation;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.Room;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.Scenario;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.SubscribeResult;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.UserDefinedState;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.UserDefinedStateTest;
|
||||
import org.openhab.binding.boschshc.internal.discovery.ThingDiscoveryService;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.serialization.GsonUtils;
|
||||
import org.openhab.binding.boschshc.internal.services.binaryswitch.dto.BinarySwitchServiceState;
|
||||
@ -70,15 +82,21 @@ import org.openhab.binding.boschshc.internal.services.intrusion.dto.IntrusionDet
|
||||
import org.openhab.binding.boschshc.internal.services.shuttercontact.ShutterContactState;
|
||||
import org.openhab.binding.boschshc.internal.services.shuttercontact.dto.ShutterContactServiceState;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link BridgeHandler}.
|
||||
@ -92,13 +110,9 @@ class BridgeHandlerTest {
|
||||
private @NonNullByDefault({}) BridgeHandler fixture;
|
||||
|
||||
private @NonNullByDefault({}) BoschHttpClient httpClient;
|
||||
|
||||
private @NonNullByDefault({}) ThingHandlerCallback thingHandlerCallback;
|
||||
|
||||
/**
|
||||
* A mocked bridge instance
|
||||
*/
|
||||
private @NonNullByDefault({}) Bridge thing;
|
||||
private @NonNullByDefault({}) Configuration bridgeConfiguration;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() throws IOException {
|
||||
@ -119,7 +133,7 @@ class BridgeHandlerTest {
|
||||
thingHandlerCallback = mock(ThingHandlerCallback.class);
|
||||
fixture.setCallback(thingHandlerCallback);
|
||||
|
||||
Configuration bridgeConfiguration = new Configuration();
|
||||
bridgeConfiguration = new Configuration();
|
||||
Map<@Nullable String, @Nullable Object> properties = new HashMap<>();
|
||||
properties.put("ipAddress", "localhost");
|
||||
properties.put("password", "test");
|
||||
@ -155,6 +169,19 @@ class BridgeHandlerTest {
|
||||
verify(mockRequest).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
void postActionWithoutRequestBody() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
String endpoint = "/intrusion/actions/disarm";
|
||||
String url = "https://127.0.0.1:8444/smarthome/intrusion/actions/disarm";
|
||||
when(httpClient.getBoschSmartHomeUrl(endpoint)).thenReturn(url);
|
||||
Request mockRequest = mock(Request.class);
|
||||
when(httpClient.createRequest(anyString(), any(), any())).thenReturn(mockRequest);
|
||||
|
||||
fixture.postAction(endpoint);
|
||||
verify(httpClient).createRequest(eq(url), same(HttpMethod.POST), isNull());
|
||||
verify(mockRequest).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
void initialAccessHttpClientOffline() {
|
||||
fixture.initialAccess(httpClient);
|
||||
@ -212,9 +239,31 @@ class BridgeHandlerTest {
|
||||
when(httpClient.createRequest(anyString(), same(HttpMethod.POST),
|
||||
argThat((JsonRpcRequest r) -> "RE/longPoll".equals(r.method)))).thenReturn(longPollRequest);
|
||||
|
||||
ThingDiscoveryService thingDiscoveryListener = mock(ThingDiscoveryService.class);
|
||||
fixture.registerDiscoveryListener(thingDiscoveryListener);
|
||||
|
||||
fixture.initialAccess(httpClient);
|
||||
|
||||
verify(thingHandlerCallback).statusUpdated(any(),
|
||||
eq(ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build()));
|
||||
verify(thingDiscoveryListener).doScan();
|
||||
}
|
||||
|
||||
@Test
|
||||
void initialAccessNoBridgeAccess() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
when(httpClient.isOnline()).thenReturn(true);
|
||||
when(httpClient.isAccessPossible()).thenReturn(true);
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), same(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse response = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(response);
|
||||
when(response.getStatus()).thenReturn(400);
|
||||
|
||||
fixture.initialAccess(httpClient);
|
||||
|
||||
verify(thingHandlerCallback).statusUpdated(same(thing),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.COMMUNICATION_ERROR)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -468,6 +517,44 @@ class BridgeHandlerTest {
|
||||
assertEquals(stateId, userState.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUserStateInfoErrorCases()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenCallRealMethod();
|
||||
when(httpClient.getBoschShcUrl(anyString())).thenCallRealMethod();
|
||||
|
||||
Request request = mock(Request.class);
|
||||
when(request.header(anyString(), anyString())).thenReturn(request);
|
||||
ContentResponse response = mock(ContentResponse.class);
|
||||
when(response.getStatus()).thenReturn(200);
|
||||
when(request.send()).thenReturn(response);
|
||||
when(httpClient.createRequest(anyString(), same(HttpMethod.GET))).thenReturn(request);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<BiFunction<Integer, String, BoschSHCException>> errorResponseHandlerCaptor = ArgumentCaptor
|
||||
.forClass(BiFunction.class);
|
||||
|
||||
String stateId = "abcdef";
|
||||
when(httpClient.sendRequest(same(request), same(UserDefinedState.class), any(),
|
||||
errorResponseHandlerCaptor.capture())).thenReturn(UserDefinedStateTest.createTestState(stateId));
|
||||
|
||||
fixture.getUserStateInfo(stateId);
|
||||
|
||||
BiFunction<Integer, String, BoschSHCException> errorResponseHandler = errorResponseHandlerCaptor.getValue();
|
||||
Exception e = errorResponseHandler.apply(500,
|
||||
"{\"@type\":\"JsonRestExceptionResponseEntity\",\"errorCode\": \"testErrorCode\",\"statusCode\": 500}");
|
||||
assertEquals(
|
||||
"Request for info of user-defined state abcdef failed with status code 500 and error code testErrorCode",
|
||||
e.getMessage());
|
||||
|
||||
e = errorResponseHandler.apply(404,
|
||||
"{\"@type\":\"JsonRestExceptionResponseEntity\",\"errorCode\": \"ENTITY_NOT_FOUND\",\"statusCode\": 404}");
|
||||
assertNotNull(e);
|
||||
|
||||
e = errorResponseHandler.apply(500, "");
|
||||
assertEquals("Request for info of user-defined state abcdef failed with status code 500", e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUserStates() throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenCallRealMethod();
|
||||
@ -650,4 +737,347 @@ class BridgeHandlerTest {
|
||||
|
||||
verify(thingHandler).processChildUpdate("hdm:ZigBee:70ac08fffefead2d#3", "PowerSwitch", expectedState);
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleLongPollResultScenarioTriggered() {
|
||||
Channel channel = mock(Channel.class);
|
||||
when(thing.getChannel(BoschSHCBindingConstants.CHANNEL_SCENARIO_TRIGGERED)).thenReturn(channel);
|
||||
when(thingHandlerCallback.isChannelLinked(any())).thenReturn(true);
|
||||
|
||||
String json = """
|
||||
{
|
||||
"result": [{
|
||||
"@type": "scenarioTriggered",
|
||||
"name": "My Scenario",
|
||||
"id": "509bd737-eed0-40b7-8caa-e8686a714399",
|
||||
"lastTimeTriggered": "1693758693032"
|
||||
}],
|
||||
"jsonrpc": "2.0"
|
||||
}
|
||||
""";
|
||||
LongPollResult longPollResult = GsonUtils.DEFAULT_GSON_INSTANCE.fromJson(json, LongPollResult.class);
|
||||
assertNotNull(longPollResult);
|
||||
|
||||
fixture.handleLongPollResult(longPollResult);
|
||||
|
||||
verify(thingHandlerCallback).stateUpdated(any(), eq(new StringType("My Scenario")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleLongPollResultUserDefinedState() {
|
||||
List<Thing> things = new ArrayList<Thing>();
|
||||
when(thing.getThings()).thenReturn(things);
|
||||
|
||||
Thing thing = mock(Thing.class);
|
||||
things.add(thing);
|
||||
|
||||
BoschSHCHandler thingHandler = mock(BoschSHCHandler.class);
|
||||
when(thing.getHandler()).thenReturn(thingHandler);
|
||||
|
||||
when(thingHandler.getBoschID()).thenReturn("3d8023d6-69ca-4e79-89dd-7090295cefbf");
|
||||
|
||||
String json = """
|
||||
{
|
||||
"result": [{
|
||||
"deleted": false,
|
||||
"@type": "userDefinedState",
|
||||
"name": "Test State",
|
||||
"id": "3d8023d6-69ca-4e79-89dd-7090295cefbf",
|
||||
"state": true
|
||||
}],
|
||||
"jsonrpc": "2.0"
|
||||
}
|
||||
""";
|
||||
LongPollResult longPollResult = GsonUtils.DEFAULT_GSON_INSTANCE.fromJson(json, LongPollResult.class);
|
||||
assertNotNull(longPollResult);
|
||||
|
||||
fixture.handleLongPollResult(longPollResult);
|
||||
|
||||
JsonElement expectedState = new JsonPrimitive(true);
|
||||
|
||||
verify(thingHandler).processUpdate("3d8023d6-69ca-4e79-89dd-7090295cefbf", expectedState);
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleLongPollFailure() {
|
||||
Throwable e = new RuntimeException("Test exception");
|
||||
fixture.handleLongPollFailure(e);
|
||||
|
||||
ThingStatusInfo expectedStatus = ThingStatusInfoBuilder
|
||||
.create(ThingStatus.UNKNOWN, ThingStatusDetail.UNKNOWN.NONE).build();
|
||||
verify(thingHandlerCallback).statusUpdated(thing, expectedStatus);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDevices() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse contentResponse = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(200);
|
||||
String devicesJson = """
|
||||
[
|
||||
{
|
||||
"@type": "device",
|
||||
"rootDeviceId": "64-da-a0-3e-81-0c",
|
||||
"id": "hdm:ZigBee:0c4314fffea15de7",
|
||||
"deviceServiceIds": [
|
||||
"CommunicationQuality",
|
||||
"PowerMeter",
|
||||
"PowerSwitch",
|
||||
"PowerSwitchConfiguration",
|
||||
"PowerSwitchProgram"
|
||||
],
|
||||
"manufacturer": "BOSCH",
|
||||
"roomId": "hz_1",
|
||||
"deviceModel": "PLUG_COMPACT",
|
||||
"serial": "0C4314FFFE802BE2",
|
||||
"profile": "LIGHT",
|
||||
"iconId": "icon_plug_lamp_table",
|
||||
"name": "My Lamp Plug",
|
||||
"status": "AVAILABLE",
|
||||
"childDeviceIds": [],
|
||||
"supportedProfiles": [
|
||||
"LIGHT",
|
||||
"GENERIC",
|
||||
"HEATING_RCC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"@type": "device",
|
||||
"rootDeviceId": "64-da-a0-3e-81-0c",
|
||||
"id": "hdm:ZigBee:000d6f0012f13bfa",
|
||||
"deviceServiceIds": [
|
||||
"LatestMotion",
|
||||
"CommunicationQuality",
|
||||
"WalkTest",
|
||||
"BatteryLevel",
|
||||
"MultiLevelSensor",
|
||||
"DeviceDefect"
|
||||
],
|
||||
"manufacturer": "BOSCH",
|
||||
"roomId": "hz_5",
|
||||
"deviceModel": "MD",
|
||||
"serial": "000D6F0012F0da96",
|
||||
"profile": "GENERIC",
|
||||
"name": "My Motion Detector",
|
||||
"status": "AVAILABLE",
|
||||
"childDeviceIds": [],
|
||||
"supportedProfiles": []
|
||||
}
|
||||
]
|
||||
""";
|
||||
when(contentResponse.getContentAsString()).thenReturn(devicesJson);
|
||||
|
||||
List<Device> devices = fixture.getDevices();
|
||||
|
||||
assertEquals(2, devices.size());
|
||||
|
||||
Device plugDevice = devices.get(0);
|
||||
assertEquals("hdm:ZigBee:0c4314fffea15de7", plugDevice.id);
|
||||
assertEquals(5, plugDevice.deviceServiceIds.size());
|
||||
assertEquals(0, plugDevice.childDeviceIds.size());
|
||||
|
||||
Device motionDetectorDevice = devices.get(1);
|
||||
assertEquals("hdm:ZigBee:000d6f0012f13bfa", motionDetectorDevice.id);
|
||||
assertEquals(6, motionDetectorDevice.deviceServiceIds.size());
|
||||
assertEquals(0, motionDetectorDevice.childDeviceIds.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDevicesErrorRestResponse() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse contentResponse = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(400); // bad request
|
||||
|
||||
List<Device> devices = fixture.getDevices();
|
||||
|
||||
assertThat(devices, hasSize(0));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionAndTimeoutExceptionArguments()")
|
||||
void getDevicesHandleExceptions() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
when(request.send()).thenThrow(new ExecutionException(new RuntimeException("Test Exception")));
|
||||
|
||||
List<Device> devices = fixture.getDevices();
|
||||
|
||||
assertThat(devices, hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRooms() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse contentResponse = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(200);
|
||||
String roomsJson = """
|
||||
[
|
||||
{
|
||||
"@type": "room",
|
||||
"id": "hz_1",
|
||||
"iconId": "icon_room_living_room",
|
||||
"name": "Living Room"
|
||||
},
|
||||
{
|
||||
"@type": "room",
|
||||
"id": "hz_2",
|
||||
"iconId": "icon_room_dining_room",
|
||||
"name": "Dining Room"
|
||||
}
|
||||
]
|
||||
""";
|
||||
when(contentResponse.getContentAsString()).thenReturn(roomsJson);
|
||||
|
||||
List<Room> rooms = fixture.getRooms();
|
||||
|
||||
assertEquals(2, rooms.size());
|
||||
|
||||
Room livingRoom = rooms.get(0);
|
||||
assertEquals("hz_1", livingRoom.id);
|
||||
assertEquals("Living Room", livingRoom.name);
|
||||
|
||||
Room diningRoom = rooms.get(1);
|
||||
assertEquals("hz_2", diningRoom.id);
|
||||
assertEquals("Dining Room", diningRoom.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRoomsErrorRestResponse() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse contentResponse = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(400); // bad request
|
||||
|
||||
List<Room> rooms = fixture.getRooms();
|
||||
|
||||
assertThat(rooms, hasSize(0));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionAndTimeoutExceptionArguments()")
|
||||
void getRoomsHandleExceptions() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
when(request.send()).thenThrow(new ExecutionException(new RuntimeException("Test Exception")));
|
||||
|
||||
List<Room> rooms = fixture.getRooms();
|
||||
|
||||
assertThat(rooms, hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getServices() {
|
||||
assertTrue(fixture.getServices().contains(ThingDiscoveryService.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleCommandIrrelevantChannel() {
|
||||
ChannelUID channelUID = mock(ChannelUID.class);
|
||||
when(channelUID.getId()).thenReturn(BoschSHCBindingConstants.CHANNEL_POWER_SWITCH);
|
||||
|
||||
fixture.handleCommand(channelUID, OnOffType.ON);
|
||||
|
||||
verifyNoInteractions(httpClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleCommandTriggerScenario()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
ChannelUID channelUID = mock(ChannelUID.class);
|
||||
when(channelUID.getId()).thenReturn(BoschSHCBindingConstants.CHANNEL_TRIGGER_SCENARIO);
|
||||
|
||||
// required to prevent NPE
|
||||
when(httpClient.sendRequest(any(), eq(Scenario[].class), any(), any())).thenReturn(new Scenario[] {});
|
||||
|
||||
fixture.handleCommand(channelUID, OnOffType.ON);
|
||||
|
||||
verify(httpClient).sendRequest(any(), eq(Scenario[].class), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerDiscoveryListener() {
|
||||
ThingDiscoveryService listener = mock(ThingDiscoveryService.class);
|
||||
assertTrue(fixture.registerDiscoveryListener(listener));
|
||||
assertFalse(fixture.registerDiscoveryListener(listener));
|
||||
}
|
||||
|
||||
@Test
|
||||
void unregisterDiscoveryListener() {
|
||||
assertFalse(fixture.unregisterDiscoveryListener());
|
||||
fixture.registerDiscoveryListener(mock(ThingDiscoveryService.class));
|
||||
assertTrue(fixture.unregisterDiscoveryListener());
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializeNoIpAddress() {
|
||||
bridgeConfiguration.setProperties(new HashMap<String, Object>());
|
||||
|
||||
fixture.initialize();
|
||||
|
||||
ThingStatusInfo expectedStatus = ThingStatusInfoBuilder
|
||||
.create(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR)
|
||||
.withDescription("@text/offline.conf-error-empty-ip").build();
|
||||
verify(thingHandlerCallback).statusUpdated(thing, expectedStatus);
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializeNoPassword() {
|
||||
HashMap<String, Object> properties = new HashMap<String, Object>();
|
||||
properties.put("ipAddress", "localhost");
|
||||
bridgeConfiguration.setProperties(properties);
|
||||
|
||||
fixture.initialize();
|
||||
|
||||
ThingStatusInfo expectedStatus = ThingStatusInfoBuilder
|
||||
.create(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR)
|
||||
.withDescription("@text/offline.conf-error-empty-password").build();
|
||||
verify(thingHandlerCallback).statusUpdated(thing, expectedStatus);
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkBridgeAccess() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse contentResponse = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(200);
|
||||
|
||||
assertTrue(fixture.checkBridgeAccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkBridgeAccessRestResponseError() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
ContentResponse contentResponse = mock(ContentResponse.class);
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(400);
|
||||
|
||||
assertFalse(fixture.checkBridgeAccess());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionAndTimeoutExceptionArguments()")
|
||||
void checkBridgeAccessRestException(Exception e) throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Request request = mock(Request.class);
|
||||
when(httpClient.createRequest(any(), eq(HttpMethod.GET))).thenReturn(request);
|
||||
when(request.send()).thenThrow(e);
|
||||
|
||||
assertFalse(fixture.checkBridgeAccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPublicInformation() throws InterruptedException, BoschSHCException, ExecutionException, TimeoutException {
|
||||
fixture.getPublicInformation();
|
||||
|
||||
verify(httpClient).createRequest(any(), same(HttpMethod.GET));
|
||||
verify(httpClient).sendRequest(any(), same(PublicInformation.class), any(), isNull());
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,21 @@
|
||||
*/
|
||||
package org.openhab.binding.boschshc.internal.devices.bridge;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -43,6 +55,8 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
@ -53,6 +67,7 @@ import org.openhab.binding.boschshc.internal.devices.bridge.dto.SubscribeResult;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.UserDefinedState;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.LongPollingFailedException;
|
||||
import org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
@ -332,18 +347,21 @@ class LongPollingTest {
|
||||
assertTrue(longPollResultItem.isState());
|
||||
}
|
||||
|
||||
@Test
|
||||
void startSubscriptionFailure()
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getBoschShcAndExecutionAndTimeoutAndInterruptedExceptionArguments()")
|
||||
void startSubscriptionFailureHandleExceptions(Exception exception)
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
when(httpClient.sendRequest(any(), same(SubscribeResult.class), any(), any()))
|
||||
.thenThrow(new ExecutionException("Subscription failed.", null));
|
||||
when(httpClient.sendRequest(any(), same(SubscribeResult.class), any(), any())).thenThrow(exception);
|
||||
|
||||
LongPollingFailedException e = assertThrows(LongPollingFailedException.class, () -> fixture.start(httpClient));
|
||||
assertTrue(e.getMessage().contains("Subscription failed."));
|
||||
assertThat(e.getCause(), instanceOf(exception.getClass()));
|
||||
assertThat(e.getMessage(), containsString(CommonTestUtils.TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startLongPollFailure() throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExceutionExceptionAndRuntimeExceptionArguments()")
|
||||
void startLongPollFailure(Exception exception)
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
when(httpClient.getBoschShcUrl(anyString())).thenCallRealMethod();
|
||||
|
||||
Request request = mock(Request.class);
|
||||
@ -364,7 +382,6 @@ class LongPollingTest {
|
||||
BufferingResponseListener bufferingResponseListener = (BufferingResponseListener) completeListener.getValue();
|
||||
|
||||
Result result = mock(Result.class);
|
||||
ExecutionException exception = new ExecutionException("test exception", null);
|
||||
when(result.getFailure()).thenReturn(exception);
|
||||
bufferingResponseListener.onComplete(result);
|
||||
|
||||
|
@ -12,7 +12,13 @@
|
||||
*/
|
||||
package org.openhab.binding.boschshc.internal.devices.bridge;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -24,10 +30,12 @@ import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.Scenario;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
@ -61,11 +69,19 @@ class ScenarioHandlerTest {
|
||||
.toArray(Exception[]::new);
|
||||
}
|
||||
|
||||
private @NonNullByDefault({}) ScenarioHandler fixture;
|
||||
|
||||
private @NonNullByDefault({}) @Mock BoschHttpClient httpClient;
|
||||
private @NonNullByDefault({}) @Mock Request request;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
fixture = new ScenarioHandler();
|
||||
}
|
||||
|
||||
@Test
|
||||
void triggerScenarioShouldSendPOSTToBoschAPI() throws Exception {
|
||||
// GIVEN
|
||||
final var httpClient = mock(BoschHttpClient.class);
|
||||
final var request = mock(Request.class);
|
||||
final var contentResponse = mock(ContentResponse.class);
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenReturn("http://localhost/smartHome/scenarios")
|
||||
.thenReturn("http://localhost/smartHome/scenarios/1234/triggers");
|
||||
@ -74,10 +90,8 @@ class ScenarioHandlerTest {
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(HttpStatus.OK_200);
|
||||
|
||||
final var handler = new ScenarioHandler();
|
||||
|
||||
// WHEN
|
||||
handler.triggerScenario(httpClient, "Scenario 1");
|
||||
fixture.triggerScenario(httpClient, "Scenario 1");
|
||||
|
||||
// THEN
|
||||
verify(httpClient).getBoschSmartHomeUrl("scenarios");
|
||||
@ -85,19 +99,15 @@ class ScenarioHandlerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void triggerScenarioShouldNoSendPOSTToScenarioNameDoesNotExist() throws Exception {
|
||||
void triggerScenarioShouldNotSendPOSTToScenarioNameDoesNotExist() throws Exception {
|
||||
// GIVEN
|
||||
final var httpClient = mock(BoschHttpClient.class);
|
||||
final var request = mock(Request.class);
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenReturn("http://localhost/smartHome/scenarios")
|
||||
.thenReturn("http://localhost/smartHome/scenarios/1234/triggers");
|
||||
when(httpClient.createRequest(anyString(), any(HttpMethod.class))).thenReturn(request).thenReturn(request);
|
||||
when(httpClient.sendRequest(any(Request.class), any(), any(), any())).thenReturn(existingScenarios);
|
||||
|
||||
final var handler = new ScenarioHandler();
|
||||
|
||||
// WHEN
|
||||
handler.triggerScenario(httpClient, "not existing Scenario");
|
||||
fixture.triggerScenario(httpClient, "not existing Scenario");
|
||||
|
||||
// THEN
|
||||
verify(httpClient).getBoschSmartHomeUrl("scenarios");
|
||||
@ -108,17 +118,13 @@ class ScenarioHandlerTest {
|
||||
@MethodSource("exceptionData")
|
||||
void triggerScenarioShouldNotPanicIfBoschAPIThrowsException(final Exception exception) throws Exception {
|
||||
// GIVEN
|
||||
final var httpClient = mock(BoschHttpClient.class);
|
||||
final var request = mock(Request.class);
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenReturn("http://localhost/smartHome/scenarios")
|
||||
.thenReturn("http://localhost/smartHome/scenarios/1234/triggers");
|
||||
when(httpClient.createRequest(anyString(), any(HttpMethod.class))).thenReturn(request);
|
||||
when(httpClient.sendRequest(any(Request.class), any(), any(), any())).thenThrow(exception);
|
||||
|
||||
final var handler = new ScenarioHandler();
|
||||
|
||||
// WHEN
|
||||
handler.triggerScenario(httpClient, "Scenario 1");
|
||||
fixture.triggerScenario(httpClient, "Scenario 1");
|
||||
|
||||
// THEN
|
||||
verify(httpClient).getBoschSmartHomeUrl("scenarios");
|
||||
@ -128,8 +134,6 @@ class ScenarioHandlerTest {
|
||||
@Test
|
||||
void triggerScenarioShouldNotPanicIfPOSTIsNotSuccessful() throws Exception {
|
||||
// GIVEN
|
||||
final var httpClient = mock(BoschHttpClient.class);
|
||||
final var request = mock(Request.class);
|
||||
final var contentResponse = mock(ContentResponse.class);
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenReturn("http://localhost/smartHome/scenarios")
|
||||
.thenReturn("http://localhost/smartHome/scenarios/1234/triggers");
|
||||
@ -138,10 +142,8 @@ class ScenarioHandlerTest {
|
||||
when(request.send()).thenReturn(contentResponse);
|
||||
when(contentResponse.getStatus()).thenReturn(HttpStatus.METHOD_NOT_ALLOWED_405);
|
||||
|
||||
final var handler = new ScenarioHandler();
|
||||
|
||||
// WHEN
|
||||
handler.triggerScenario(httpClient, "Scenario 1");
|
||||
fixture.triggerScenario(httpClient, "Scenario 1");
|
||||
|
||||
// THEN
|
||||
verify(httpClient).getBoschSmartHomeUrl("scenarios");
|
||||
@ -152,21 +154,27 @@ class ScenarioHandlerTest {
|
||||
@MethodSource("httpExceptionData")
|
||||
void triggerScenarioShouldNotPanicIfPOSTThrowsException(final Exception exception) throws Exception {
|
||||
// GIVEN
|
||||
final var httpClient = mock(BoschHttpClient.class);
|
||||
final var request = mock(Request.class);
|
||||
when(httpClient.getBoschSmartHomeUrl(anyString())).thenReturn("http://localhost/smartHome/scenarios")
|
||||
.thenReturn("http://localhost/smartHome/scenarios/1234/triggers");
|
||||
when(httpClient.createRequest(anyString(), any(HttpMethod.class))).thenReturn(request).thenReturn(request);
|
||||
when(httpClient.sendRequest(any(Request.class), any(), any(), any())).thenReturn(existingScenarios);
|
||||
when(request.send()).thenThrow(exception);
|
||||
|
||||
final var handler = new ScenarioHandler();
|
||||
|
||||
// WHEN
|
||||
handler.triggerScenario(httpClient, "Scenario 1");
|
||||
fixture.triggerScenario(httpClient, "Scenario 1");
|
||||
|
||||
// THEN
|
||||
verify(httpClient).getBoschSmartHomeUrl("scenarios");
|
||||
verify(request).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
void prettyLogScenarios() {
|
||||
Scenario scenario1 = Scenario.createScenario("id1", "Scenario 1", "1708619045411");
|
||||
Scenario scenario2 = Scenario.createScenario("id2", "Scenario 2", "1708619065445");
|
||||
assertEquals(
|
||||
"[\n" + " Scenario{name='Scenario 1', id='id1', lastTimeTriggered='1708619045411'}\n"
|
||||
+ " Scenario{name='Scenario 2', id='id2', lastTimeTriggered='1708619065445'}\n" + "]",
|
||||
fixture.prettyLogScenarios(new Scenario[] { scenario1, scenario2 }));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.boschshc.internal.devices.bridge.dto;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Scenario}.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
class ScenarioTest {
|
||||
|
||||
private Scenario fixture;
|
||||
|
||||
@BeforeEach
|
||||
protected void setUp() throws Exception {
|
||||
fixture = Scenario.createScenario("abc", "My Scenario", "1708845918493");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isValid() {
|
||||
assertTrue(Scenario.isValid(new Scenario[] { fixture }));
|
||||
assertFalse(Scenario.isValid(new Scenario[] { fixture, new Scenario() }));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
assertEquals("Scenario{name='My Scenario', id='abc', lastTimeTriggered='1708845918493'}", fixture.toString());
|
||||
}
|
||||
}
|
@ -13,14 +13,20 @@
|
||||
package org.openhab.binding.boschshc.internal.devices.intrusion;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.openhab.binding.boschshc.internal.devices.AbstractBoschSHCHandlerTest;
|
||||
@ -29,6 +35,8 @@ import org.openhab.binding.boschshc.internal.services.intrusion.actions.arm.dto.
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
@ -64,6 +72,20 @@ class IntrusionDetectionHandlerTest extends AbstractBoschSHCHandlerTest<Intrusio
|
||||
assertEquals("0", armRequest.profileId);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionAndTimeoutAndInterruptedExceptionArguments()")
|
||||
void testHandleCommandArmActionHandleExceptions(Exception e)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
when(getBridgeHandler().postAction(any(), any())).thenThrow(e);
|
||||
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_ARM_ACTION),
|
||||
new StringType("0"));
|
||||
|
||||
verify(getBridgeHandler()).postAction(eq("intrusion/actions/arm"), armActionRequestCaptor.capture());
|
||||
ArmActionRequest armRequest = armActionRequestCaptor.getValue();
|
||||
assertEquals("0", armRequest.profileId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleCommandDisarmAction() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_DISARM_ACTION),
|
||||
@ -71,6 +93,20 @@ class IntrusionDetectionHandlerTest extends AbstractBoschSHCHandlerTest<Intrusio
|
||||
verify(getBridgeHandler()).postAction("intrusion/actions/disarm");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionAndTimeoutAndInterruptedExceptionArguments()")
|
||||
void testHandleCommandDisarmActionHandleExceptions(Exception e)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
when(getBridgeHandler().postAction(any())).thenThrow(e);
|
||||
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_DISARM_ACTION),
|
||||
OnOffType.ON);
|
||||
|
||||
verify(getCallback()).statusUpdated(same(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.COMMUNICATION_ERROR)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleCommandMuteAction() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_MUTE_ACTION),
|
||||
|
@ -15,6 +15,7 @@ package org.openhab.binding.boschshc.internal.devices.shuttercontrol;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -140,4 +141,14 @@ class ShutterControl2HandlerTest extends ShutterControlHandlerTest {
|
||||
ChildProtectionServiceState state = childProtectionServiceStateCaptor.getValue();
|
||||
assertTrue(state.childLockActive);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleCommandChildProtectionInvalidCommand()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
|
||||
getFixture().handleCommand(
|
||||
new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_PROTECTION),
|
||||
DecimalType.ZERO);
|
||||
verify(getBridgeHandler(), times(0)).putState(eq(getDeviceID()), eq("ChildProtection"),
|
||||
childProtectionServiceStateCaptor.capture());
|
||||
}
|
||||
}
|
||||
|
@ -17,22 +17,19 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.openhab.binding.boschshc.internal.devices.AbstractBoschSHCHandlerTest;
|
||||
@ -44,9 +41,7 @@ import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Unit tests for UserStateHandlerTest
|
||||
@ -94,25 +89,41 @@ class UserStateHandlerTest extends AbstractBoschSHCHandlerTest<UserStateHandler>
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@MethodSource("provideExceptions")
|
||||
void testHandleCommandSetStateUpdatesThingStatusOnException(Exception mockException)
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getExecutionExceptionAndInterruptedExceptionArguments()")
|
||||
void testHandleCommandSetStateUpdatesThingStatusOnException(Exception exception)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
reset(getCallback());
|
||||
lenient().when(getBridgeHandler().putState(anyString(), anyString(), any(UserStateServiceState.class)))
|
||||
.thenThrow(mockException);
|
||||
when(getBridgeHandler().putState(anyString(), anyString(), any(UserStateServiceState.class)))
|
||||
.thenThrow(exception);
|
||||
var channel = new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_USER_DEFINED_STATE);
|
||||
|
||||
getFixture().handleCommand(channel, OnOffType.ON);
|
||||
|
||||
verify(getCallback()).getBridge(any(ThingUID.class));
|
||||
|
||||
ThingStatusInfo expectedStatusInfo = new ThingStatusInfo(ThingStatus.OFFLINE,
|
||||
ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
String.format("Error while putting user-defined state for %s", channel.getThingUID().getId()));
|
||||
verify(getCallback()).statusUpdated(same(getThing()), eq(expectedStatusInfo));
|
||||
verify(getCallback()).statusUpdated(same(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.COMMUNICATION_ERROR)));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> provideExceptions() {
|
||||
return Stream.of(Arguments.of(new TimeoutException("test exception")),
|
||||
Arguments.of(new InterruptedException("test exception")));
|
||||
@Test
|
||||
void initializeWithoutId() {
|
||||
when(getThing().getConfiguration()).thenReturn(new Configuration());
|
||||
|
||||
getFixture().initialize();
|
||||
|
||||
verify(getCallback()).statusUpdated(same(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.CONFIGURATION_ERROR)));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.binding.boschshc.internal.tests.common.CommonTestUtils#getBoschShcAndExecutionAndTimeoutAndInterruptedExceptionArguments()")
|
||||
void initializeHandleExceptions(Exception e)
|
||||
throws BoschSHCException, InterruptedException, TimeoutException, ExecutionException {
|
||||
when(getBridgeHandler().getUserStateInfo(anyString())).thenThrow(e);
|
||||
|
||||
getFixture().initialize();
|
||||
|
||||
verify(getCallback()).statusUpdated(same(getThing()),
|
||||
argThat(status -> status.getStatus().equals(ThingStatus.OFFLINE)
|
||||
&& status.getStatusDetail().equals(ThingStatusDetail.CONFIGURATION_ERROR)));
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,9 @@ import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.ConnectException;
|
||||
@ -48,6 +50,7 @@ import org.mockito.quality.Strictness;
|
||||
import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
|
||||
import org.openhab.binding.boschshc.internal.devices.bridge.dto.PublicInformation;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
/**
|
||||
@ -128,6 +131,7 @@ class BridgeDiscoveryParticipantTest {
|
||||
@Test
|
||||
void testCreateResult() throws Exception {
|
||||
DiscoveryResult result = fixture.createResult(shcBridge);
|
||||
|
||||
assertNotNull(result);
|
||||
assertThat(result.getBindingId(), is(BoschSHCBindingConstants.BINDING_ID));
|
||||
assertThat(result.getThingUID().getId(), is("192-168-0-123"));
|
||||
@ -138,19 +142,23 @@ class BridgeDiscoveryParticipantTest {
|
||||
@Test
|
||||
void testCreateResultOtherDevice() throws Exception {
|
||||
DiscoveryResult result = fixture.createResult(otherDevice);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateResultNoIPAddress() throws Exception {
|
||||
when(shcBridge.getHostAddresses()).thenReturn(new String[] { "" });
|
||||
|
||||
DiscoveryResult result = fixture.createResult(shcBridge);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetThingUID() throws Exception {
|
||||
ThingUID thingUID = fixture.getThingUID(shcBridge);
|
||||
|
||||
assertNotNull(thingUID);
|
||||
assertThat(thingUID.getBindingId(), is(BoschSHCBindingConstants.BINDING_ID));
|
||||
assertThat(thingUID.getId(), is("192-168-0-123"));
|
||||
@ -165,6 +173,7 @@ class BridgeDiscoveryParticipantTest {
|
||||
void testGetBridgeAddress() throws Exception {
|
||||
@Nullable
|
||||
PublicInformation bridgeInformation = fixture.discoverBridge("192.168.0.123");
|
||||
|
||||
assertThat(bridgeInformation, not(nullValue()));
|
||||
assertThat(bridgeInformation.shcIpAddress, is("192.168.0.123"));
|
||||
}
|
||||
@ -178,6 +187,7 @@ class BridgeDiscoveryParticipantTest {
|
||||
void testGetPublicInformationFromPossibleBridgeAddress() throws Exception {
|
||||
@Nullable
|
||||
PublicInformation bridgeInformation = fixture.getPublicInformationFromPossibleBridgeAddress("192.168.0.123");
|
||||
|
||||
assertThat(bridgeInformation, not(nullValue()));
|
||||
assertThat(bridgeInformation.shcIpAddress, is("192.168.0.123"));
|
||||
}
|
||||
@ -187,6 +197,7 @@ class BridgeDiscoveryParticipantTest {
|
||||
when(contentResponse.getContentAsString()).thenReturn("{\"nothing\":\"useful\"}");
|
||||
|
||||
fixture = new BridgeDiscoveryParticipant(mockHttpClient);
|
||||
|
||||
assertThat(fixture.getPublicInformationFromPossibleBridgeAddress("192.168.0.123"), is(nullValue()));
|
||||
}
|
||||
|
||||
@ -195,6 +206,7 @@ class BridgeDiscoveryParticipantTest {
|
||||
when(contentResponse.getStatus()).thenReturn(HttpStatus.BAD_REQUEST_400);
|
||||
|
||||
fixture = new BridgeDiscoveryParticipant(mockHttpClient);
|
||||
|
||||
assertThat(fixture.getPublicInformationFromPossibleBridgeAddress("192.168.0.123"), is(nullValue()));
|
||||
}
|
||||
|
||||
@ -207,4 +219,13 @@ class BridgeDiscoveryParticipantTest {
|
||||
PublicInformation result2 = fixture.getOrComputePublicInformation("192.168.0.123");
|
||||
assertSame(result, result2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPublicConstructor() {
|
||||
HttpClientFactory httpClientFactory = mock(HttpClientFactory.class);
|
||||
|
||||
fixture = new BridgeDiscoveryParticipant(httpClientFactory);
|
||||
|
||||
verify(httpClientFactory).createHttpClient(eq(BoschSHCBindingConstants.BINDING_ID), any());
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@ -77,10 +78,35 @@ class ThingDiscoveryServiceTest {
|
||||
when(bridgeHandler.getThing()).thenReturn(mockBridge);
|
||||
}
|
||||
|
||||
@Test
|
||||
void initialize() {
|
||||
fixture.initialize();
|
||||
verify(bridgeHandler).registerDiscoveryListener(fixture);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStartScan() throws InterruptedException {
|
||||
mockBridgeCalls();
|
||||
|
||||
Device device = new Device();
|
||||
device.name = "My Smart Plug";
|
||||
device.deviceModel = "PSM";
|
||||
device.id = "hdm:HomeMaticIP:3014F711A00004953859F31B";
|
||||
device.deviceServiceIds = List.of("PowerMeter", "PowerSwitch", "PowerSwitchProgram", "Routing");
|
||||
|
||||
List<Device> devices = new ArrayList<>();
|
||||
devices.add(device);
|
||||
when(bridgeHandler.getDevices()).thenReturn(devices);
|
||||
|
||||
UserDefinedState userDefinedState = new UserDefinedState();
|
||||
userDefinedState.setName("My State");
|
||||
userDefinedState.setId("23d34fa6-382a-444d-8aae-89c706e22158");
|
||||
userDefinedState.setState(true);
|
||||
|
||||
List<UserDefinedState> userDefinedStates = new ArrayList<>();
|
||||
userDefinedStates.add(userDefinedState);
|
||||
when(bridgeHandler.getUserStates()).thenReturn(userDefinedStates);
|
||||
|
||||
fixture.activate();
|
||||
fixture.startScan();
|
||||
|
||||
@ -268,6 +294,15 @@ class ThingDiscoveryServiceTest {
|
||||
verify(discoveryListener, times(2)).thingDiscovered(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void dispose() {
|
||||
Bridge thing = mock(Bridge.class);
|
||||
when(thing.getUID()).thenReturn(new ThingUID(BoschSHCBindingConstants.THING_TYPE_SHC, "shc123456"));
|
||||
when(bridgeHandler.getThing()).thenReturn(thing);
|
||||
fixture.dispose();
|
||||
verify(bridgeHandler).unregisterDiscoveryListener();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getThingTypeUIDLightControl2ChildDevice() {
|
||||
Device device = new Device();
|
||||
|
@ -71,4 +71,9 @@ class UserStateServiceStateTest {
|
||||
subject.setState(true);
|
||||
assertEquals(OnOffType.ON, subject.toOnOffType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
assertEquals("UserStateServiceState{state=false, type='userdefinedstates'}", subject.toString());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.boschshc.internal.tests.common;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
|
||||
|
||||
/**
|
||||
* Common utilities used in unit tests.
|
||||
*
|
||||
* @author David Pace - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public final class CommonTestUtils {
|
||||
|
||||
public static final String TEST_EXCEPTION_MESSAGE = "Test exception";
|
||||
|
||||
private CommonTestUtils() {
|
||||
// Utility Class
|
||||
}
|
||||
|
||||
public static List<Exception> getExecutionExceptionAndInterruptedExceptionArguments() {
|
||||
return List.of(new ExecutionException(TEST_EXCEPTION_MESSAGE, null),
|
||||
new InterruptedException(TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
public static List<Exception> getExceutionExceptionAndRuntimeExceptionArguments() {
|
||||
return List.of(new ExecutionException(TEST_EXCEPTION_MESSAGE, null),
|
||||
new RuntimeException(TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
public static List<Exception> getBoschShcAndExecutionAndTimeoutExceptionArguments() {
|
||||
return List.of(new BoschSHCException(TEST_EXCEPTION_MESSAGE),
|
||||
new ExecutionException(TEST_EXCEPTION_MESSAGE, null), new TimeoutException(TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
public static List<Exception> getBoschShcAndExecutionAndTimeoutAndInterruptedExceptionArguments() {
|
||||
return List.of(new BoschSHCException(TEST_EXCEPTION_MESSAGE),
|
||||
new ExecutionException(TEST_EXCEPTION_MESSAGE, null), new TimeoutException(TEST_EXCEPTION_MESSAGE),
|
||||
new InterruptedException(TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
public static List<Exception> getExecutionAndTimeoutAndInterruptedExceptionArguments() {
|
||||
return List.of(new ExecutionException(TEST_EXCEPTION_MESSAGE, null),
|
||||
new TimeoutException(TEST_EXCEPTION_MESSAGE), new InterruptedException(TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
public static List<Exception> getExecutionAndTimeoutExceptionArguments() {
|
||||
return List.of(new ExecutionException(TEST_EXCEPTION_MESSAGE, null),
|
||||
new TimeoutException(TEST_EXCEPTION_MESSAGE));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user