]> git.basschouten.com Git - openhab-addons.git/blob
9a57d99ea97821c6b8d215a7906e5683bb777fe4
[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.dwdunwetter.internal.handler;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.mockito.ArgumentMatchers.*;
18 import static org.mockito.Mockito.*;
19
20 import java.io.InputStream;
21 import java.util.List;
22 import java.util.Objects;
23
24 import javax.xml.parsers.DocumentBuilder;
25 import javax.xml.parsers.DocumentBuilderFactory;
26
27 import org.hamcrest.CoreMatchers;
28 import org.junit.jupiter.api.BeforeEach;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.api.extension.ExtendWith;
31 import org.mockito.ArgumentCaptor;
32 import org.mockito.Mock;
33 import org.mockito.junit.jupiter.MockitoExtension;
34 import org.mockito.junit.jupiter.MockitoSettings;
35 import org.mockito.quality.Strictness;
36 import org.openhab.binding.dwdunwetter.internal.DwdUnwetterBindingConstants;
37 import org.openhab.core.config.core.Configuration;
38 import org.openhab.core.test.java.JavaTest;
39 import org.openhab.core.thing.Channel;
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.ThingStatusInfo;
44 import org.openhab.core.thing.ThingUID;
45 import org.openhab.core.thing.binding.ThingHandler;
46 import org.openhab.core.thing.binding.ThingHandlerCallback;
47 import org.openhab.core.thing.binding.builder.ChannelBuilder;
48 import org.openhab.core.thing.type.ChannelTypeUID;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Node;
51 import org.w3c.dom.NodeList;
52
53 /**
54  * Test cases for {@link DwdUnwetterHandler}. The tests provide mocks for supporting entities using Mockito.
55  *
56  * @author Martin Koehler - Initial contribution
57  */
58 @ExtendWith(MockitoExtension.class)
59 @MockitoSettings(strictness = Strictness.LENIENT)
60 public class DwdUnwetterHandlerTest extends JavaTest {
61
62     private ThingHandler handler;
63
64     private @Mock ThingHandlerCallback callback;
65     private @Mock Thing thing;
66
67     @BeforeEach
68     public void setUp() {
69         when(callback.createChannelBuilder(any(ChannelUID.class), any(ChannelTypeUID.class)))
70                 .thenAnswer(invocation -> ChannelBuilder.create(invocation.getArgument(0, ChannelUID.class))
71                         .withType(invocation.getArgument(1, ChannelTypeUID.class)));
72
73         handler = new DwdUnwetterHandler(thing);
74         handler.setCallback(callback);
75         // mock getConfiguration to prevent NPEs
76         when(thing.getUID()).thenReturn(new ThingUID(DwdUnwetterBindingConstants.BINDING_ID, "test"));
77         Configuration configuration = new Configuration();
78         configuration.put("refresh", Integer.valueOf("1"));
79         configuration.put("warningCount", Integer.valueOf("1"));
80         when(thing.getConfiguration()).thenReturn(configuration);
81     }
82
83     @Test
84     public void testInitializeShouldCallTheCallback() {
85         // we expect the handler#initialize method to call the callback during execution and
86         // pass it the thing and a ThingStatusInfo object containing the ThingStatus of the thing.
87         handler.initialize();
88
89         // the argument captor will capture the argument of type ThingStatusInfo given to the
90         // callback#statusUpdated method.
91         ArgumentCaptor<ThingStatusInfo> statusInfoCaptor = ArgumentCaptor.forClass(ThingStatusInfo.class);
92
93         // verify the interaction with the callback and capture the ThingStatusInfo argument:
94         waitForAssert(() -> {
95             verify(callback, times(1)).statusUpdated(eq(thing), statusInfoCaptor.capture());
96         });
97
98         // assert that the (temporary) UNKNOWN status was to the mocked thing first:
99         assertThat(statusInfoCaptor.getAllValues().get(0).getStatus(), is(ThingStatus.UNKNOWN));
100     }
101
102     /**
103      * Tests that the labels of the channels are equal to the ChannelType Definition
104      */
105     @Test
106     public void testLabels() throws Exception {
107         handler.initialize();
108
109         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
110         DocumentBuilder builder = factory.newDocumentBuilder();
111         InputStream stream = getClass().getResourceAsStream("/OH-INF/thing/thing-types.xml");
112         Document document = builder.parse(stream);
113         NodeList nodeList = document.getElementsByTagName("channel-type");
114
115         thing = handler.getThing();
116         List<Channel> channels = thing.getChannels();
117         for (Channel channel : channels) {
118             String label = getLabel(nodeList, channel.getChannelTypeUID());
119             assertThat(channel.getLabel(), CoreMatchers.startsWith(label));
120         }
121     }
122
123     private String getLabel(NodeList nodeList, ChannelTypeUID uuid) {
124         for (int i = 0; i < nodeList.getLength(); i++) {
125             Node node = nodeList.item(i);
126             Node nodeId = node.getAttributes().getNamedItem("id");
127             if (nodeId == null) {
128                 continue;
129             }
130             if (Objects.equals(nodeId.getTextContent(), uuid.getId())) {
131                 return getLabel(node.getChildNodes());
132             }
133         }
134         return null;
135     }
136
137     private String getLabel(NodeList nodeList) {
138         for (int i = 0; i < nodeList.getLength(); i++) {
139             Node node = nodeList.item(i);
140             if (node.getNodeName().equals("label")) {
141                 return node.getTextContent();
142             }
143         }
144         return null;
145     }
146 }