]> git.basschouten.com Git - openhab-addons.git/blob
14a4717ff67b66ecd91dd8fd0304f533d50e58a0
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.robonect.internal;
14
15 import static org.junit.Assert.assertEquals;
16 import static org.mockito.Mockito.times;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.when;
19
20 import java.nio.charset.StandardCharsets;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24
25 import org.eclipse.jetty.client.HttpClient;
26 import org.eclipse.jetty.client.api.ContentResponse;
27 import org.eclipse.jetty.client.api.Request;
28 import org.eclipse.jetty.http.HttpMethod;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.mockito.Mock;
32 import org.mockito.MockitoAnnotations;
33 import org.openhab.binding.robonect.internal.model.ErrorList;
34 import org.openhab.binding.robonect.internal.model.MowerInfo;
35 import org.openhab.binding.robonect.internal.model.Name;
36 import org.openhab.binding.robonect.internal.model.VersionInfo;
37
38 /**
39  * The goal of this class is to test the functionality of the RobonectClient,
40  * by mocking the module responses.
41  * 
42  * @author Marco Meyer - Initial contribution
43  */
44 public class RobonectClientTest {
45
46     private RobonectClient subject;
47
48     @Mock
49     private HttpClient httpClientMock;
50
51     @Mock
52     private ContentResponse responseMock;
53
54     @Mock
55     private Request requestMock;
56
57     @Before
58     public void init() {
59         MockitoAnnotations.initMocks(this);
60         RobonectEndpoint dummyEndPoint = new RobonectEndpoint("123.456.789.123", null, null);
61         subject = new RobonectClient(httpClientMock, dummyEndPoint);
62     }
63
64     @Test
65     public void shouldCallStatusCommand() throws InterruptedException, ExecutionException, TimeoutException {
66         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=status")).thenReturn(requestMock);
67         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
68         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
69         when(requestMock.send()).thenReturn(responseMock);
70         when(responseMock.getEncoding()).thenReturn("utf8");
71         when(responseMock.getContentAsString()).thenReturn(
72                 "{\"successful\": true, \"name\": \"Mein Automower\", \"status\": {\"status\": 17, \"stopped\": false, \"duration\": 4359, \"mode\": 0, \"battery\": 100, \"hours\": 29}, \"timer\": {\"status\": 2, \"next\": {\"date\": \"01.05.2017\", \"time\": \"19:00:00\", \"unix\": 1493665200}}, \"wlan\": {\"signal\": -76}}");
73         subject.getMowerInfo();
74         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=status");
75     }
76
77     @Test
78     public void shouldCallStartCommand() throws InterruptedException, ExecutionException, TimeoutException {
79         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=start")).thenReturn(requestMock);
80         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
81         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
82         when(requestMock.send()).thenReturn(responseMock);
83         when(responseMock.getEncoding()).thenReturn("utf8");
84         when(responseMock.getContentAsString()).thenReturn("{\"successful\": true}");
85         subject.start();
86         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=start");
87     }
88
89     @Test
90     public void shouldCallStopCommand() throws InterruptedException, ExecutionException, TimeoutException {
91         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=stop")).thenReturn(requestMock);
92         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
93         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
94         when(requestMock.send()).thenReturn(responseMock);
95         when(responseMock.getEncoding()).thenReturn("utf8");
96         when(responseMock.getContentAsString()).thenReturn("{\"successful\": true}");
97         subject.stop();
98         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=stop");
99     }
100
101     @Test
102     public void shouldResetErrors() throws InterruptedException, ExecutionException, TimeoutException {
103         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=error&reset")).thenReturn(requestMock);
104         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
105         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
106         when(requestMock.send()).thenReturn(responseMock);
107         when(responseMock.getEncoding()).thenReturn("utf8");
108         when(responseMock.getContentAsString()).thenReturn("{\"successful\": true}");
109         subject.resetErrors();
110         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=error&reset");
111     }
112
113     @Test
114     public void shouldRetrieveName() throws InterruptedException, ExecutionException, TimeoutException {
115         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=name")).thenReturn(requestMock);
116         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
117         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
118         when(requestMock.send()).thenReturn(responseMock);
119         when(responseMock.getEncoding()).thenReturn("utf8");
120         when(responseMock.getContentAsString()).thenReturn("{\"successful\": true, \"name\": \"hugo\"}");
121         Name name = subject.getName();
122         assertEquals("hugo", name.getName());
123         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=name");
124     }
125
126     @Test
127     public void shouldSetNewName() throws InterruptedException, ExecutionException, TimeoutException {
128         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=name&name=MyRobo")).thenReturn(requestMock);
129         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
130         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
131         when(requestMock.send()).thenReturn(responseMock);
132         when(responseMock.getEncoding()).thenReturn("utf8");
133         when(responseMock.getContentAsString()).thenReturn("{\"successful\": true, \"name\": \"MyRobo\"}");
134         Name name = subject.setName("MyRobo");
135         assertEquals("MyRobo", name.getName());
136         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=name&name=MyRobo");
137     }
138
139     @Test
140     public void shouldListErrors() throws InterruptedException, ExecutionException, TimeoutException {
141         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=error")).thenReturn(requestMock);
142         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
143         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
144         when(requestMock.send()).thenReturn(responseMock);
145         when(responseMock.getEncoding()).thenReturn("utf8");
146         when(responseMock.getContentAsString()).thenReturn(
147                 "{\"errors\": [{\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"04.05.2017\", \"time\": \"22:22:17\", \"unix\": 1493936537}, {\"error_code\": 15, \"error_message\": \"Grasi ist angehoben\", \"date\": \"02.05.2017\", \"time\": \"20:36:43\", \"unix\": 1493757403}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"26.04.2017\", \"time\": \"21:31:18\", \"unix\": 1493242278}, {\"error_code\": 13, \"error_message\": \"Kein Antrieb\", \"date\": \"21.04.2017\", \"time\": \"20:17:22\", \"unix\": 1492805842}, {\"error_code\": 10, \"error_message\": \"Grasi ist umgedreht\", \"date\": \"20.04.2017\", \"time\": \"20:14:37\", \"unix\": 1492719277}, {\"error_code\": 1, \"error_message\": \"Grasi hat Arbeitsbereich überschritten\", \"date\": \"12.04.2017\", \"time\": \"19:10:09\", \"unix\": 1492024209}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"10.04.2017\", \"time\": \"22:59:35\", \"unix\": 1491865175}, {\"error_code\": 1, \"error_message\": \"Grasi hat Arbeitsbereich überschritten\", \"date\": \"10.04.2017\", \"time\": \"21:21:55\", \"unix\": 1491859315}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"10.04.2017\", \"time\": \"20:26:13\", \"unix\": 1491855973}, {\"error_code\": 1, \"error_message\": \"Grasi hat Arbeitsbereich überschritten\", \"date\": \"09.04.2017\", \"time\": \"14:50:36\", \"unix\": 1491749436}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"09.04.2017\", \"time\": \"14:23:27\", \"unix\": 1491747807}], \"successful\": true}");
148         ErrorList list = subject.errorList();
149         assertEquals(11, list.getErrors().size());
150         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=error");
151     }
152
153     @Test
154     public void shouldRetrieveVersionInfo() throws InterruptedException, ExecutionException, TimeoutException {
155         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=version")).thenReturn(requestMock);
156         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
157         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
158         when(requestMock.send()).thenReturn(responseMock);
159         when(responseMock.getEncoding()).thenReturn("utf8");
160         when(responseMock.getContentAsString()).thenReturn(
161                 "{\"robonect\": {\"serial\": \"05D92D32-38355048-43203030\", \"version\": \"V0.9\", \"compiled\": \"2017-03-25 20:10:00\", \"comment\": \"V0.9c\"}, \"successful\": true}");
162         VersionInfo info = subject.getVersionInfo();
163         assertEquals("05D92D32-38355048-43203030", info.getRobonect().getSerial());
164         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=version");
165     }
166
167     @Test
168     public void shouldHandleProperEncoding() throws InterruptedException, ExecutionException, TimeoutException {
169         byte[] responseBytesISO88591 = "{\"successful\": true, \"name\": \"Mein Automower\", \"status\": {\"status\": 7, \"stopped\": true, \"duration\": 192, \"mode\": 1, \"battery\": 95, \"hours\": 41}, \"timer\": {\"status\": 2}, \"error\" : {\"error_code\": 15, \"error_message\": \"Utanför arbetsområdet\", \"date\": \"02.05.2017\", \"time\": \"20:36:43\", \"unix\": 1493757403}, \"wlan\": {\"signal\": -75}}"
170                 .getBytes(StandardCharsets.ISO_8859_1);
171         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=status")).thenReturn(requestMock);
172         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
173         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
174         when(requestMock.send()).thenReturn(responseMock);
175         when(responseMock.getEncoding()).thenReturn(null);
176         when(responseMock.getContent()).thenReturn(responseBytesISO88591);
177         MowerInfo info = subject.getMowerInfo();
178         assertEquals("Utanför arbetsområdet", info.getError().getErrorMessage());
179         verify(httpClientMock, times(1)).newRequest("http://123.456.789.123/json?cmd=status");
180     }
181
182     @Test(expected = RobonectCommunicationException.class)
183     public void shouldReceiveErrorAnswerOnInterruptedException()
184             throws InterruptedException, ExecutionException, TimeoutException {
185         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=status")).thenReturn(requestMock);
186         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
187         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
188         when(requestMock.send()).thenThrow(new InterruptedException("Mock Interrupted Exception"));
189         MowerInfo answer = subject.getMowerInfo();
190     }
191
192     @Test(expected = RobonectCommunicationException.class)
193     public void shouldReceiveErrorAnswerOnExecutionException()
194             throws InterruptedException, ExecutionException, TimeoutException {
195         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=status")).thenReturn(requestMock);
196         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
197         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
198         when(requestMock.send()).thenThrow(new ExecutionException(new Exception("Mock Exception")));
199         MowerInfo answer = subject.getMowerInfo();
200     }
201
202     @Test(expected = RobonectCommunicationException.class)
203     public void shouldReceiveErrorAnswerOnTimeoutException()
204             throws InterruptedException, ExecutionException, TimeoutException {
205         when(httpClientMock.newRequest("http://123.456.789.123/json?cmd=status")).thenReturn(requestMock);
206         when(requestMock.method(HttpMethod.GET)).thenReturn(requestMock);
207         when(requestMock.timeout(30000L, TimeUnit.MILLISECONDS)).thenReturn(requestMock);
208         when(requestMock.send()).thenThrow(new TimeoutException("Mock Timeout Exception"));
209         MowerInfo answer = subject.getMowerInfo();
210     }
211 }