]> git.basschouten.com Git - openhab-addons.git/blob
e6827db2b569db4ac78724ea6c9d7ee7437ac97b
[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
57     private static final String INTERNAL_PHONE_NUMBER = "999";
58     private static final String OTHER_PHONE_NUMBER = "555-456";
59     private static final String JOHN_DOES_PHONE_NUMBER = "12345";
60     private static final String JOHN_DOES_NAME = "John Doe";
61     private static final ThingUID THING_UID = new ThingUID(BINDING_ID, THING_TYPE_FRITZBOX.getId(), "test");
62     private static final String MY_PHONEBOOK = UIDUtils.encode(THING_UID.getAsString()) + ":MyPhonebook";
63
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             switch (number) {
112                 case JOHN_DOES_PHONE_NUMBER:
113                     return Optional.of(JOHN_DOES_NAME);
114                 default:
115                     return Optional.empty();
116             }
117         }
118
119         @Override
120         public String getName() {
121             return MY_PHONEBOOK;
122         }
123     };
124
125     @BeforeEach
126     public void setup() {
127         when(mockPhonebookProvider.getPhonebookByName(any(String.class))).thenReturn(Optional.of(phonebook));
128         when(mockPhonebookProvider.getPhonebooks()).thenReturn(Set.of(phonebook));
129     }
130
131     @ParameterizedTest
132     @MethodSource("parameters")
133     public void testPhonebookProfileResolvesPhoneNumber(ParameterSet parameterSet) {
134         StateProfile profile = initProfile(MY_PHONEBOOK, parameterSet.matchCount, parameterSet.phoneNumberIndex);
135         verifySendUpdate(profile, parameterSet.state, parameterSet.resultingState);
136     }
137
138     private StateProfile initProfile(Object phonebookName, @Nullable Object matchCount,
139             @Nullable Object phoneNumberIndex) {
140         Map<String, Object> properties = new HashMap<>();
141         properties.put(PhonebookProfile.PHONEBOOK_PARAM, phonebookName);
142         if (matchCount != null) {
143             properties.put(PhonebookProfile.MATCH_COUNT_PARAM, matchCount);
144         }
145         if (phoneNumberIndex != null) {
146             properties.put(PhonebookProfile.PHONE_NUMBER_INDEX_PARAM, phoneNumberIndex);
147         }
148         when(mockContext.getConfiguration()).thenReturn(new Configuration(properties));
149         return new PhonebookProfile(mockCallback, mockContext, Map.of(THING_UID, mockPhonebookProvider));
150     }
151
152     private void verifySendUpdate(StateProfile profile, State state, State expectedState) {
153         reset(mockCallback);
154         profile.onStateUpdateFromHandler(state);
155         verify(mockCallback, times(1)).sendUpdate(eq(expectedState));
156     }
157 }