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