]> git.basschouten.com Git - openhab-addons.git/blob
cbdd634970111766f09b6383c85a7f0a00e40d93
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.webthing.internal.link;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.Mockito.*;
17
18 import java.net.URI;
19 import java.nio.file.Files;
20 import java.nio.file.Paths;
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.junit.jupiter.api.Test;
27 import org.openhab.binding.webthing.internal.ChannelHandler;
28 import org.openhab.binding.webthing.internal.channel.Channels;
29 import org.openhab.binding.webthing.internal.client.Mocks;
30 import org.openhab.binding.webthing.internal.client.WebthingTest;
31 import org.openhab.binding.webthing.internal.client.dto.PropertyStatusMessage;
32 import org.openhab.core.library.types.*;
33 import org.openhab.core.thing.*;
34 import org.openhab.core.types.Command;
35 import org.openhab.core.types.State;
36
37 import com.google.gson.Gson;
38
39 /**
40  * Mapping test.
41  *
42  * Please consider that changes of 'ItemType<->PropertyType mapping' validated by this test
43  * will break the compatibility to former releases.
44  *
45  * @author Gregor Roth - Initial contribution
46  */
47 @NonNullByDefault
48 public class WebthingChannelLinkTest {
49     private final Gson gson = new Gson();
50
51     @Test
52     public void testChannelToProperty() throws Exception {
53         var httpClient = mock(org.eclipse.jetty.client.HttpClient.class);
54         var request = Mocks.mockRequest(null, load("/awning_response.json"));
55         when(httpClient.newRequest(URI.create("http://example.org:8090/0"))).thenReturn(request);
56
57         var request2 = Mocks.mockRequest("{\"target_position\":10}", load("/awning_property.json"));
58         when(httpClient.newRequest(URI.create("http://example.org:8090/0/properties/target_position")))
59                 .thenReturn(request2);
60
61         var thingUID = new ThingUID("webthing", "anwing");
62         var channelUID = Channels.createChannelUID(thingUID, "target_position");
63
64         var webthing = WebthingTest.createTestWebthing("http://example.org:8090/0", httpClient);
65         var channel = Channels.createChannel(thingUID, "target_position",
66                 Objects.requireNonNull(webthing.getPropertyDescription("target_position")));
67
68         var testWebthingThingHandler = new TestWebthingThingHandler();
69         ChannelToPropertyLink.establish(testWebthingThingHandler, channel, webthing, "target_position");
70
71         testWebthingThingHandler.listeners.get(channelUID).onItemStateChanged(channelUID, new DecimalType(10));
72     }
73
74     @Test
75     public void testChannelToPropertyServerError() throws Exception {
76         var httpClient = mock(org.eclipse.jetty.client.HttpClient.class);
77         var request = Mocks.mockRequest(null, load("/awning_response.json"));
78         when(httpClient.newRequest(URI.create("http://example.org:8090/0"))).thenReturn(request);
79
80         var request2 = Mocks.mockRequest("{\"target_position\":130}", load("/awning_property.json"), 200, 500);
81         when(httpClient.newRequest(URI.create("http://example.org:8090/0/properties/target_position")))
82                 .thenReturn(request2);
83
84         var thingUID = new ThingUID("webthing", "anwing");
85         var channelUID = Channels.createChannelUID(thingUID, "target_position");
86
87         var webthing = WebthingTest.createTestWebthing("http://example.org:8090/0", httpClient);
88         var channel = Channels.createChannel(thingUID, "target_position",
89                 Objects.requireNonNull(webthing.getPropertyDescription("target_position")));
90
91         var testWebthingThingHandler = new TestWebthingThingHandler();
92         ChannelToPropertyLink.establish(testWebthingThingHandler, channel, webthing, "target_position");
93
94         testWebthingThingHandler.listeners.get(channelUID).onItemStateChanged(channelUID, new DecimalType(130));
95     }
96
97     @Test
98     public void testPropertyToChannel() throws Exception {
99         var httpClient = mock(org.eclipse.jetty.client.HttpClient.class);
100         var request = Mocks.mockRequest(null, load("/awning_response.json"));
101         when(httpClient.newRequest(URI.create("http://example.org:8090/0"))).thenReturn(request);
102
103         var request2 = Mocks.mockRequest("{\"target_position\":10}", load("/awning_property.json"));
104         when(httpClient.newRequest(URI.create("http://example.org:8090/0/properties/target_position")))
105                 .thenReturn(request2);
106
107         var thingUID = new ThingUID("webthing", "anwing");
108         var channelUID = Channels.createChannelUID(thingUID, "target_position");
109
110         var errorHandler = new WebthingTest.ErrorHandler();
111         var websocketConnectionFactory = new WebthingTest.TestWebsocketConnectionFactory();
112         var webthing = WebthingTest.createTestWebthing("http://example.org:8090/0", httpClient, errorHandler,
113                 websocketConnectionFactory);
114         var channel = Channels.createChannel(thingUID, "target_position",
115                 Objects.requireNonNull(webthing.getPropertyDescription("target_position")));
116
117         var testWebthingThingHandler = new TestWebthingThingHandler();
118         PropertyToChannelLink.establish(webthing, "target_position", testWebthingThingHandler, channel);
119
120         var message = new PropertyStatusMessage();
121         message.messageType = "propertyStatus";
122         message.data = Map.of("target_position", 77);
123         websocketConnectionFactory.webSocketRef.get().sendToClient(message);
124
125         assertEquals(new DecimalType(77), testWebthingThingHandler.itemState.get(channelUID));
126     }
127
128     @Test
129     public void testDataTypeMapping() throws Exception {
130         performDataTypeMappingTest("level_prop", 56.5, new DecimalType(56.5), 3.5, new DecimalType(3.5));
131         performDataTypeMappingTest("level_unit_prop", 10, new PercentType(10), 90, new PercentType(90));
132         performDataTypeMappingTest("thermo_prop", "off", new StringType("off"), "auto", new StringType("auto"));
133         performDataTypeMappingTest("temp_prop", 18.6, new DecimalType(18.6), 23.2, new DecimalType(23.2));
134         performDataTypeMappingTest("targettemp_prop", 18.6, new DecimalType(18.6), 23.2, new DecimalType(23.2));
135         performDataTypeMappingTest("open_prop", true, OpenClosedType.OPEN, false, OpenClosedType.CLOSED);
136         performDataTypeMappingTest("colortemp_prop", 10, new PercentType(10), 60, new PercentType(60));
137         performDataTypeMappingTest("color_prop", "#f2fe00", new HSBType("62,100,99"), "#ff0000",
138                 new HSBType("0.0,100.0,100.0"));
139         performDataTypeMappingTest("colormode_prop", "color", new StringType("color"), "temperature",
140                 new StringType("temperature"));
141         performDataTypeMappingTest("brightness_prop", 33, new PercentType(33), 65, new PercentType(65));
142         performDataTypeMappingTest("voltage_prop", 4.5, new DecimalType(4.5), 30.2, new DecimalType(30.2));
143         performDataTypeMappingTest("heating_prop", "off", new StringType("off"), "cooling", new StringType("cooling"));
144         performDataTypeMappingTest("onoff_prop", true, OnOffType.ON, false, OnOffType.OFF);
145         performDataTypeMappingTest("string_prop", "initial", new StringType("initial"), "updated",
146                 new StringType("updated"));
147         performDataTypeMappingTest("number_prop", 80.5, new DecimalType(80.5), 60.9, new DecimalType(60.9));
148         performDataTypeMappingTest("integer_prop", 11, new DecimalType(11), 77, new DecimalType(77));
149         performDataTypeMappingTest("boolean_prop", true, OnOffType.ON, false, OnOffType.OFF);
150     }
151
152     private void performDataTypeMappingTest(String propertyName, Object initialValue, State initialState,
153             Object updatedValue, State updatedState) throws Exception {
154         var httpClient = mock(org.eclipse.jetty.client.HttpClient.class);
155         var request = Mocks.mockRequest(null, load("/datatypes_test_response.json"));
156         when(httpClient.newRequest(URI.create("http://example.org:8090/"))).thenReturn(request);
157
158         var request2 = Mocks.mockRequest(gson.toJson(Map.of(propertyName, updatedValue)),
159                 gson.toJson(Map.of(propertyName, initialValue)));
160         when(httpClient.newRequest(URI.create("http://example.org:8090/properties/" + propertyName)))
161                 .thenReturn(request2);
162
163         var thingUID = new ThingUID("webthing", "test");
164         var channelUID = Channels.createChannelUID(thingUID, propertyName);
165
166         var errorHandler = new WebthingTest.ErrorHandler();
167         var websocketConnectionFactory = new WebthingTest.TestWebsocketConnectionFactory();
168         var webthing = WebthingTest.createTestWebthing("http://example.org:8090/", httpClient, errorHandler,
169                 websocketConnectionFactory);
170         var channel = Channels.createChannel(thingUID, propertyName,
171                 Objects.requireNonNull(webthing.getPropertyDescription(propertyName)));
172
173         var testWebthingThingHandler = new TestWebthingThingHandler();
174
175         PropertyToChannelLink.establish(webthing, propertyName, testWebthingThingHandler, channel);
176
177         var message = new PropertyStatusMessage();
178         message.messageType = "propertyStatus";
179         message.data = Map.of(propertyName, initialValue);
180         websocketConnectionFactory.webSocketRef.get().sendToClient(message);
181
182         assertEquals(initialState, testWebthingThingHandler.itemState.get(channelUID));
183
184         ChannelToPropertyLink.establish(testWebthingThingHandler, channel, webthing, propertyName);
185         testWebthingThingHandler.listeners.get(channelUID).onItemStateChanged(channelUID, updatedState);
186     }
187
188     public static String load(String name) throws Exception {
189         return new String(Files.readAllBytes(Paths.get(WebthingTest.class.getResource(name).toURI())));
190     }
191
192     private static class TestWebthingThingHandler implements ChannelHandler {
193         public final Map<ChannelUID, ItemChangedListener> listeners = new ConcurrentHashMap<>();
194         public final Map<ChannelUID, Command> itemState = new ConcurrentHashMap<>();
195
196         @Override
197         public void observeChannel(ChannelUID channelUID, ItemChangedListener listener) {
198             listeners.put(channelUID, listener);
199         }
200
201         @Override
202         public void updateItemState(ChannelUID channelUID, Command command) {
203             itemState.put(channelUID, command);
204         }
205     }
206 }