]> git.basschouten.com Git - openhab-addons.git/blob
92ce5dd4a1310f1a4764e2ade67195cba4a51c2d
[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.discovery;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.CoreMatchers.nullValue;
17 import static org.hamcrest.MatcherAssert.assertThat;
18 import static org.junit.jupiter.api.Assertions.assertNull;
19 import static org.junit.jupiter.api.Assertions.assertTrue;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.never;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26
27 import java.util.ArrayList;
28 import java.util.UUID;
29
30 import org.eclipse.jdt.annotation.NonNullByDefault;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.api.Test;
33 import org.junit.jupiter.api.extension.ExtendWith;
34 import org.mockito.ArgumentCaptor;
35 import org.mockito.Captor;
36 import org.mockito.Mock;
37 import org.mockito.junit.jupiter.MockitoExtension;
38 import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
39 import org.openhab.binding.boschshc.internal.devices.bridge.BridgeHandler;
40 import org.openhab.binding.boschshc.internal.devices.bridge.dto.Device;
41 import org.openhab.binding.boschshc.internal.devices.bridge.dto.Room;
42 import org.openhab.binding.boschshc.internal.devices.bridge.dto.UserDefinedState;
43 import org.openhab.core.config.discovery.DiscoveryListener;
44 import org.openhab.core.config.discovery.DiscoveryResult;
45 import org.openhab.core.config.discovery.DiscoveryService;
46 import org.openhab.core.thing.Bridge;
47 import org.openhab.core.thing.ThingUID;
48
49 /**
50  * Unit tests for {@link ThingDiscoveryService}.
51  *
52  * @author Gerd Zanker - Initial contribution
53  */
54 @ExtendWith(MockitoExtension.class)
55 @NonNullByDefault
56 class ThingDiscoveryServiceTest {
57
58     private @NonNullByDefault({}) ThingDiscoveryService fixture;
59
60     private @Mock @NonNullByDefault({}) BridgeHandler bridgeHandler;
61     private @Mock @NonNullByDefault({}) DiscoveryListener discoveryListener;
62     private @Captor @NonNullByDefault({}) ArgumentCaptor<DiscoveryService> discoveryServiceCaptor;
63     private @Captor @NonNullByDefault({}) ArgumentCaptor<DiscoveryResult> discoveryResultCaptor;
64
65     @BeforeEach
66     void beforeEach() {
67         fixture = new ThingDiscoveryService();
68         fixture.addDiscoveryListener(discoveryListener);
69         fixture.setThingHandler(bridgeHandler);
70     }
71
72     private void mockBridgeCalls() {
73         // Set the Mock Bridge as the ThingHandler
74         ThingUID bridgeUID = new ThingUID(BoschSHCBindingConstants.THING_TYPE_SHC, "testSHC");
75         Bridge mockBridge = mock(Bridge.class);
76         when(mockBridge.getUID()).thenReturn(bridgeUID);
77         when(bridgeHandler.getThing()).thenReturn(mockBridge);
78     }
79
80     @Test
81     void testStartScan() throws InterruptedException {
82         mockBridgeCalls();
83
84         fixture.activate();
85         fixture.startScan();
86
87         verify(bridgeHandler).getRooms();
88         verify(bridgeHandler).getDevices();
89
90         fixture.stopScan();
91         fixture.deactivate();
92     }
93
94     @Test
95     void testStartScanWithoutBridgeHandler() {
96         mockBridgeCalls();
97
98         // No fixture.setThingHandler(bridgeHandler);
99         fixture.activate();
100         fixture.startScan();
101
102         // bridgeHandler not called, just no exception expected
103         fixture.stopScan();
104         fixture.deactivate();
105     }
106
107     @Test
108     void testSetGetThingHandler() {
109         fixture.setThingHandler(bridgeHandler);
110         assertThat(fixture.getThingHandler(), is(bridgeHandler));
111     }
112
113     @Test
114     void testAddDevices() {
115         mockBridgeCalls();
116
117         ArrayList<Device> devices = new ArrayList<>();
118         ArrayList<Room> emptyRooms = new ArrayList<>();
119
120         Device device1 = new Device();
121         device1.deviceModel = "TWINGUARD";
122         device1.id = "testDevice:ID";
123         device1.name = "Test Name";
124         devices.add(device1);
125         Device device2 = new Device();
126         device2.deviceModel = "TWINGUARD";
127         device2.id = "testDevice:2";
128         device2.name = "Second device";
129         devices.add(device2);
130
131         verify(discoveryListener, never()).thingDiscovered(any(), any());
132
133         fixture.addDevices(devices, emptyRooms);
134
135         // two calls for the two devices expected
136         verify(discoveryListener, times(2)).thingDiscovered(any(), any());
137     }
138
139     @Test
140     void testAddDevicesWithNoDevices() {
141         ArrayList<Device> emptyDevices = new ArrayList<>();
142         ArrayList<Room> emptyRooms = new ArrayList<>();
143
144         verify(discoveryListener, never()).thingDiscovered(any(), any());
145
146         fixture.addDevices(emptyDevices, emptyRooms);
147
148         // nothing shall be discovered, but also no exception shall be thrown
149         verify(discoveryListener, never()).thingDiscovered(any(), any());
150     }
151
152     @Test
153     void testAddDevice() {
154         mockBridgeCalls();
155
156         Device device = new Device();
157         device.deviceModel = "TWINGUARD";
158         device.id = "testDevice:ID";
159         device.name = "Test Name";
160         fixture.addDevice(device, "TestRoom");
161
162         verify(discoveryListener).thingDiscovered(discoveryServiceCaptor.capture(), discoveryResultCaptor.capture());
163
164         assertThat(discoveryServiceCaptor.getValue().getClass(), is(ThingDiscoveryService.class));
165         DiscoveryResult result = discoveryResultCaptor.getValue();
166         assertThat(result.getBindingId(), is(BoschSHCBindingConstants.BINDING_ID));
167         assertThat(result.getThingTypeUID(), is(BoschSHCBindingConstants.THING_TYPE_TWINGUARD));
168         assertThat(result.getThingUID().getId(), is("testDevice_ID"));
169         assertThat(result.getBridgeUID().getId(), is("testSHC"));
170         assertThat(result.getLabel(), is("Test Name"));
171         assertThat(String.valueOf(result.getProperties().get("Location")), is("TestRoom"));
172     }
173
174     @Test
175     void testAddDeviceWithNiceNameAndAppendedRoomName() {
176         assertDeviceNiceName("-RoomClimateControl-", "TestRoom", "Room Climate Control TestRoom");
177     }
178
179     @Test
180     void testAddDeviceWithNiceNameWithEmtpyRoomName() {
181         assertDeviceNiceName("-RoomClimateControl-", "", "Room Climate Control");
182     }
183
184     @Test
185     void testAddDeviceWithNiceNameWithoutAppendingRoomName() {
186         assertDeviceNiceName("-SmokeDetectionSystem-", "TestRoom", "Smoke Detection System");
187     }
188
189     @Test
190     void testAddDeviceWithNiceNameWithoutUsualName() {
191         assertDeviceNiceName("My other device", "TestRoom", "My other device");
192     }
193
194     private void assertDeviceNiceName(String deviceName, String roomName, String expectedNiceName) {
195         mockBridgeCalls();
196
197         Device device = new Device();
198         device.deviceModel = "TWINGUARD";
199         device.id = "testDevice:ID";
200         device.name = deviceName;
201         fixture.addDevice(device, roomName);
202         verify(discoveryListener).thingDiscovered(discoveryServiceCaptor.capture(), discoveryResultCaptor.capture());
203         assertThat(discoveryServiceCaptor.getValue().getClass(), is(ThingDiscoveryService.class));
204         DiscoveryResult result = discoveryResultCaptor.getValue();
205         assertThat(result.getLabel(), is(expectedNiceName));
206     }
207
208     @Test
209     void testGetRoomForDevice() {
210         Device device = new Device();
211
212         ArrayList<Room> rooms = new ArrayList<>();
213         Room room1 = new Room();
214         room1.id = "r1";
215         room1.name = "Room1";
216         rooms.add(room1);
217         Room room2 = new Room();
218         room2.id = "r2";
219         room2.name = "Room 2";
220         rooms.add(room2);
221
222         device.roomId = "r1";
223         assertThat(fixture.getRoomNameForDevice(device, rooms), is("Room1"));
224
225         device.roomId = "r2";
226         assertThat(fixture.getRoomNameForDevice(device, rooms), is("Room 2"));
227
228         device.roomId = "unknown";
229         assertTrue(fixture.getRoomNameForDevice(device, rooms).isEmpty());
230     }
231
232     @Test
233     void testGetThingTypeUID() {
234         Device device = new Device();
235
236         device.deviceModel = "invalid";
237         assertNull(fixture.getThingTypeUID(device));
238
239         // just two spot checks
240         device.deviceModel = "BBL";
241         assertThat(fixture.getThingTypeUID(device), is(BoschSHCBindingConstants.THING_TYPE_SHUTTER_CONTROL));
242         device.deviceModel = "TWINGUARD";
243         assertThat(fixture.getThingTypeUID(device), is(BoschSHCBindingConstants.THING_TYPE_TWINGUARD));
244     }
245
246     @Test
247     void testAddUserDefinedStates() {
248         mockBridgeCalls();
249
250         ArrayList<UserDefinedState> userStates = new ArrayList<>();
251
252         UserDefinedState userState1 = new UserDefinedState();
253         userState1.setId(UUID.randomUUID().toString());
254         userState1.setName("first defined state");
255         userState1.setState(true);
256         UserDefinedState userState2 = new UserDefinedState();
257         userState2.setId(UUID.randomUUID().toString());
258         userState2.setName("another defined state");
259         userState2.setState(false);
260         userStates.add(userState1);
261         userStates.add(userState2);
262
263         verify(discoveryListener, never()).thingDiscovered(any(), any());
264
265         fixture.addUserStates(userStates);
266
267         // two calls for the two devices expected
268         verify(discoveryListener, times(2)).thingDiscovered(any(), any());
269     }
270
271     @Test
272     void getThingTypeUIDLightControl2ChildDevice() {
273         Device device = new Device();
274         device.deviceModel = ThingDiscoveryService.DEVICE_MODEL_LIGHT_CONTROL_CHILD_DEVICE;
275
276         assertThat(fixture.getThingTypeUID(device), is(nullValue()));
277     }
278 }