]> git.basschouten.com Git - openhab-addons.git/blob
c99a02b57640ac49543fb508852dbc860accbc0d
[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.dmx.test;
14
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.core.Is.is;
17 import static org.hamcrest.number.IsCloseTo.closeTo;
18 import static org.junit.jupiter.api.Assertions.*;
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.*;
21 import static org.openhab.binding.dmx.test.TestBridgeHandler.THING_TYPE_TEST_BRIDGE;
22
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Objects;
26 import java.util.function.Consumer;
27
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.mockito.ArgumentCaptor;
30 import org.mockito.ArgumentMatchers;
31 import org.openhab.core.config.core.Configuration;
32 import org.openhab.core.library.types.PercentType;
33 import org.openhab.core.test.java.JavaTest;
34 import org.openhab.core.thing.Bridge;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.thing.Thing;
37 import org.openhab.core.thing.ThingStatus;
38 import org.openhab.core.thing.ThingStatusDetail;
39 import org.openhab.core.thing.binding.ThingHandler;
40 import org.openhab.core.thing.binding.ThingHandlerCallback;
41 import org.openhab.core.thing.binding.builder.BridgeBuilder;
42 import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
43 import org.openhab.core.types.State;
44
45 /**
46  * Common utilities for DMX thing handler tests.
47  *
48  * @author Simon Kaufmann - initial contribution and API
49  *
50  */
51 @NonNullByDefault
52 public class AbstractDmxThingTestParent extends JavaTest {
53
54     private @NonNullByDefault({}) Map<String, Object> bridgeProperties;
55
56     protected @NonNullByDefault({}) Bridge bridge;
57     protected @NonNullByDefault({}) TestBridgeHandler dmxBridgeHandler;
58     protected @NonNullByDefault({}) ThingHandlerCallback mockCallback;
59
60     protected void setup() {
61         initializeBridge();
62
63         mockCallback = mock(ThingHandlerCallback.class);
64         doAnswer(answer -> {
65             ((Thing) answer.getArgument(0)).setStatusInfo(answer.getArgument(1));
66             return null;
67         }).when(mockCallback).statusUpdated(any(), any());
68     }
69
70     private void initializeBridge() {
71         bridgeProperties = new HashMap<>();
72         bridge = BridgeBuilder.create(THING_TYPE_TEST_BRIDGE, "testbridge").withLabel("Test Bridge")
73                 .withConfiguration(new Configuration(bridgeProperties)).build();
74         dmxBridgeHandler = new TestBridgeHandler(bridge);
75         bridge.setHandler(dmxBridgeHandler);
76         ThingHandlerCallback bridgeHandler = mock(ThingHandlerCallback.class);
77         doAnswer(answer -> {
78             ((Thing) answer.getArgument(0)).setStatusInfo(answer.getArgument(1));
79             return null;
80         }).when(bridgeHandler).statusUpdated(any(), any());
81         dmxBridgeHandler.setCallback(bridgeHandler);
82         dmxBridgeHandler.initialize();
83     }
84
85     protected void initializeHandler(ThingHandler handler) {
86         handler.getThing().setHandler(handler);
87         handler.setCallback(mockCallback);
88         handler.initialize();
89     }
90
91     protected void assertThingStatus(Thing thing) {
92         // check that thing turns online if properly configured
93         waitForAssert(() -> assertEquals(ThingStatus.ONLINE, thing.getStatusInfo().getStatus()));
94
95         // check that thing properly follows bridge status
96         ThingHandler handler = thing.getHandler();
97         assertNotNull(handler);
98         Objects.requireNonNull(handler);
99         handler.bridgeStatusChanged(ThingStatusInfoBuilder.create(ThingStatus.OFFLINE).build());
100         waitForAssert(() -> assertEquals(ThingStatus.OFFLINE, thing.getStatusInfo().getStatus()));
101         handler.bridgeStatusChanged(ThingStatusInfoBuilder.create(ThingStatus.ONLINE).build());
102         waitForAssert(() -> assertEquals(ThingStatus.ONLINE, thing.getStatusInfo().getStatus()));
103     }
104
105     protected void assertThingStatusWithoutBridge(ThingHandler handler) {
106         handler.setCallback(mockCallback);
107         handler.initialize();
108         waitForAssert(() -> {
109             assertEquals(ThingStatus.OFFLINE, handler.getThing().getStatus());
110             assertEquals(ThingStatusDetail.CONFIGURATION_ERROR, handler.getThing().getStatusInfo().getStatusDetail());
111         });
112     }
113
114     public void assertPercentTypeCommands(ThingHandler handler, ChannelUID channelUID, int fadeTime) {
115         long currentTime = System.currentTimeMillis();
116
117         // set 30%
118         handler.handleCommand(channelUID, new PercentType(30));
119         currentTime = dmxBridgeHandler.calcBuffer(currentTime, fadeTime);
120
121         waitForAssert(() -> {
122             assertChannelStateUpdate(channelUID,
123                     state -> assertThat(((PercentType) state).doubleValue(), is(closeTo(30.0, 1.0))));
124         });
125
126         // set 0%
127         handler.handleCommand(channelUID, PercentType.ZERO);
128         currentTime = dmxBridgeHandler.calcBuffer(currentTime, fadeTime);
129
130         waitForAssert(() -> {
131             assertChannelStateUpdate(channelUID, state -> assertEquals(PercentType.ZERO, state));
132         });
133
134         // set 100%
135         handler.handleCommand(channelUID, PercentType.HUNDRED);
136         currentTime = dmxBridgeHandler.calcBuffer(currentTime, fadeTime);
137
138         waitForAssert(() -> {
139             assertChannelStateUpdate(channelUID,
140                     state -> assertThat(((PercentType) state).doubleValue(), is(closeTo(100.0, 0.5))));
141         });
142     }
143
144     protected void assertChannelStateUpdate(ChannelUID channelUID, Consumer<State> stateAssertion) {
145         ArgumentCaptor<State> captor = ArgumentCaptor.forClass(State.class);
146         verify(mockCallback, atLeastOnce()).stateUpdated(ArgumentMatchers.eq(channelUID), captor.capture());
147         State value = captor.getValue();
148         stateAssertion.accept(value);
149     }
150 }