]> git.basschouten.com Git - openhab-addons.git/blob
bb672f80a22fc06b31b8f2030ffdc1c40f00aeaf
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.groupepsa.internal.things;
14
15 import static org.mockito.ArgumentMatchers.*;
16 import static org.mockito.Mockito.*;
17
18 import java.io.BufferedReader;
19 import java.io.InputStream;
20 import java.io.InputStreamReader;
21 import java.util.stream.Collectors;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jetty.client.HttpClient;
25 import org.eclipse.jetty.client.HttpContentResponse;
26 import org.eclipse.jetty.client.HttpResponse;
27 import org.junit.jupiter.api.AfterEach;
28 import org.junit.jupiter.api.BeforeEach;
29 import org.junit.jupiter.api.Test;
30 import org.mockito.Mock;
31 import org.mockito.MockitoAnnotations;
32 import org.openhab.binding.groupepsa.internal.bridge.GroupePSABridgeHandler;
33 import org.openhab.binding.groupepsa.internal.rest.api.GroupePSAConnectApi;
34 import org.openhab.binding.groupepsa.internal.rest.exceptions.GroupePSACommunicationException;
35 import org.openhab.core.auth.client.oauth2.OAuthFactory;
36 import org.openhab.core.config.core.Configuration;
37 import org.openhab.core.library.types.DateTimeType;
38 import org.openhab.core.library.types.StringType;
39 import org.openhab.core.thing.Bridge;
40 import org.openhab.core.thing.ChannelUID;
41 import org.openhab.core.thing.Thing;
42 import org.openhab.core.thing.ThingStatus;
43 import org.openhab.core.thing.ThingStatusDetail;
44 import org.openhab.core.thing.ThingUID;
45 import org.openhab.core.thing.binding.ThingHandlerCallback;
46 import org.openhab.core.types.State;
47
48 /**
49  * The {@link GroupePSAHandlerTest} is responsible for testing the binding
50  *
51  * @author Arjan Mels - Initial contribution
52  */
53 @NonNullByDefault
54 public class GroupePSAHandlerTest {
55     private @NonNullByDefault({}) AutoCloseable closeable;
56
57     private @NonNullByDefault({}) GroupePSAConnectApi api;
58     private @NonNullByDefault({}) GroupePSABridgeHandler bridgeHandler;
59     private @NonNullByDefault({}) GroupePSAHandler thingHandler;
60
61     private @NonNullByDefault({}) @Mock ThingHandlerCallback thingCallback;
62     private @NonNullByDefault({}) @Mock ThingHandlerCallback bridgeCallback;
63     private @NonNullByDefault({}) @Mock Thing thing;
64     private @NonNullByDefault({}) @Mock Bridge bridge;
65
66     private @NonNullByDefault({}) @Mock OAuthFactory oAuthFactory;
67     private @NonNullByDefault({}) @Mock HttpClient httpClient;
68
69     static String getResourceFileAsString(String fileName) throws GroupePSACommunicationException {
70         try (InputStream is = GroupePSAConnectApi.class.getResourceAsStream(fileName)) {
71             try (InputStreamReader isr = new InputStreamReader(is); BufferedReader reader = new BufferedReader(isr)) {
72                 return reader.lines().collect(Collectors.joining(System.lineSeparator()));
73             }
74         } catch (Exception e) {
75             throw new GroupePSACommunicationException(e);
76         }
77     }
78
79     static HttpContentResponse createHttpResponse(String file) throws GroupePSACommunicationException {
80         return new HttpContentResponse(new HttpResponse(null, null).status(200),
81                 getResourceFileAsString("/" + file).getBytes(), "json", "UTF-8");
82     }
83
84     @BeforeEach
85     @SuppressWarnings("null")
86     public void setUp() throws GroupePSACommunicationException {
87         closeable = MockitoAnnotations.openMocks(this);
88
89         // Create real objects
90         bridgeHandler = spy(new GroupePSABridgeHandler(bridge, oAuthFactory, httpClient));
91         thingHandler = spy(new GroupePSAHandler(thing));
92         api = spy(new GroupePSAConnectApi(httpClient, bridgeHandler, "clientId", "realm"));
93
94         // Setup API mock
95         doReturn(createHttpResponse("dummy_user.json")).when(api).executeRequest(contains("user"), anyString());
96         doReturn(createHttpResponse("dummy_vehiclestatus3.json")).when(api).executeRequest(contains("status"),
97                 anyString());
98
99         // Setup bridge handler mock
100         bridgeHandler.setCallback(bridgeCallback);
101         doReturn(api).when(bridgeHandler).getAPI();
102
103         // Setup bridge mock
104         Configuration bridgeConfig = new Configuration();
105         bridgeConfig.put("vendor", "OPEL");
106         bridgeConfig.put("userName", "user");
107         bridgeConfig.put("password", "pwd");
108         bridgeConfig.put("clientId", "clientIdValue");
109         bridgeConfig.put("clientSecret", "clientSecretValue");
110         doReturn(bridgeConfig).when(bridge).getConfiguration();
111         doReturn(ThingStatus.ONLINE).when(bridge).getStatus();
112         doReturn(bridgeHandler).when(bridge).getHandler();
113         doReturn(new ThingUID("a:b:c")).when(bridge).getUID();
114
115         // Setup thing mock
116         Configuration thingConfig = new Configuration();
117         thingConfig.put("id", "mock_id");
118         doReturn(thingConfig).when(thing).getConfiguration();
119         doReturn(new ThingUID("a:b:c")).when(thing).getUID();
120
121         // Setup thing handler mock
122         thingHandler.setCallback(thingCallback);
123         doReturn(bridge).when(thingHandler).getBridge();
124         doNothing().when(thingHandler).buildDoorChannels(any());
125     }
126
127     @AfterEach
128     public void tearDown() throws Exception {
129         // Free any resources, like open database connections, files etc.
130         thingHandler.dispose();
131         bridgeHandler.dispose();
132         closeable.close();
133     }
134
135     @Test
136     public void intializeAndCheckChannels() throws InterruptedException {
137         // Initialize the bridge
138         bridgeHandler.initialize();
139
140         // check that the bridge is online
141         verify(bridgeCallback, timeout(2000)).statusUpdated(eq(bridge),
142                 argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE)));
143
144         // Initialize the thing
145         thingHandler.initialize();
146
147         // check that the thing is offline without detail (last update time is not
148         // within 15 minutes)
149         verify(thingCallback, timeout(2000)).statusUpdated(eq(thing),
150                 argThat(arg -> arg.getStatus().equals(ThingStatus.OFFLINE)
151                         && arg.getStatusDetail().equals(ThingStatusDetail.NONE)));
152
153         // check that the channels are updated
154         verify(thingCallback, atLeast(30)).stateUpdated(any(ChannelUID.class), any(State.class));
155         verify(thingCallback).stateUpdated(eq(new ChannelUID("a:b:c:electric#chargingStatus")),
156                 eq(new StringType("Disconnected")));
157         verify(thingCallback).stateUpdated(eq(new ChannelUID("a:b:c:various#lastUpdated")), any(DateTimeType.class));
158     }
159 }