]> git.basschouten.com Git - openhab-addons.git/blob
d49e33f37df90066967b81c49fb2df1ea89c04ba
[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.mybmw.internal.handler.backend;
14
15 import static org.junit.jupiter.api.Assertions.assertEquals;
16 import static org.junit.jupiter.api.Assertions.assertNotNull;
17 import static org.junit.jupiter.api.Assertions.fail;
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.ArgumentMatchers.anyLong;
20 import static org.mockito.ArgumentMatchers.anyString;
21 import static org.mockito.Mockito.doReturn;
22
23 import java.util.List;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.TimeoutException;
26
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jetty.client.HttpClient;
29 import org.eclipse.jetty.client.api.ContentResponse;
30 import org.eclipse.jetty.client.api.Request;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.api.Test;
33 import org.mockito.Mockito;
34 import org.openhab.binding.mybmw.internal.MyBMWBridgeConfiguration;
35 import org.openhab.binding.mybmw.internal.dto.remote.ExecutionStatusContainer;
36 import org.openhab.binding.mybmw.internal.dto.vehicle.Vehicle;
37 import org.openhab.binding.mybmw.internal.dto.vehicle.VehicleBase;
38 import org.openhab.binding.mybmw.internal.dto.vehicle.VehicleStateContainer;
39 import org.openhab.binding.mybmw.internal.handler.enums.RemoteService;
40 import org.openhab.binding.mybmw.internal.util.FileReader;
41 import org.openhab.binding.mybmw.internal.utils.BimmerConstants;
42 import org.openhab.binding.mybmw.internal.utils.ImageProperties;
43 import org.openhab.core.io.net.http.HttpClientFactory;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 import ch.qos.logback.classic.Level;
48
49 /**
50  * this test tests the different MyBMWProxy request types (GET, POST) and their errors (SUCCESS, other)
51  * 
52  * @author Martin Grassl - initial contribution
53  */
54 @NonNullByDefault
55 public class MyBMWHttpProxyTest {
56
57     private final Logger logger = LoggerFactory.getLogger(MyBMWHttpProxyTest.class);
58
59     @BeforeEach
60     public void setupLogger() {
61         Logger root = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
62
63         if ("debug".equals(System.getenv("LOG_LEVEL"))) {
64             ((ch.qos.logback.classic.Logger) root).setLevel(Level.DEBUG);
65         } else if ("trace".equals(System.getenv("LOG_LEVEL"))) {
66             ((ch.qos.logback.classic.Logger) root).setLevel(Level.TRACE);
67         }
68
69         logger.trace("tracing enabled");
70         logger.debug("debugging enabled");
71         logger.info("info enabled");
72     }
73
74     @Test
75     void testWrongBrand() {
76         // test successful GET for vehicle state
77         String responseContent = FileReader.fileToString("responses/BEV/vehicles_state.json");
78         MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(200, responseContent);
79
80         try {
81             myBMWProxy.requestVehicleState("testVin", "WRONG_BRAND");
82         } catch (NetworkException e) {
83             assertEquals("Unknown Brand WRONG_BRAND", e.getMessage());
84         }
85     }
86
87     @Test
88     void testSuccessfulGet() {
89         // test successful GET for vehicle state
90         String responseContent = FileReader.fileToString("responses/BEV/vehicles_state.json");
91         MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(200, responseContent);
92
93         try {
94             VehicleStateContainer vehicleStateContainer = myBMWProxy.requestVehicleState("testVin",
95                     BimmerConstants.BRAND_BMW);
96             assertEquals(2686, vehicleStateContainer.getState().getCurrentMileage());
97         } catch (NetworkException e) {
98             fail(e.toString());
99         }
100     }
101
102     @Test
103     void testErrorGet() {
104         // test successful GET for vehicle state
105         String responseContent = FileReader.fileToString("responses/BEV/vehicles_state.json");
106         MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(400, responseContent);
107
108         try {
109             myBMWProxy.requestVehicleState("testVin", BimmerConstants.BRAND_BMW);
110
111             fail("here an exception should be thrown");
112         } catch (NetworkException e) {
113             assertEquals(400, e.getStatus());
114         }
115     }
116
117     @Test
118     void testSuccessfulPost() {
119         // test successful POST for remote service execution
120         String responseContent = FileReader.fileToString("responses/MILD_HYBRID/remote_service_call.json");
121         MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(200, responseContent);
122
123         try {
124             ExecutionStatusContainer executionStatusContainer = myBMWProxy.executeRemoteServiceCall("testVin",
125                     BimmerConstants.BRAND_BMW, RemoteService.LIGHT_FLASH);
126             assertNotNull(executionStatusContainer.getCreationTime());
127             assertNotNull(executionStatusContainer.getEventId());
128             assertEquals("", executionStatusContainer.getEventStatus());
129         } catch (NetworkException e) {
130             fail(e.toString());
131         }
132     }
133
134     @Test
135     void testErrorPost() {
136         // test successful POST for remote service execution
137         String responseContent = FileReader.fileToString("responses/MILD_HYBRID/remote_service_call.json");
138         MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(400, responseContent);
139
140         try {
141             myBMWProxy.executeRemoteServiceCall("testVin", BimmerConstants.BRAND_BMW, RemoteService.LIGHT_FLASH);
142             fail("here an exception should be thrown");
143         } catch (NetworkException e) {
144             assertEquals(400, e.getStatus());
145         }
146     }
147
148     @Test
149     void testSuccessfulImage() {
150         // test successful POST for remote service execution
151         MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(200, "test");
152
153         try {
154             byte[] image = myBMWProxy.requestImage("testVin", BimmerConstants.BRAND_BMW, new ImageProperties());
155             assertNotNull(image);
156         } catch (NetworkException e) {
157             fail(e.toString());
158         }
159     }
160
161     @Test
162     void testSuccessfulGetVehicles() {
163         HttpClientFactory httpClientFactoryMock = Mockito.mock(HttpClientFactory.class);
164         HttpClient httpClientMock = Mockito.mock(HttpClient.class);
165         Mockito.when(httpClientFactoryMock.getCommonHttpClient()).thenReturn(httpClientMock);
166
167         MyBMWBridgeConfiguration myBMWBridgeConfiguration = new MyBMWBridgeConfiguration();
168
169         MyBMWHttpProxy myBMWProxyMock = Mockito
170                 .spy(new MyBMWHttpProxy(httpClientFactoryMock, myBMWBridgeConfiguration));
171
172         String vehiclesBaseString = FileReader.fileToString("responses/BEV/vehicles_base.json");
173         List<VehicleBase> baseVehicles = JsonStringDeserializer.getVehicleBaseList(vehiclesBaseString);
174
175         String vehicleStateString = FileReader.fileToString("responses/BEV/vehicles_state.json");
176         VehicleStateContainer vehicleStateContainer = JsonStringDeserializer.getVehicleState(vehicleStateString);
177
178         try {
179             doReturn(baseVehicles).when(myBMWProxyMock).requestVehiclesBase();
180             doReturn(vehicleStateContainer).when(myBMWProxyMock).requestVehicleState(anyString(), anyString());
181
182             List<Vehicle> vehicles = myBMWProxyMock.requestVehicles();
183
184             logger.debug("found vehicles {}", vehicles.toString());
185
186             assertNotNull(vehicles);
187             assertEquals(1, vehicles.size());
188             assertEquals("I20", vehicles.get(0).getVehicleBase().getAttributes().getBodyType());
189
190         } catch (NetworkException e) {
191             fail("vehicles not loaded properly", e);
192         }
193     }
194
195     MyBMWHttpProxy generateMyBmwProxy(int statuscode, String responseContent) {
196         HttpClientFactory httpClientFactoryMock = Mockito.mock(HttpClientFactory.class);
197         HttpClient httpClientMock = Mockito.mock(HttpClient.class);
198         Request requestMock = Mockito.mock(Request.class);
199         Mockito.when(httpClientMock.newRequest(Mockito.anyString())).thenReturn(requestMock);
200         Mockito.when(httpClientMock.POST(Mockito.anyString())).thenReturn(requestMock);
201         MyBMWBridgeConfiguration myBMWBridgeConfiguration = new MyBMWBridgeConfiguration();
202         Mockito.when(httpClientFactoryMock.getCommonHttpClient()).thenReturn(httpClientMock);
203
204         ContentResponse responseMock = Mockito.mock(ContentResponse.class);
205         Mockito.when(responseMock.getStatus()).thenReturn(statuscode);
206         Mockito.when(responseMock.getContent()).thenReturn(responseContent.getBytes());
207         Mockito.when(responseMock.getContentAsString()).thenReturn(responseContent);
208         try {
209             Mockito.when(requestMock.timeout(anyLong(), any())).thenReturn(requestMock);
210             Mockito.when(requestMock.send()).thenReturn(responseMock);
211         } catch (InterruptedException e1) {
212             logger.error(e1.getMessage(), e1);
213         } catch (TimeoutException e1) {
214             logger.error(e1.getMessage(), e1);
215         } catch (ExecutionException e1) {
216             logger.error(e1.getMessage(), e1);
217         }
218
219         return new MyBMWHttpProxy(httpClientFactoryMock, myBMWBridgeConfiguration);
220     }
221 }