2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mybmw.internal.handler.backend;
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;
23 import java.util.List;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.TimeoutException;
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;
47 import ch.qos.logback.classic.Level;
50 * this test tests the different MyBMWProxy request types (GET, POST) and their errors (SUCCESS, other)
52 * @author Martin Grassl - initial contribution
55 public class MyBMWHttpProxyTest {
57 private final Logger logger = LoggerFactory.getLogger(MyBMWHttpProxyTest.class);
60 public void setupLogger() {
61 Logger root = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
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);
69 logger.trace("tracing enabled");
70 logger.debug("debugging enabled");
71 logger.info("info enabled");
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);
81 myBMWProxy.requestVehicleState("testVin", "WRONG_BRAND");
82 } catch (NetworkException e) {
83 assertEquals("Unknown Brand WRONG_BRAND", e.getMessage());
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);
94 VehicleStateContainer vehicleStateContainer = myBMWProxy.requestVehicleState("testVin",
95 BimmerConstants.BRAND_BMW);
96 assertEquals(2686, vehicleStateContainer.getState().getCurrentMileage());
97 } catch (NetworkException e) {
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);
109 myBMWProxy.requestVehicleState("testVin", BimmerConstants.BRAND_BMW);
111 fail("here an exception should be thrown");
112 } catch (NetworkException e) {
113 assertEquals(400, e.getStatus());
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);
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) {
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);
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());
149 void testSuccessfulImage() {
150 // test successful POST for remote service execution
151 MyBMWHttpProxy myBMWProxy = generateMyBmwProxy(200, "test");
154 byte[] image = myBMWProxy.requestImage("testVin", BimmerConstants.BRAND_BMW, new ImageProperties());
155 assertNotNull(image);
156 } catch (NetworkException e) {
162 void testSuccessfulGetVehicles() {
163 HttpClientFactory httpClientFactoryMock = Mockito.mock(HttpClientFactory.class);
164 HttpClient httpClientMock = Mockito.mock(HttpClient.class);
165 Mockito.when(httpClientFactoryMock.getCommonHttpClient()).thenReturn(httpClientMock);
167 MyBMWBridgeConfiguration myBMWBridgeConfiguration = new MyBMWBridgeConfiguration();
169 MyBMWHttpProxy myBMWProxyMock = Mockito
170 .spy(new MyBMWHttpProxy(httpClientFactoryMock, myBMWBridgeConfiguration));
172 String vehiclesBaseString = FileReader.fileToString("responses/BEV/vehicles_base.json");
173 List<VehicleBase> baseVehicles = JsonStringDeserializer.getVehicleBaseList(vehiclesBaseString);
175 String vehicleStateString = FileReader.fileToString("responses/BEV/vehicles_state.json");
176 VehicleStateContainer vehicleStateContainer = JsonStringDeserializer.getVehicleState(vehicleStateString);
179 doReturn(baseVehicles).when(myBMWProxyMock).requestVehiclesBase();
180 doReturn(vehicleStateContainer).when(myBMWProxyMock).requestVehicleState(anyString(), anyString());
182 List<Vehicle> vehicles = myBMWProxyMock.requestVehicles();
184 logger.debug("found vehicles {}", vehicles.toString());
186 assertNotNull(vehicles);
187 assertEquals(1, vehicles.size());
188 assertEquals("I20", vehicles.get(0).getVehicleBase().getAttributes().getBodyType());
190 } catch (NetworkException e) {
191 fail("vehicles not loaded properly", e);
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);
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);
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);
219 return new MyBMWHttpProxy(httpClientFactoryMock, myBMWBridgeConfiguration);