2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.sensibo.internal.handler;
15 import static org.junit.jupiter.api.Assertions.*;
17 import java.io.IOException;
18 import java.util.HashMap;
19 import java.util.List;
22 import org.junit.jupiter.api.Test;
23 import org.mockito.ArgumentCaptor;
24 import org.mockito.ArgumentMatchers;
25 import org.mockito.Mockito;
26 import org.openhab.binding.sensibo.internal.SensiboBindingConstants;
27 import org.openhab.binding.sensibo.internal.SensiboCommunicationException;
28 import org.openhab.binding.sensibo.internal.WireHelper;
29 import org.openhab.binding.sensibo.internal.dto.poddetails.PodDetailsDTO;
30 import org.openhab.binding.sensibo.internal.handler.SensiboSkyHandler.StateChange;
31 import org.openhab.binding.sensibo.internal.model.SensiboModel;
32 import org.openhab.binding.sensibo.internal.model.SensiboSky;
33 import org.openhab.core.config.core.Configuration;
34 import org.openhab.core.library.types.DecimalType;
35 import org.openhab.core.library.types.QuantityType;
36 import org.openhab.core.library.unit.ImperialUnits;
37 import org.openhab.core.library.unit.SIUnits;
38 import org.openhab.core.thing.Channel;
39 import org.openhab.core.thing.ChannelUID;
40 import org.openhab.core.thing.Thing;
41 import org.openhab.core.thing.ThingUID;
44 * @author Arne Seime - Initial contribution
46 public class SensiboSkyHandlerTest {
48 private final WireHelper wireHelper = new WireHelper();
51 public void testStateChangeValidation() throws IOException, SensiboCommunicationException {
52 final PodDetailsDTO rsp = wireHelper.deSerializeResponse("/get_pod_details_response.json", PodDetailsDTO.class);
53 SensiboSky sky = new SensiboSky(rsp);
54 Thing thing = Mockito.mock(Thing.class);
55 SensiboSkyHandler handler = new SensiboSkyHandler(thing);
58 StateChange stateChangeCheck = handler.checkStateChangeValid(sky, SensiboSkyHandler.TARGET_TEMPERATURE_PROPERTY,
59 new DecimalType(123));
60 assertFalse(stateChangeCheck.valid);
61 assertNotNull(stateChangeCheck.validationMessage);
62 assertTrue(handler.checkStateChangeValid(sky, SensiboSkyHandler.TARGET_TEMPERATURE_PROPERTY,
63 new DecimalType(10)).valid);
66 StateChange stateChangeCheckMode = handler.checkStateChangeValid(sky, "mode", "invalid");
67 assertFalse(stateChangeCheckMode.valid);
68 assertNotNull(stateChangeCheckMode.validationMessage);
69 assertTrue(handler.checkStateChangeValid(sky, "mode", "auto").valid);
72 StateChange stateChangeCheckSwing = handler.checkStateChangeValid(sky, "swing", "invalid");
73 assertFalse(stateChangeCheckSwing.valid);
74 assertNotNull(stateChangeCheckSwing.validationMessage);
75 assertTrue(handler.checkStateChangeValid(sky, "swing", "stopped").valid);
78 StateChange stateChangeCheckFanLevel = handler.checkStateChangeValid(sky, "fanLevel", "invalid");
79 assertFalse(stateChangeCheckFanLevel.valid);
80 assertNotNull(stateChangeCheckFanLevel.validationMessage);
81 assertTrue(handler.checkStateChangeValid(sky, "fanLevel", "high").valid);
85 public void testTemperatureConversion() throws IOException {
86 final PodDetailsDTO rsp = wireHelper.deSerializeResponse("/get_pod_details_response.json", PodDetailsDTO.class);
87 SensiboSky sky = new SensiboSky(rsp);
88 Thing thing = Mockito.mock(Thing.class);
89 Mockito.when(thing.getUID()).thenReturn(new ThingUID("sensibo:account:thinguid"));
91 Map<String, Object> config = new HashMap<>();
92 config.put("macAddress", sky.getMacAddress());
93 Mockito.when(thing.getConfiguration()).thenReturn(new Configuration(config));
95 SensiboSkyHandler handler = Mockito.spy(new SensiboSkyHandler(thing));
98 SensiboModel model = new SensiboModel(0);
101 // Once with Celcius argument
102 handler.handleCommand(new ChannelUID(thing.getUID(), SensiboBindingConstants.CHANNEL_TARGET_TEMPERATURE),
103 new QuantityType<>(50, ImperialUnits.FAHRENHEIT), model);
105 // Once with Fahrenheit
106 handler.handleCommand(new ChannelUID(thing.getUID(), SensiboBindingConstants.CHANNEL_TARGET_TEMPERATURE),
107 new QuantityType<>(10, SIUnits.CELSIUS), model);
109 // Once with Decimal directly
110 handler.handleCommand(new ChannelUID(thing.getUID(), SensiboBindingConstants.CHANNEL_TARGET_TEMPERATURE),
111 new DecimalType(10), model);
113 ArgumentCaptor<DecimalType> valueCapture = ArgumentCaptor.forClass(DecimalType.class);
114 Mockito.verify(handler, Mockito.times(3)).updateAcState(ArgumentMatchers.eq(sky), ArgumentMatchers.anyString(),
115 valueCapture.capture());
116 assertEquals(new DecimalType(10), valueCapture.getValue());
120 public void testAddDynamicChannelsMarco() throws IOException, SensiboCommunicationException {
121 testAddDynamicChannels("/get_pod_details_response_marco.json");
125 public void testAddDynamicChannels() throws IOException, SensiboCommunicationException {
126 testAddDynamicChannels("/get_pod_details_response.json");
129 private void testAddDynamicChannels(String podDetailsResponse) throws IOException, SensiboCommunicationException {
130 final PodDetailsDTO rsp = wireHelper.deSerializeResponse(podDetailsResponse, PodDetailsDTO.class);
131 SensiboSky sky = new SensiboSky(rsp);
132 Thing thing = Mockito.mock(Thing.class);
133 Mockito.when(thing.getUID()).thenReturn(new ThingUID("sensibo:account:thinguid"));
134 SensiboSkyHandler handler = Mockito.spy(new SensiboSkyHandler(thing));
135 List<Channel> dynamicChannels = handler.createDynamicChannels(sky);
136 assertTrue(!dynamicChannels.isEmpty());