]> git.basschouten.com Git - openhab-addons.git/blob
85f7ea3a4315cca826c5f2c569bafa78632be647
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.boschshc.internal.console;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.hamcrest.Matchers.allOf;
18 import static org.hamcrest.Matchers.containsString;
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.*;
21
22 import java.io.IOException;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.nio.file.Paths;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.concurrent.ExecutionException;
31 import java.util.concurrent.TimeoutException;
32 import java.util.stream.Collectors;
33
34 import org.eclipse.jdt.annotation.NonNullByDefault;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.extension.ExtendWith;
38 import org.mockito.Mock;
39 import org.mockito.junit.jupiter.MockitoExtension;
40 import org.openhab.binding.boschshc.internal.devices.bridge.BridgeHandler;
41 import org.openhab.binding.boschshc.internal.devices.bridge.dto.Device;
42 import org.openhab.binding.boschshc.internal.devices.bridge.dto.PublicInformation;
43 import org.openhab.binding.boschshc.internal.devices.bridge.dto.SoftwareUpdateState;
44 import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
45 import org.openhab.core.io.console.Console;
46 import org.openhab.core.thing.Bridge;
47 import org.openhab.core.thing.Thing;
48 import org.openhab.core.thing.ThingRegistry;
49
50 /**
51  * Unit tests for Console command to list Bosch SHC devices and openhab support.
52  *
53  * @author Gerd Zanker - Initial contribution
54  */
55 @ExtendWith(MockitoExtension.class)
56 @NonNullByDefault
57 class BoschShcCommandExtensionTest {
58
59     private @NonNullByDefault({}) BoschShcCommandExtension fixture;
60
61     private @Mock @NonNullByDefault({}) ThingRegistry thingRegistry;
62
63     @BeforeEach
64     void setUp() {
65         fixture = new BoschShcCommandExtension(thingRegistry);
66     }
67
68     @Test
69     void execute() {
70         // only sanity checks, content is tested with the functions called by execute
71         Console consoleMock = mock(Console.class);
72         when(thingRegistry.getAll()).thenReturn(Collections.emptyList());
73
74         fixture.execute(new String[] {}, consoleMock);
75         verify(consoleMock, times(5)).printUsage(any());
76         fixture.execute(new String[] { "" }, consoleMock);
77         verify(consoleMock, times(10)).printUsage(any());
78
79         fixture.execute(new String[] { BoschShcCommandExtension.SHOW_BINDINGINFO }, consoleMock);
80         verify(consoleMock, atLeastOnce()).print(any());
81         fixture.execute(new String[] { BoschShcCommandExtension.SHOW_DEVICES }, consoleMock);
82         verify(consoleMock, atLeastOnce()).print(any());
83         fixture.execute(new String[] { BoschShcCommandExtension.SHOW_SERVICES }, consoleMock);
84         verify(consoleMock, atLeastOnce()).print(any());
85
86         fixture.execute(new String[] { BoschShcCommandExtension.GET_BRIDGEINFO }, consoleMock);
87         verify(consoleMock, atLeastOnce()).print(any());
88         fixture.execute(new String[] { BoschShcCommandExtension.GET_DEVICES }, consoleMock);
89         verify(consoleMock, atLeastOnce()).print(any());
90     }
91
92     @Test
93     void getCompleter() {
94         assertThat(fixture.getCompleter(), is(fixture));
95     }
96
97     @Test
98     void getUsages() {
99         List<String> strings = fixture.getUsages();
100         assertThat(strings.size(), is(5));
101         assertThat(strings.get(0), is("boschshc showBindingInfo - list detailed information about this binding"));
102         assertThat(strings.get(1), is("boschshc showDevices - list all devices supported by this binding"));
103     }
104
105     @Test
106     void complete() {
107         ArrayList<String> candidates = new ArrayList<>();
108         assertThat(fixture.complete(new String[] { "" }, 1, 0, candidates), is(false));
109         assertThat(fixture.complete(new String[] { "" }, 0, 0, candidates), is(true));
110         // for empty arguments, the completer suggest all usage commands
111         assertThat(candidates.size(), is(fixture.getUsages().size()));
112     }
113
114     @Test
115     void printBridgeInfo() throws BoschSHCException, ExecutionException, InterruptedException, TimeoutException {
116         // no bridge
117         when(thingRegistry.getAll()).thenReturn(Collections.emptyList());
118         assertThat(fixture.buildBridgeInfo(), is(""));
119
120         // one bridge
121         PublicInformation publicInformation = new PublicInformation();
122         publicInformation.shcGeneration = "Gen-T";
123         publicInformation.shcIpAddress = "1.2.3.4";
124         publicInformation.softwareUpdateState = new SoftwareUpdateState();
125         Bridge mockBridge = mock(Bridge.class);
126         when(mockBridge.getLabel()).thenReturn("TestLabel");
127         BridgeHandler mockBridgeHandler = mock(BridgeHandler.class);
128         when(mockBridgeHandler.getThing()).thenReturn(mockBridge);
129         when(mockBridgeHandler.getPublicInformation()).thenReturn(publicInformation);
130         Thing mockBridgeThing = mock(Thing.class);
131         when(mockBridgeThing.getHandler()).thenReturn(mockBridgeHandler);
132         when(thingRegistry.getAll()).thenReturn(Collections.singletonList(mockBridgeThing));
133         assertThat(fixture.buildBridgeInfo(),
134                 allOf(containsString("Bridge: TestLabel"), containsString("access possible: false"),
135                         containsString("SHC Generation: Gen-T"), containsString("IP Address: 1.2.3.4")));
136
137         // two bridges
138         PublicInformation publicInformation2 = new PublicInformation();
139         publicInformation2.shcGeneration = "Gen-U";
140         publicInformation2.shcIpAddress = "11.22.33.44";
141         publicInformation2.softwareUpdateState = new SoftwareUpdateState();
142         Bridge mockBridge2 = mock(Bridge.class);
143         when(mockBridge2.getLabel()).thenReturn("Bridge  2");
144         BridgeHandler mockBridgeHandler2 = mock(BridgeHandler.class);
145         when(mockBridgeHandler2.getThing()).thenReturn(mockBridge2);
146         when(mockBridgeHandler2.getPublicInformation()).thenReturn(publicInformation2);
147         Thing mockBridgeThing2 = mock(Thing.class);
148         when(mockBridgeThing2.getHandler()).thenReturn(mockBridgeHandler2);
149         when(thingRegistry.getAll()).thenReturn(Arrays.asList(mockBridgeThing, mockBridgeThing2));
150         assertThat(fixture.buildBridgeInfo(),
151                 allOf(containsString("Bridge: TestLabel"), containsString("access possible: false"),
152                         containsString("SHC Generation: Gen-T"), containsString("IP Address: 1.2.3.4"),
153                         containsString("Bridge: Bridge  2"), containsString("access possible: false"),
154                         containsString("SHC Generation: Gen-U"), containsString("IP Address: 11.22.33.44")));
155     }
156
157     @Test
158     void printDeviceInfo() throws InterruptedException {
159         // no bridge
160         when(thingRegistry.getAll()).thenReturn(Collections.emptyList());
161         assertThat(fixture.buildDeviceInfo(), is(""));
162
163         // One bridge, No device
164         BridgeHandler mockBridgeHandler = mock(BridgeHandler.class);
165         Thing mockBridgeThing = mock(Thing.class);
166         when(mockBridgeThing.getLabel()).thenReturn("TestLabel");
167         when(mockBridgeThing.getHandler()).thenReturn(mockBridgeHandler);
168         when(thingRegistry.getAll()).thenReturn(Collections.singletonList(mockBridgeThing));
169         assertThat(fixture.buildDeviceInfo(), allOf(containsString("thing: TestLabel"), containsString("devices (0)")));
170
171         // One bridge, One UNsupported device
172         Device mockShcDevice = mock(Device.class);
173         mockShcDevice.deviceModel = "";
174         mockShcDevice.deviceServiceIds = Collections.emptyList();
175         when(mockBridgeHandler.getDevices()).thenReturn(List.of(mockShcDevice));
176         assertThat(fixture.buildDeviceInfo(), allOf(containsString("thing: TestLabel"), containsString("devices (1)"),
177                 containsString("!UNSUPPORTED!")));
178
179         // One bridge, One supported device
180         mockShcDevice.deviceModel = "TWINGUARD";
181         mockShcDevice.deviceServiceIds = Collections.emptyList();
182         when(mockBridgeHandler.getDevices()).thenReturn(List.of(mockShcDevice));
183         assertThat(fixture.buildDeviceInfo(), allOf(containsString("thing: TestLabel"), containsString("devices (1)"),
184                 containsString("TWINGUARD -> twinguard")));
185
186         // One bridge, One supported device with services
187         mockShcDevice.deviceModel = "TWINGUARD";
188         mockShcDevice.deviceServiceIds = List.of("unknownService", "batterylevel");
189         when(mockBridgeHandler.getDevices()).thenReturn(List.of(mockShcDevice));
190         assertThat(fixture.buildDeviceInfo(), allOf(containsString("thing: TestLabel"), containsString("devices (1)"),
191                 containsString("TWINGUARD -> twinguard"), containsString("service: unknownService -> !UNSUPPORTED!"),
192                 containsString("batterylevel -> batterylevel")));
193     }
194
195     @Test
196     void printBindingInfo() {
197         assertThat(fixture.buildBindingInfo(), containsString("Bosch SHC Binding"));
198     }
199
200     @Test
201     void printSupportedDevices() {
202         assertThat(fixture.buildSupportedDeviceStatus(),
203                 allOf(containsString("Supported Devices"), containsString("BBL = boschshc:shutter-control")));
204     }
205
206     @Test
207     void printSupportedServices() {
208         assertThat(fixture.buildSupportedServiceStatus(),
209                 allOf(containsString("Supported Services"), containsString("airqualitylevel")));
210     }
211
212     /**
213      * The list of services returned by getAllBoschShcServices() shall match
214      * the implemented services in org.openhab.bindings.boschshc.internal.services.
215      * Because reflection doesn't return all services classes during runtime
216      * this test supports consistency between the lists of services and the implemented services.
217      */
218     @Test
219     void getAllBoschShcServices() throws IOException {
220         List<String> services = Files
221                 .walk(Paths.get("src/main/java/org/openhab/binding/boschshc/internal/services").toAbsolutePath(), 1)
222                 .filter(Files::isDirectory).map(Path::getFileName).map(Path::toString)
223                 // exclude folders which no service implementation
224                 .filter(name -> !name.equals("dto")).filter(name -> !name.equals("services")).sorted()
225                 .collect(Collectors.toList());
226         assertThat(services, is(fixture.getAllBoschShcServices()));
227     }
228 }