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.mqtt.homie.generic.internal.mapping;
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.*;
20 import java.util.concurrent.CompletableFuture;
21 import java.util.function.Function;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.junit.jupiter.api.Test;
26 import org.junit.jupiter.api.extension.ExtendWith;
27 import org.mockito.Mock;
28 import org.mockito.junit.jupiter.MockitoExtension;
29 import org.mockito.junit.jupiter.MockitoSettings;
30 import org.mockito.quality.Strictness;
31 import org.openhab.binding.mqtt.generic.tools.ChildMap;
32 import org.openhab.binding.mqtt.homie.internal.handler.ThingChannelConstants;
33 import org.openhab.binding.mqtt.homie.internal.homie300.DeviceCallback;
34 import org.openhab.binding.mqtt.homie.internal.homie300.Node;
35 import org.openhab.binding.mqtt.homie.internal.homie300.NodeAttributes;
38 * Tests cases for {@link HomieChildMap}.
40 * @author David Graeff - Initial contribution
42 @ExtendWith(MockitoExtension.class)
43 @MockitoSettings(strictness = Strictness.LENIENT)
45 public class HomieChildMapTests {
46 private @Mock @NonNullByDefault({}) DeviceCallback callbackMock;
48 private final String deviceID = ThingChannelConstants.TEST_HOMIE_THING.getId();
49 private final String deviceTopic = "homie/" + deviceID;
51 // A completed future is returned for a subscribe call to the attributes
52 final CompletableFuture<@Nullable Void> future = CompletableFuture.completedFuture(null);
54 ChildMap<Node> subject = new ChildMap<>();
56 private Node createNode(String id) {
57 Node node = new Node(deviceTopic, id, ThingChannelConstants.TEST_HOMIE_THING, callbackMock,
58 spy(new NodeAttributes()));
59 doReturn(future).when(node.attributes).subscribeAndReceive(any(), any(), anyString(), any(), anyInt());
60 doReturn(future).when(node.attributes).unsubscribe();
64 private void removedNode(Node node) {
65 callbackMock.nodeRemoved(node);
68 public static class AddedAction implements Function<Node, CompletableFuture<Void>> {
70 public CompletableFuture<Void> apply(Node t) {
71 return CompletableFuture.completedFuture(null);
76 public void testArrayToSubtopicCreateAndRemove() {
77 AddedAction addedAction = spy(new AddedAction());
79 // Assign "abc,def" to the
80 subject.apply(new String[] { "abc", "def" }, addedAction, this::createNode, this::removedNode);
82 assertThat(future.isDone(), is(true));
83 assertThat(subject.get("abc").nodeID, is("abc"));
84 assertThat(subject.get("def").nodeID, is("def"));
86 verify(addedAction, times(2)).apply(any());
88 Node soonToBeRemoved = subject.get("def");
89 subject.apply(new String[] { "abc" }, addedAction, this::createNode, this::removedNode);
90 verify(callbackMock).nodeRemoved(eq(soonToBeRemoved));