[mielecloud] Fix washing machine can be started channel is not updated (#12583)
* Add tests to ensure that parsing works correctly * Fetch /actions on server sent event * Refactor onServerSentEvent * Remove ActionStateFetcher * Manually construct BigDecimal Signed-off-by: Björn Lange <bjoern.lange@itemis.de>
This commit is contained in:
@@ -1,178 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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.mielecloud.internal.webservice;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.openhab.binding.mielecloud.internal.util.MockUtil;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.api.DeviceState;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.api.json.StateType;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.exception.AuthorizationFailedException;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.exception.MieleWebserviceException;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.exception.TooManyRequestsException;
|
||||
|
||||
/**
|
||||
* @author Björn Lange - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ActionStateFetcherTest {
|
||||
private ScheduledExecutorService mockImmediatelyExecutingExecutorService() {
|
||||
ScheduledExecutorService scheduler = mock(ScheduledExecutorService.class);
|
||||
when(scheduler.submit(ArgumentMatchers.<Runnable> any()))
|
||||
.thenAnswer(new Answer<@Nullable ScheduledFuture<?>>() {
|
||||
@Override
|
||||
@Nullable
|
||||
public ScheduledFuture<?> answer(@Nullable InvocationOnMock invocation) throws Throwable {
|
||||
((Runnable) MockUtil.requireNonNull(invocation).getArgument(0)).run();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchActionsIsInvokedWhenInitialDeviceStateIsSet() {
|
||||
// given:
|
||||
ScheduledExecutorService scheduler = mockImmediatelyExecutingExecutorService();
|
||||
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
DeviceState deviceState = mock(DeviceState.class);
|
||||
DeviceState newDeviceState = mock(DeviceState.class);
|
||||
ActionStateFetcher actionsfetcher = new ActionStateFetcher(() -> webservice, scheduler);
|
||||
|
||||
when(deviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
when(newDeviceState.getStateType()).thenReturn(Optional.of(StateType.END_PROGRAMMED));
|
||||
|
||||
// when:
|
||||
actionsfetcher.onDeviceStateUpdated(deviceState);
|
||||
|
||||
// then:
|
||||
verify(webservice).fetchActions(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchActionsIsInvokedOnStateTransition() {
|
||||
// given:
|
||||
ScheduledExecutorService scheduler = mockImmediatelyExecutingExecutorService();
|
||||
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
DeviceState deviceState = mock(DeviceState.class);
|
||||
DeviceState newDeviceState = mock(DeviceState.class);
|
||||
ActionStateFetcher actionsfetcher = new ActionStateFetcher(() -> webservice, scheduler);
|
||||
|
||||
when(deviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
when(newDeviceState.getStateType()).thenReturn(Optional.of(StateType.END_PROGRAMMED));
|
||||
|
||||
actionsfetcher.onDeviceStateUpdated(deviceState);
|
||||
|
||||
// when:
|
||||
actionsfetcher.onDeviceStateUpdated(newDeviceState);
|
||||
|
||||
// then:
|
||||
verify(webservice, times(2)).fetchActions(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchActionsIsNotInvokedWhenNoStateTransitionOccurrs() {
|
||||
// given:
|
||||
ScheduledExecutorService scheduler = mockImmediatelyExecutingExecutorService();
|
||||
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
DeviceState deviceState = mock(DeviceState.class);
|
||||
DeviceState newDeviceState = mock(DeviceState.class);
|
||||
ActionStateFetcher actionsfetcher = new ActionStateFetcher(() -> webservice, scheduler);
|
||||
|
||||
when(deviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
when(newDeviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
|
||||
actionsfetcher.onDeviceStateUpdated(deviceState);
|
||||
|
||||
// when:
|
||||
actionsfetcher.onDeviceStateUpdated(newDeviceState);
|
||||
|
||||
// then:
|
||||
verify(webservice, times(1)).fetchActions(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchActionsFailsWithAMieleWebserviceExceptionThenNoExceptionIsThrown() {
|
||||
// given:
|
||||
ScheduledExecutorService scheduler = mockImmediatelyExecutingExecutorService();
|
||||
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
doThrow(new MieleWebserviceException("It went wrong", ConnectionError.REQUEST_EXECUTION_FAILED))
|
||||
.when(webservice).fetchActions(any());
|
||||
|
||||
DeviceState deviceState = mock(DeviceState.class);
|
||||
when(deviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
|
||||
ActionStateFetcher actionsfetcher = new ActionStateFetcher(() -> webservice, scheduler);
|
||||
|
||||
// when:
|
||||
actionsfetcher.onDeviceStateUpdated(deviceState);
|
||||
|
||||
// then:
|
||||
verify(webservice, times(1)).fetchActions(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchActionsFailsWithAnAuthorizationFailedExceptionThenNoExceptionIsThrown() {
|
||||
// given:
|
||||
ScheduledExecutorService scheduler = mockImmediatelyExecutingExecutorService();
|
||||
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
doThrow(new AuthorizationFailedException("Authorization failed")).when(webservice).fetchActions(any());
|
||||
|
||||
DeviceState deviceState = mock(DeviceState.class);
|
||||
when(deviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
|
||||
ActionStateFetcher actionsfetcher = new ActionStateFetcher(() -> webservice, scheduler);
|
||||
|
||||
// when:
|
||||
actionsfetcher.onDeviceStateUpdated(deviceState);
|
||||
|
||||
// then:
|
||||
verify(webservice, times(1)).fetchActions(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchActionsFailsWithATooManyRequestsExceptionThenNoExceptionIsThrown() {
|
||||
// given:
|
||||
ScheduledExecutorService scheduler = mockImmediatelyExecutingExecutorService();
|
||||
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
doThrow(new TooManyRequestsException("Too many requests", null)).when(webservice).fetchActions(any());
|
||||
|
||||
DeviceState deviceState = mock(DeviceState.class);
|
||||
when(deviceState.getStateType()).thenReturn(Optional.of(StateType.RUNNING));
|
||||
|
||||
ActionStateFetcher actionsfetcher = new ActionStateFetcher(() -> webservice, scheduler);
|
||||
|
||||
// when:
|
||||
actionsfetcher.onDeviceStateUpdated(deviceState);
|
||||
|
||||
// then:
|
||||
verify(webservice, times(1)).fetchActions(any());
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import org.openhab.binding.mielecloud.internal.webservice.retry.AuthorizationFai
|
||||
import org.openhab.binding.mielecloud.internal.webservice.retry.NTimesRetryStrategy;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.retry.RetryStrategy;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.retry.RetryStrategyCombiner;
|
||||
import org.openhab.binding.mielecloud.internal.webservice.sse.ServerSentEvent;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
|
||||
/**
|
||||
@@ -58,7 +59,8 @@ public class DefaultMieleWebserviceTest {
|
||||
|
||||
private static final String SERVER_ADDRESS = "https://api.mcs3.miele.com";
|
||||
private static final String ENDPOINT_DEVICES = SERVER_ADDRESS + "/v1/devices/";
|
||||
private static final String ENDPOINT_ACTIONS = ENDPOINT_DEVICES + DEVICE_IDENTIFIER + "/actions";
|
||||
private static final String ENDPOINT_EXTENSION_ACTIONS = "/actions";
|
||||
private static final String ENDPOINT_ACTIONS = ENDPOINT_DEVICES + DEVICE_IDENTIFIER + ENDPOINT_EXTENSION_ACTIONS;
|
||||
private static final String ENDPOINT_LOGOUT = SERVER_ADDRESS + "/thirdparty/logout";
|
||||
|
||||
private static final String ACCESS_TOKEN = "DE_0123456789abcdef0123456789abcdef";
|
||||
@@ -721,6 +723,214 @@ public class DefaultMieleWebserviceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receivingSseActionsEventNotifiesConnectionAlive() throws Exception {
|
||||
// given:
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
var connectionStatusListener = mock(ConnectionStatusListener.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.addConnectionStatusListener(connectionStatusListener);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS, "{}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verify(connectionStatusListener).onConnectionAlive();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receivingSseActionsEventWithNonJsonPayloadDoesNothing() throws Exception {
|
||||
// given:
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.setAccessToken(ACCESS_TOKEN);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS,
|
||||
"{\"" + DEVICE_IDENTIFIER + "\": {}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verifyNoMoreInteractions(dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receivingSseActionsEventFetchesActionsForADevice() throws Exception {
|
||||
// given:
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_ACTIONS, ACCESS_TOKEN)).thenReturn(request);
|
||||
|
||||
var response = createContentResponseMock(200, "{}");
|
||||
when(request.send()).thenReturn(response);
|
||||
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.setAccessToken(ACCESS_TOKEN);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS,
|
||||
"{\"" + DEVICE_IDENTIFIER + "\": {}}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verify(dispatcher).dispatchActionStateUpdates(eq(DEVICE_IDENTIFIER), any());
|
||||
verifyNoMoreInteractions(dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receivingSseActionsEventFetchesActionsForMultipleDevices() throws Exception {
|
||||
// given:
|
||||
var otherRequest = mock(Request.class);
|
||||
var otherDeviceIdentifier = "000124430017";
|
||||
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_ACTIONS, ACCESS_TOKEN)).thenReturn(request);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_DEVICES + otherDeviceIdentifier + ENDPOINT_EXTENSION_ACTIONS,
|
||||
ACCESS_TOKEN)).thenReturn(otherRequest);
|
||||
|
||||
var response = createContentResponseMock(200, "{}");
|
||||
when(request.send()).thenReturn(response);
|
||||
when(otherRequest.send()).thenReturn(response);
|
||||
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.setAccessToken(ACCESS_TOKEN);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS,
|
||||
"{\"" + DEVICE_IDENTIFIER + "\": {}, \"" + otherDeviceIdentifier + "\": {}}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verify(dispatcher).dispatchActionStateUpdates(eq(DEVICE_IDENTIFIER), any());
|
||||
verify(dispatcher).dispatchActionStateUpdates(eq(otherDeviceIdentifier), any());
|
||||
verifyNoMoreInteractions(dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchingActionsAfterReceivingSseActionsEventFailsForADeviceThenNothingHappensForThisDevice()
|
||||
throws Exception {
|
||||
// given:
|
||||
var otherRequest = mock(Request.class);
|
||||
var otherDeviceIdentifier = "000124430017";
|
||||
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_ACTIONS, ACCESS_TOKEN)).thenReturn(request);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_DEVICES + otherDeviceIdentifier + ENDPOINT_EXTENSION_ACTIONS,
|
||||
ACCESS_TOKEN)).thenReturn(otherRequest);
|
||||
|
||||
var response = createContentResponseMock(200, "{}");
|
||||
when(request.send()).thenReturn(response);
|
||||
var otherResponse = createContentResponseMock(405, "{\"message\": \"HTTP 405 Method Not Allowed\"}");
|
||||
when(otherRequest.send()).thenReturn(otherResponse);
|
||||
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.setAccessToken(ACCESS_TOKEN);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS,
|
||||
"{\"" + DEVICE_IDENTIFIER + "\": {}, \"" + otherDeviceIdentifier + "\": {}}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verify(dispatcher).dispatchActionStateUpdates(eq(DEVICE_IDENTIFIER), any());
|
||||
verifyNoMoreInteractions(dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchingActionsAfterReceivingSseActionsEventFailsBecauseOfTooManyRequestsThenNothingHappens()
|
||||
throws Exception {
|
||||
// given:
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_ACTIONS, ACCESS_TOKEN)).thenReturn(request);
|
||||
|
||||
var response = createContentResponseMock(429, "{\"message\": \"Too Many Requests\"}");
|
||||
when(request.send()).thenReturn(response);
|
||||
|
||||
var headerFields = mock(HttpFields.class);
|
||||
when(headerFields.containsKey(anyString())).thenReturn(false);
|
||||
when(response.getHeaders()).thenReturn(headerFields);
|
||||
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.setAccessToken(ACCESS_TOKEN);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS,
|
||||
"{\"" + DEVICE_IDENTIFIER + "\": {}}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verifyNoMoreInteractions(dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchingActionsAfterReceivingSseActionsEventFailsBecauseOfAuthorizationFailedThenThisIsNotifiedToListeners()
|
||||
throws Exception {
|
||||
// given:
|
||||
var requestFactory = mock(RequestFactory.class);
|
||||
when(requestFactory.createGetRequest(ENDPOINT_ACTIONS, ACCESS_TOKEN)).thenReturn(request);
|
||||
|
||||
var response = createContentResponseMock(401, "{\"message\": \"Unauthorized\"}");
|
||||
when(request.send()).thenReturn(response);
|
||||
|
||||
var dispatcher = mock(DeviceStateDispatcher.class);
|
||||
var scheduler = mock(ScheduledExecutorService.class);
|
||||
|
||||
var connectionStatusListener = mock(ConnectionStatusListener.class);
|
||||
|
||||
try (var webservice = new DefaultMieleWebservice(requestFactory, new NTimesRetryStrategy(0), dispatcher,
|
||||
scheduler)) {
|
||||
webservice.addConnectionStatusListener(connectionStatusListener);
|
||||
webservice.setAccessToken(ACCESS_TOKEN);
|
||||
|
||||
var actionsEvent = new ServerSentEvent(DefaultMieleWebservice.SSE_EVENT_TYPE_ACTIONS,
|
||||
"{\"" + DEVICE_IDENTIFIER + "\": {}}");
|
||||
|
||||
// when:
|
||||
webservice.onServerSentEvent(actionsEvent);
|
||||
|
||||
// then:
|
||||
verifyNoMoreInteractions(dispatcher);
|
||||
verify(connectionStatusListener).onConnectionError(ConnectionError.AUTHORIZATION_FAILED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link RetryStrategy} for testing purposes. No exceptions will be catched.
|
||||
*
|
||||
|
||||
@@ -18,6 +18,7 @@ import static org.mockito.Mockito.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -128,9 +129,11 @@ public class ActionsStateTest {
|
||||
|
||||
// when:
|
||||
boolean canBeStarted = actionState.canBeStarted();
|
||||
boolean canBeStopped = actionState.canBeStopped();
|
||||
|
||||
// then:
|
||||
assertTrue(canBeStarted);
|
||||
assertFalse(canBeStopped);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -141,9 +144,27 @@ public class ActionsStateTest {
|
||||
when(actions.getProcessAction()).thenReturn(Collections.singletonList(ProcessAction.STOP));
|
||||
|
||||
// when:
|
||||
boolean canBeStarted = actionState.canBeStarted();
|
||||
boolean canBeStopped = actionState.canBeStopped();
|
||||
|
||||
// then:
|
||||
assertFalse(canBeStarted);
|
||||
assertTrue(canBeStopped);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueWhenProcessActionStartAndStopAreAvailable() {
|
||||
// given:
|
||||
Actions actions = mock(Actions.class);
|
||||
ActionsState actionState = new ActionsState(DEVICE_IDENTIFIER, actions);
|
||||
when(actions.getProcessAction()).thenReturn(List.of(ProcessAction.START, ProcessAction.STOP));
|
||||
|
||||
// when:
|
||||
boolean canBeStarted = actionState.canBeStarted();
|
||||
boolean canBeStopped = actionState.canBeStopped();
|
||||
|
||||
// then:
|
||||
assertTrue(canBeStarted);
|
||||
assertTrue(canBeStopped);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 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.mielecloud.internal.webservice.api.json;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.openhab.binding.mielecloud.internal.util.ResourceUtil.getResourceAsString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Björn Lange - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ActionsCollectionTest {
|
||||
@Test
|
||||
public void canCreateActionsCollection() throws IOException {
|
||||
// given:
|
||||
String json = getResourceAsString(
|
||||
"/org/openhab/binding/mielecloud/internal/webservice/api/json/actionsCollection.json");
|
||||
|
||||
// when:
|
||||
ActionsCollection collection = ActionsCollection.fromJson(json);
|
||||
|
||||
// then:
|
||||
assertEquals(Collections.singleton("000123456789"), collection.getDeviceIdentifiers());
|
||||
Actions actions = collection.getActions("000123456789");
|
||||
|
||||
assertEquals(List.of(ProcessAction.START, ProcessAction.STOP), actions.getProcessAction());
|
||||
assertEquals(Collections.singletonList(Light.DISABLE), actions.getLight());
|
||||
assertEquals(Optional.empty(), actions.getStartTime());
|
||||
assertEquals(Collections.singletonList(123), actions.getProgramId());
|
||||
assertEquals(Optional.of(true), actions.getPowerOn());
|
||||
assertEquals(Optional.of(false), actions.getPowerOff());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void creatingActionsCollectionFromInvalidJsonThrowsMieleSyntaxException() {
|
||||
// given:
|
||||
String invalidJson = "{\":{}}";
|
||||
|
||||
// when:
|
||||
assertThrows(MieleSyntaxException.class, () -> {
|
||||
ActionsCollection.fromJson(invalidJson);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canCreateActionsCollectionWithLargeProgramID() throws IOException {
|
||||
// given:
|
||||
String json = "{\"mac-00124B000AE539D6\": {}}";
|
||||
|
||||
// when:
|
||||
DeviceCollection collection = DeviceCollection.fromJson(json);
|
||||
|
||||
// then:
|
||||
assertEquals(Collections.singleton("mac-00124B000AE539D6"), collection.getDeviceIdentifiers());
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -100,4 +102,28 @@ public class ActionsTest {
|
||||
// then:
|
||||
assertEquals(Arrays.asList(1, 2, 3, 4), actions.getProgramId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processActionContainsSingleEntryWhenThereIsOneProcessAction() {
|
||||
// given:
|
||||
String json = "{ \"processAction\": [1] }";
|
||||
|
||||
// when:
|
||||
Actions actions = new Gson().fromJson(json, Actions.class);
|
||||
|
||||
// then:
|
||||
assertEquals(Collections.singletonList(ProcessAction.START), actions.getProcessAction());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processActionContainsTwoEntriesWhenThereAreTwoProcessActions() {
|
||||
// given:
|
||||
String json = "{ \"processAction\": [1,2] }";
|
||||
|
||||
// when:
|
||||
Actions actions = new Gson().fromJson(json, Actions.class);
|
||||
|
||||
// then:
|
||||
assertEquals(List.of(ProcessAction.START, ProcessAction.STOP), actions.getProcessAction());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"000123456789": {
|
||||
"processAction": [1, 2],
|
||||
"light": [2],
|
||||
"ambientLight": [],
|
||||
"startTime": null,
|
||||
"ventilationStep": [],
|
||||
"programId": [123],
|
||||
"targetTemperature": [],
|
||||
"deviceName": false,
|
||||
"powerOn": true,
|
||||
"powerOff": false,
|
||||
"colors": [],
|
||||
"modes": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user