]> git.basschouten.com Git - openhab-addons.git/blob
13acf950a1f8f0ec34aa28a05a07ba162bbd9e8e
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.tr064.internal.phonebook;
14
15 import static org.mockito.ArgumentMatchers.*;
16 import static org.mockito.Mockito.*;
17 import static org.mockito.MockitoAnnotations.openMocks;
18 import static org.openhab.binding.tr064.internal.Tr064BindingConstants.*;
19
20 import java.math.BigDecimal;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Optional;
26 import java.util.Set;
27
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.junit.jupiter.api.AfterEach;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.params.ParameterizedTest;
33 import org.junit.jupiter.params.provider.MethodSource;
34 import org.mockito.Mock;
35 import org.openhab.core.config.core.Configuration;
36 import org.openhab.core.library.types.StringListType;
37 import org.openhab.core.library.types.StringType;
38 import org.openhab.core.thing.ThingUID;
39 import org.openhab.core.thing.profiles.ProfileCallback;
40 import org.openhab.core.thing.profiles.ProfileContext;
41 import org.openhab.core.thing.profiles.StateProfile;
42 import org.openhab.core.types.State;
43 import org.openhab.core.types.UnDefType;
44 import org.openhab.core.util.UIDUtils;
45
46 /**
47  *
48  * @author Christoph Weitkamp - Initial contribution
49  */
50 class PhonebookProfileTest {
51
52     private static final String INTERNAL_PHONE_NUMBER = "999";
53     private static final String OTHER_PHONE_NUMBER = "555-456";
54     private static final String JOHN_DOES_PHONE_NUMBER = "12345";
55     private static final String JOHN_DOES_NAME = "John Doe";
56     private static final ThingUID THING_UID = new ThingUID(BINDING_ID, THING_TYPE_FRITZBOX.getId(), "test");
57     private static final String MY_PHONEBOOK = UIDUtils.encode(THING_UID.getAsString()) + ":MyPhonebook";
58
59     @NonNullByDefault
60     public static class ParameterSet {
61         public final State state;
62         public final State resultingState;
63         public final @Nullable Object matchCount;
64         public final @Nullable Object phoneNumberIndex;
65
66         public ParameterSet(State state, State resultingState, @Nullable Object matchCount,
67                 @Nullable Object phoneNumberIndex) {
68             this.state = state;
69             this.resultingState = resultingState;
70             this.matchCount = matchCount;
71             this.phoneNumberIndex = phoneNumberIndex;
72         }
73     }
74
75     public static Collection<Object[]> parameters() {
76         return Arrays.asList(new Object[][] { //
77                 { new ParameterSet(UnDefType.UNDEF, UnDefType.UNDEF, null, null) }, //
78                 { new ParameterSet(new StringType(JOHN_DOES_PHONE_NUMBER), new StringType(JOHN_DOES_NAME), null,
79                         null) }, //
80                 { new ParameterSet(new StringType(JOHN_DOES_PHONE_NUMBER), new StringType(JOHN_DOES_NAME),
81                         BigDecimal.ONE, null) }, //
82                 { new ParameterSet(new StringType(JOHN_DOES_PHONE_NUMBER), new StringType(JOHN_DOES_NAME), "3", null) }, //
83                 { new ParameterSet(new StringListType(JOHN_DOES_PHONE_NUMBER, INTERNAL_PHONE_NUMBER),
84                         new StringType(JOHN_DOES_NAME), null, null) }, //
85                 { new ParameterSet(new StringListType(JOHN_DOES_PHONE_NUMBER, INTERNAL_PHONE_NUMBER),
86                         new StringType(JOHN_DOES_NAME), null, BigDecimal.ZERO) }, //
87                 { new ParameterSet(new StringListType(INTERNAL_PHONE_NUMBER, JOHN_DOES_PHONE_NUMBER),
88                         new StringType(JOHN_DOES_NAME), null, BigDecimal.ONE) }, //
89                 { new ParameterSet(new StringType(OTHER_PHONE_NUMBER), new StringType(OTHER_PHONE_NUMBER), null,
90                         null) }, //
91                 { new ParameterSet(new StringListType(OTHER_PHONE_NUMBER, INTERNAL_PHONE_NUMBER),
92                         new StringType(OTHER_PHONE_NUMBER), null, null) }, //
93                 { new ParameterSet(new StringListType(OTHER_PHONE_NUMBER, INTERNAL_PHONE_NUMBER),
94                         new StringType(OTHER_PHONE_NUMBER), null, BigDecimal.ZERO) }, //
95                 { new ParameterSet(new StringListType(INTERNAL_PHONE_NUMBER, OTHER_PHONE_NUMBER),
96                         new StringType(OTHER_PHONE_NUMBER), null, BigDecimal.ONE) }, //
97         });
98     }
99
100     private AutoCloseable mocksCloseable;
101
102     private @Mock ProfileCallback mockCallback;
103     private @Mock ProfileContext mockContext;
104     private @Mock PhonebookProvider mockPhonebookProvider;
105
106     @NonNullByDefault
107     private final Phonebook phonebook = new Phonebook() {
108         @Override
109         public Optional<String> lookupNumber(String number, int matchCount) {
110             switch (number) {
111                 case JOHN_DOES_PHONE_NUMBER:
112                     return Optional.of(JOHN_DOES_NAME);
113                 default:
114                     return Optional.empty();
115             }
116         }
117
118         @Override
119         public String getName() {
120             return MY_PHONEBOOK;
121         }
122     };
123
124     @BeforeEach
125     public void setup() {
126         mocksCloseable = openMocks(this);
127
128         when(mockPhonebookProvider.getPhonebookByName(any(String.class))).thenReturn(Optional.of(phonebook));
129         when(mockPhonebookProvider.getPhonebooks()).thenReturn(Set.of(phonebook));
130     }
131
132     @AfterEach
133     public void afterEach() throws Exception {
134         mocksCloseable.close();
135     }
136
137     @ParameterizedTest
138     @MethodSource("parameters")
139     public void testPhonebookProfileResolvesPhoneNumber(ParameterSet parameterSet) {
140         StateProfile profile = initProfile(MY_PHONEBOOK, parameterSet.matchCount, parameterSet.phoneNumberIndex);
141         verifySendUpdate(profile, parameterSet.state, parameterSet.resultingState);
142     }
143
144     private StateProfile initProfile(Object phonebookName, @Nullable Object matchCount,
145             @Nullable Object phoneNumberIndex) {
146         Map<String, Object> properties = new HashMap<>();
147         properties.put(PhonebookProfile.PHONEBOOK_PARAM, phonebookName);
148         if (matchCount != null) {
149             properties.put(PhonebookProfile.MATCH_COUNT_PARAM, matchCount);
150         }
151         if (phoneNumberIndex != null) {
152             properties.put(PhonebookProfile.PHONE_NUMBER_INDEX_PARAM, phoneNumberIndex);
153         }
154         when(mockContext.getConfiguration()).thenReturn(new Configuration(properties));
155         return new PhonebookProfile(mockCallback, mockContext, Map.of(THING_UID, mockPhonebookProvider));
156     }
157
158     private void verifySendUpdate(StateProfile profile, State state, State expectedState) {
159         reset(mockCallback);
160         profile.onStateUpdateFromHandler(state);
161         verify(mockCallback, times(1)).sendUpdate(eq(expectedState));
162     }
163 }