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.tplinksmarthome.internal.handler;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.ArgumentMatchers.*;
17 import static org.mockito.Mockito.*;
18 import static org.openhab.binding.tplinksmarthome.internal.ChannelUIDConstants.CHANNEL_UID_SWITCH;
19 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.*;
21 import java.io.IOException;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.junit.jupiter.api.AfterEach;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.junit.jupiter.api.extension.ExtendWith;
28 import org.mockito.ArgumentCaptor;
29 import org.mockito.Mock;
30 import org.mockito.Mockito;
31 import org.mockito.junit.jupiter.MockitoExtension;
32 import org.mockito.junit.jupiter.MockitoSettings;
33 import org.mockito.quality.Strictness;
34 import org.openhab.binding.tplinksmarthome.internal.ChannelUIDConstants;
35 import org.openhab.binding.tplinksmarthome.internal.Commands;
36 import org.openhab.binding.tplinksmarthome.internal.Connection;
37 import org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeConfiguration;
38 import org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeDiscoveryService;
39 import org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeThingType;
40 import org.openhab.binding.tplinksmarthome.internal.device.SmartHomeDevice;
41 import org.openhab.binding.tplinksmarthome.internal.model.ModelTestUtil;
42 import org.openhab.core.config.core.Configuration;
43 import org.openhab.core.library.types.OnOffType;
44 import org.openhab.core.library.types.QuantityType;
45 import org.openhab.core.thing.ChannelUID;
46 import org.openhab.core.thing.Thing;
47 import org.openhab.core.thing.ThingStatus;
48 import org.openhab.core.thing.ThingStatusInfo;
49 import org.openhab.core.thing.binding.ThingHandlerCallback;
50 import org.openhab.core.types.RefreshType;
51 import org.openhab.core.types.State;
54 * Tests cases for {@link SmartHomeHandler} class.
56 * @author Hilbrand Bouwkamp - Initial contribution
58 @ExtendWith(MockitoExtension.class)
59 @MockitoSettings(strictness = Strictness.LENIENT)
61 public class SmartHomeHandlerTest {
63 private @NonNullByDefault({}) SmartHomeHandler handler;
65 private @Mock @NonNullByDefault({}) Connection connection;
66 private @Mock @NonNullByDefault({}) ThingHandlerCallback callback;
67 private @Mock @NonNullByDefault({}) Thing thing;
68 private @Mock @NonNullByDefault({}) SmartHomeDevice smartHomeDevice;
69 private @Mock @NonNullByDefault({}) TPLinkSmartHomeDiscoveryService discoveryService;
71 private final Configuration configuration = new Configuration();
74 public void setUp() throws IOException {
75 configuration.put(CONFIG_IP, "localhost");
76 configuration.put(CONFIG_REFRESH, 1);
77 when(thing.getConfiguration()).thenReturn(configuration);
78 lenient().when(smartHomeDevice.getUpdateCommand()).thenReturn(Commands.getSysinfo());
79 lenient().when(connection.sendCommand(Commands.getSysinfo()))
80 .thenReturn(ModelTestUtil.readJson("plug_get_sysinfo_response"));
81 handler = new SmartHomeHandler(thing, smartHomeDevice, TPLinkSmartHomeThingType.HS100, discoveryService) {
83 Connection createConnection(TPLinkSmartHomeConfiguration config) {
87 lenient().when(smartHomeDevice.handleCommand(eq(CHANNEL_UID_SWITCH), any())).thenReturn(true);
88 lenient().when(callback.isChannelLinked(any())).thenReturn(true);
89 handler.setCallback(callback);
98 public void testInitializeShouldCallTheCallback() throws InterruptedException {
100 ArgumentCaptor<ThingStatusInfo> statusInfoCaptor = ArgumentCaptor.forClass(ThingStatusInfo.class);
102 verify(callback).statusUpdated(eq(thing), statusInfoCaptor.capture());
103 ThingStatusInfo thingStatusInfo = statusInfoCaptor.getValue();
104 assertEquals(ThingStatus.UNKNOWN, thingStatusInfo.getStatus(), "Device should be unknown");
108 public void testHandleCommandRefreshType() {
109 handler.initialize();
110 assertHandleCommandRefreshType(-53);
114 public void testHandleCommandRefreshTypeRangeExtender() throws IOException {
115 when(connection.sendCommand(Commands.getSysinfo()))
116 .thenReturn(ModelTestUtil.readJson("rangeextender_get_sysinfo_response"));
117 handler.initialize();
118 assertHandleCommandRefreshType(-70);
121 private void assertHandleCommandRefreshType(int expectedRssi) {
122 handler.initialize();
123 ChannelUID channelUID = ChannelUIDConstants.CHANNEL_UID_RSSI;
124 handler.handleCommand(channelUID, RefreshType.REFRESH);
125 ArgumentCaptor<State> stateCaptor = ArgumentCaptor.forClass(State.class);
126 verify(callback).stateUpdated(eq(channelUID), stateCaptor.capture());
127 assertEquals(new QuantityType<>(expectedRssi + " dBm"), stateCaptor.getValue(),
128 "State of RSSI channel should be set");
132 public void testHandleCommandOther() throws InterruptedException {
133 handler.initialize();
134 ChannelUID channelUID = ChannelUIDConstants.CHANNEL_UID_SWITCH;
135 Mockito.doReturn(OnOffType.ON).when(smartHomeDevice).updateChannel(eq(channelUID), any());
136 handler.handleCommand(channelUID, RefreshType.REFRESH);
137 ArgumentCaptor<State> stateCaptor = ArgumentCaptor.forClass(State.class);
138 verify(callback).stateUpdated(eq(channelUID), stateCaptor.capture());
139 assertSame(OnOffType.ON, stateCaptor.getValue(), "State of channel switch should be set");
143 public void testRefreshChannels() {
144 handler.initialize();
145 handler.refreshChannels();