]> git.basschouten.com Git - openhab-addons.git/blob
e02d428307b09271810a6f2fb4a3f282ea70d53f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.innogysmarthome.internal;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.ArgumentMatchers.any;
17 import static org.mockito.Mockito.*;
18
19 import java.net.URI;
20 import java.util.concurrent.Future;
21
22 import org.eclipse.jetty.websocket.api.Session;
23 import org.eclipse.jetty.websocket.api.StatusCode;
24 import org.eclipse.jetty.websocket.client.WebSocketClient;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.openhab.binding.innogysmarthome.internal.listener.EventListener;
28
29 /**
30  * @author Sven Strohschein - Initial contribution
31  */
32 public class InnogyWebSocketTest {
33
34     private InnogyWebSocketAccessible webSocket;
35     private EventListenerDummy eventListener;
36     private WebSocketClient webSocketClientMock;
37     private Session sessionMock;
38
39     @BeforeEach
40     public void before() throws Exception {
41         sessionMock = mock(Session.class);
42
43         Future<Session> futureMock = mock(Future.class);
44         when(futureMock.get()).thenReturn(sessionMock);
45
46         webSocketClientMock = mock(WebSocketClient.class);
47         when(webSocketClientMock.connect(any(), any())).thenReturn(futureMock);
48
49         eventListener = new EventListenerDummy();
50         webSocket = new InnogyWebSocketAccessible(eventListener, new URI(""), 1000);
51     }
52
53     @Test
54     public void testStart() throws Exception {
55         startWebSocket();
56
57         assertTrue(webSocket.isRunning());
58     }
59
60     @Test
61     public void testStop() throws Exception {
62         startWebSocket();
63
64         webSocket.stop();
65
66         assertFalse(webSocket.isRunning());
67     }
68
69     @Test
70     public void testOnCloseAfterStop() throws Exception {
71         startWebSocket();
72
73         assertFalse(eventListener.isOnEventCalled());
74         assertFalse(eventListener.isOnErrorCalled());
75         assertFalse(eventListener.isConnectionClosedCalled());
76
77         webSocket.stop();
78         webSocket.onClose(StatusCode.ABNORMAL, "Test");
79
80         assertFalse(eventListener.isOnEventCalled());
81         assertFalse(eventListener.isOnErrorCalled());
82         // stop() itself causes a (abnormal) close event, that shouldn't get noticed
83         // (otherwise it would cause a reconnect event which would lead to an infinite loop ...)
84         assertFalse(eventListener.isConnectionClosedCalled());
85     }
86
87     @Test
88     public void testOnCloseAfterRestart() throws Exception {
89         startWebSocket();
90
91         assertFalse(eventListener.isOnEventCalled());
92         assertFalse(eventListener.isOnErrorCalled());
93         assertFalse(eventListener.isConnectionClosedCalled());
94
95         webSocket.stop();
96         webSocket.onClose(StatusCode.ABNORMAL, "Test");
97
98         assertFalse(eventListener.isOnEventCalled());
99         assertFalse(eventListener.isOnErrorCalled());
100         // stop() itself causes a (abnormal) close event, that shouldn't get noticed
101         // (otherwise it would cause a reconnect event which would lead to an infinite loop ...)
102         assertFalse(eventListener.isConnectionClosedCalled());
103
104         startWebSocket();
105
106         webSocket.onClose(StatusCode.ABNORMAL, "Test");
107
108         assertFalse(eventListener.isOnEventCalled());
109         assertFalse(eventListener.isOnErrorCalled());
110         // A close event after a restart of the web socket should get recognized again
111         assertTrue(eventListener.isConnectionClosedCalled());
112     }
113
114     @Test
115     public void testOnCloseAbnormal() throws Exception {
116         startWebSocket();
117
118         assertFalse(eventListener.isOnEventCalled());
119         assertFalse(eventListener.isOnErrorCalled());
120         assertFalse(eventListener.isConnectionClosedCalled());
121
122         webSocket.onClose(StatusCode.ABNORMAL, "Test");
123
124         assertFalse(eventListener.isOnEventCalled());
125         assertFalse(eventListener.isOnErrorCalled());
126         assertTrue(eventListener.isConnectionClosedCalled());
127     }
128
129     @Test
130     public void testOnCloseNormal() throws Exception {
131         startWebSocket();
132
133         assertFalse(eventListener.isOnEventCalled());
134         assertFalse(eventListener.isOnErrorCalled());
135         assertFalse(eventListener.isConnectionClosedCalled());
136
137         webSocket.onClose(StatusCode.NORMAL, "Test");
138
139         assertFalse(eventListener.isOnEventCalled());
140         assertFalse(eventListener.isOnErrorCalled());
141         // Nothing should get noticed when a normal close is executed (for example by stopping OpenHAB)
142         assertFalse(eventListener.isConnectionClosedCalled());
143     }
144
145     @Test
146     public void testOnMessage() throws Exception {
147         startWebSocket();
148
149         assertFalse(eventListener.isOnEventCalled());
150         assertFalse(eventListener.isOnErrorCalled());
151         assertFalse(eventListener.isConnectionClosedCalled());
152
153         webSocket.onMessage("Test-Message");
154
155         assertTrue(eventListener.isOnEventCalled());
156         assertFalse(eventListener.isOnErrorCalled());
157         assertFalse(eventListener.isConnectionClosedCalled());
158     }
159
160     @Test
161     public void testOnMessageAfterStop() throws Exception {
162         startWebSocket();
163
164         assertFalse(eventListener.isOnEventCalled());
165         assertFalse(eventListener.isOnErrorCalled());
166         assertFalse(eventListener.isConnectionClosedCalled());
167
168         webSocket.stop();
169         webSocket.onClose(StatusCode.ABNORMAL, "Test");
170         webSocket.onMessage("Test-Message");
171
172         assertFalse(eventListener.isOnEventCalled());
173         assertFalse(eventListener.isOnErrorCalled());
174         assertFalse(eventListener.isConnectionClosedCalled());
175     }
176
177     @Test
178     public void testOnError() throws Exception {
179         startWebSocket();
180
181         assertFalse(eventListener.isOnEventCalled());
182         assertFalse(eventListener.isOnErrorCalled());
183         assertFalse(eventListener.isConnectionClosedCalled());
184
185         webSocket.onError(new RuntimeException("Test-Exception"));
186
187         assertFalse(eventListener.isOnEventCalled());
188         assertTrue(eventListener.isOnErrorCalled());
189         assertFalse(eventListener.isConnectionClosedCalled());
190     }
191
192     private void startWebSocket() throws Exception {
193         webSocket.start();
194         when(sessionMock.isOpen()).thenReturn(true);
195
196         webSocket.onConnect(sessionMock);
197     }
198
199     private class InnogyWebSocketAccessible extends InnogyWebSocket {
200
201         private InnogyWebSocketAccessible(EventListener eventListener, URI webSocketURI, int maxIdleTimeout) {
202             super(eventListener, webSocketURI, maxIdleTimeout);
203         }
204
205         @Override
206         WebSocketClient startWebSocketClient() {
207             return webSocketClientMock;
208         }
209     }
210
211     private class EventListenerDummy implements EventListener {
212
213         private boolean isOnEventCalled;
214         private boolean isOnErrorCalled;
215         private boolean isConnectionClosedCalled;
216
217         @Override
218         public void onEvent(String msg) {
219             isOnEventCalled = true;
220         }
221
222         @Override
223         public void onError(Throwable cause) {
224             isOnErrorCalled = true;
225         }
226
227         @Override
228         public void connectionClosed() {
229             isConnectionClosedCalled = true;
230         }
231
232         public boolean isOnEventCalled() {
233             return isOnEventCalled;
234         }
235
236         public boolean isOnErrorCalled() {
237             return isOnErrorCalled;
238         }
239
240         public boolean isConnectionClosedCalled() {
241             return isConnectionClosedCalled;
242         }
243     }
244 }