]> git.basschouten.com Git - openhab-addons.git/blob
b9f83b6b767beb87422038aa9e7ca7e44545a10d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.mqtt.generic.mapping;
14
15 import static java.lang.annotation.ElementType.FIELD;
16 import static org.hamcrest.CoreMatchers.is;
17 import static org.junit.Assert.*;
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.Mockito.doReturn;
20
21 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy;
23 import java.lang.annotation.Target;
24 import java.lang.reflect.Field;
25 import java.math.BigDecimal;
26 import java.util.concurrent.CompletableFuture;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.ScheduledExecutorService;
29 import java.util.concurrent.ScheduledThreadPoolExecutor;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.TimeoutException;
32
33 import org.eclipse.jdt.annotation.NonNull;
34 import org.eclipse.jdt.annotation.Nullable;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.mockito.Mock;
38 import org.mockito.MockitoAnnotations;
39 import org.openhab.binding.mqtt.generic.mapping.SubscribeFieldToMQTTtopic.FieldChanged;
40 import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
41
42 /**
43  * Tests cases for {@link org.openhab.binding.mqtt.generic.mapping.SubscribeFieldToMQTTtopic}.
44  *
45  * @author David Graeff - Initial contribution
46  */
47 public class SubscribeFieldToMQTTtopicTests {
48     @Retention(RetentionPolicy.RUNTIME)
49     @Target({ FIELD })
50     private @interface TestValue {
51         String value() default "";
52     }
53
54     @TopicPrefix
55     public static class Attributes extends AbstractMqttAttributeClass {
56         @SuppressWarnings("unused")
57         public transient String ignoreTransient = "";
58         @SuppressWarnings("unused")
59         public final String ignoreFinal = "";
60
61         public @TestValue("string") String aString;
62         public @TestValue("false") Boolean aBoolean;
63         public @TestValue("10") Long aLong;
64         public @TestValue("10") Integer aInteger;
65         public @TestValue("10") BigDecimal aDecimal;
66
67         public @TestValue("10") @TopicPrefix("a") int Int = 24;
68         public @TestValue("false") boolean aBool = true;
69         public @TestValue("abc,def") @MQTTvalueTransform(splitCharacter = ",") String[] properties;
70
71         public enum ReadyState {
72             unknown,
73             init,
74             ready,
75         }
76
77         public @TestValue("init") ReadyState state = ReadyState.unknown;
78
79         public enum DataTypeEnum {
80             unknown,
81             integer_,
82             float_,
83         }
84
85         public @TestValue("integer") @MQTTvalueTransform(suffix = "_") DataTypeEnum datatype = DataTypeEnum.unknown;
86
87         @Override
88         public @NonNull Object getFieldsOf() {
89             return this;
90         }
91     }
92
93     Attributes attributes = new Attributes();
94
95     @Mock
96     MqttBrokerConnection connection;
97
98     @Mock
99     SubscribeFieldToMQTTtopic fieldSubscriber;
100
101     @Mock
102     FieldChanged fieldChanged;
103
104     @Before
105     public void setUp() {
106         MockitoAnnotations.initMocks(this);
107         doReturn(CompletableFuture.completedFuture(true)).when(connection).subscribe(any(), any());
108     }
109
110     @Test(expected = TimeoutException.class)
111     public void TimeoutIfNoMessageReceive()
112             throws InterruptedException, NoSuchFieldException, ExecutionException, TimeoutException {
113         final Field field = Attributes.class.getField("Int");
114         ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
115
116         SubscribeFieldToMQTTtopic subscriber = new SubscribeFieldToMQTTtopic(scheduler, field, fieldChanged,
117                 "homie/device123", false);
118         subscriber.subscribeAndReceive(connection, 1000).get(50, TimeUnit.MILLISECONDS);
119     }
120
121     @Test(expected = ExecutionException.class)
122     public void MandatoryMissing()
123             throws InterruptedException, NoSuchFieldException, ExecutionException, TimeoutException {
124         final Field field = Attributes.class.getField("Int");
125         ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
126
127         SubscribeFieldToMQTTtopic subscriber = new SubscribeFieldToMQTTtopic(scheduler, field, fieldChanged,
128                 "homie/device123", true);
129         subscriber.subscribeAndReceive(connection, 50).get();
130     }
131
132     @Test
133     public void MessageReceive()
134             throws InterruptedException, NoSuchFieldException, ExecutionException, TimeoutException {
135         final FieldChanged changed = (field, value) -> {
136             try {
137                 field.set(attributes.getFieldsOf(), value);
138             } catch (IllegalArgumentException | IllegalAccessException e) {
139                 fail(e.getMessage());
140             }
141         };
142         final Field field = Attributes.class.getField("Int");
143         ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
144
145         SubscribeFieldToMQTTtopic subscriber = new SubscribeFieldToMQTTtopic(scheduler, field, changed,
146                 "homie/device123", false);
147         CompletableFuture<@Nullable Void> future = subscriber.subscribeAndReceive(connection, 1000);
148
149         // Simulate a received MQTT message
150         subscriber.processMessage("ignored", "10".getBytes());
151         // No timeout should happen
152         future.get(50, TimeUnit.MILLISECONDS);
153         assertThat(attributes.Int, is(10));
154     }
155 }