• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.contacts.calllog;
18 
19 import static com.google.android.collect.Lists.newArrayList;
20 
21 import android.database.MatrixCursor;
22 import android.provider.CallLog.Calls;
23 import android.test.AndroidTestCase;
24 
25 import java.util.List;
26 
27 /**
28  * Unit tests for {@link CallLogGroupBuilder}
29  */
30 public class CallLogGroupBuilderTest extends AndroidTestCase {
31     /** A phone number for testing. */
32     private static final String TEST_NUMBER1 = "14125551234";
33     /** A phone number for testing. */
34     private static final String TEST_NUMBER2 = "14125555555";
35 
36     /** The object under test. */
37     private CallLogGroupBuilder mBuilder;
38     /** Records the created groups. */
39     private FakeGroupCreator mFakeGroupCreator;
40     /** Cursor to store the values. */
41     private MatrixCursor mCursor;
42 
43     @Override
setUp()44     protected void setUp() throws Exception {
45         super.setUp();
46         mFakeGroupCreator = new FakeGroupCreator();
47         mBuilder = new CallLogGroupBuilder(mFakeGroupCreator);
48         createCursor();
49     }
50 
51     @Override
tearDown()52     protected void tearDown() throws Exception {
53         mCursor = null;
54         mBuilder = null;
55         mFakeGroupCreator = null;
56         super.tearDown();
57     }
58 
testAddGroups_NoCalls()59     public void testAddGroups_NoCalls() {
60         mBuilder.addGroups(mCursor);
61         assertEquals(0, mFakeGroupCreator.groups.size());
62     }
63 
testAddGroups_OneCall()64     public void testAddGroups_OneCall() {
65         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
66         mBuilder.addGroups(mCursor);
67         assertEquals(0, mFakeGroupCreator.groups.size());
68     }
69 
testAddGroups_TwoCallsNotMatching()70     public void testAddGroups_TwoCallsNotMatching() {
71         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
72         addOldCallLogEntry(TEST_NUMBER2, Calls.INCOMING_TYPE);
73         mBuilder.addGroups(mCursor);
74         assertEquals(0, mFakeGroupCreator.groups.size());
75     }
76 
testAddGroups_ThreeCallsMatching()77     public void testAddGroups_ThreeCallsMatching() {
78         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
79         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
80         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
81         mBuilder.addGroups(mCursor);
82         assertEquals(1, mFakeGroupCreator.groups.size());
83         assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
84     }
85 
testAddGroups_MatchingIncomingAndOutgoing()86     public void testAddGroups_MatchingIncomingAndOutgoing() {
87         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
88         addOldCallLogEntry(TEST_NUMBER1, Calls.OUTGOING_TYPE);
89         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
90         mBuilder.addGroups(mCursor);
91         assertEquals(1, mFakeGroupCreator.groups.size());
92         assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
93     }
94 
testAddGroups_HeaderSplitsGroups()95     public void testAddGroups_HeaderSplitsGroups() {
96         addNewCallLogHeader();
97         addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
98         addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
99         addOldCallLogHeader();
100         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
101         addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
102         mBuilder.addGroups(mCursor);
103         assertEquals(2, mFakeGroupCreator.groups.size());
104         assertGroupIs(1, 2, false, mFakeGroupCreator.groups.get(0));
105         assertGroupIs(4, 2, false, mFakeGroupCreator.groups.get(1));
106     }
107 
testAddGroups_Voicemail()108     public void testAddGroups_Voicemail() {
109         // Groups with one or more missed calls.
110         assertCallsAreGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE);
111         assertCallsAreGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
112         // Does not group with other types of calls, include voicemail themselves.
113         assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.VOICEMAIL_TYPE);
114         assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE);
115         assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE);
116     }
117 
testAddGroups_Missed()118     public void testAddGroups_Missed() {
119         // Groups with one or more missed calls.
120         assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
121         assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
122         // Does not group with other types of calls.
123         assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.VOICEMAIL_TYPE);
124         assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
125         assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE);
126     }
127 
testAddGroups_Incoming()128     public void testAddGroups_Incoming() {
129         // Groups with one or more incoming or outgoing.
130         assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE);
131         assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
132         assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
133         assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
134         // Does not group with voicemail and missed calls.
135         assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE);
136         assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
137     }
138 
testAddGroups_Outgoing()139     public void testAddGroups_Outgoing() {
140         // Groups with one or more incoming or outgoing.
141         assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
142         assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE);
143         assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
144         assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
145         // Does not group with voicemail and missed calls.
146         assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE);
147         assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
148     }
149 
testAddGroups_Mixed()150     public void testAddGroups_Mixed() {
151         addMultipleOldCallLogEntries(TEST_NUMBER1,
152                 Calls.VOICEMAIL_TYPE,  // Stand-alone
153                 Calls.INCOMING_TYPE,  // Group 1: 1-2
154                 Calls.OUTGOING_TYPE,
155                 Calls.MISSED_TYPE,  // Group 2: 3-4
156                 Calls.MISSED_TYPE,
157                 Calls.VOICEMAIL_TYPE,  // Stand-alone
158                 Calls.INCOMING_TYPE,  // Stand-alone
159                 Calls.VOICEMAIL_TYPE,  // Group 3: 7-9
160                 Calls.MISSED_TYPE,
161                 Calls.MISSED_TYPE,
162                 Calls.OUTGOING_TYPE);  // Stand-alone
163         mBuilder.addGroups(mCursor);
164         assertEquals(3, mFakeGroupCreator.groups.size());
165         assertGroupIs(1, 2, false, mFakeGroupCreator.groups.get(0));
166         assertGroupIs(3, 2, false, mFakeGroupCreator.groups.get(1));
167         assertGroupIs(7, 3, false, mFakeGroupCreator.groups.get(2));
168     }
169 
testEqualPhoneNumbers()170     public void testEqualPhoneNumbers() {
171         // Identical.
172         assertTrue(mBuilder.equalNumbers("6505555555", "6505555555"));
173         assertTrue(mBuilder.equalNumbers("650 555 5555", "650 555 5555"));
174         // Formatting.
175         assertTrue(mBuilder.equalNumbers("6505555555", "650 555 5555"));
176         assertTrue(mBuilder.equalNumbers("6505555555", "(650) 555-5555"));
177         assertTrue(mBuilder.equalNumbers("650 555 5555", "(650) 555-5555"));
178         // Short codes.
179         assertTrue(mBuilder.equalNumbers("55555", "55555"));
180         assertTrue(mBuilder.equalNumbers("55555", "555 55"));
181         // Different numbers.
182         assertFalse(mBuilder.equalNumbers("6505555555", "650555555"));
183         assertFalse(mBuilder.equalNumbers("6505555555", "6505555551"));
184         assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 555"));
185         assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 5551"));
186         assertFalse(mBuilder.equalNumbers("55555", "5555"));
187         assertFalse(mBuilder.equalNumbers("55555", "55551"));
188         // SIP addresses.
189         assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@host.com"));
190         assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@HOST.COM"));
191         assertTrue(mBuilder.equalNumbers("user@host.com", "user@host.com"));
192         assertTrue(mBuilder.equalNumbers("user@host.com", "user@HOST.COM"));
193         assertFalse(mBuilder.equalNumbers("USER@host.com", "user@host.com"));
194         assertFalse(mBuilder.equalNumbers("user@host.com", "user@host1.com"));
195         // SIP address vs phone number.
196         assertFalse(mBuilder.equalNumbers("6505555555@host.com", "6505555555"));
197         assertFalse(mBuilder.equalNumbers("6505555555", "6505555555@host.com"));
198         assertFalse(mBuilder.equalNumbers("user@host.com", "6505555555"));
199         assertFalse(mBuilder.equalNumbers("6505555555", "user@host.com"));
200         // Nulls.
201         assertTrue(mBuilder.equalNumbers(null, null));
202         assertFalse(mBuilder.equalNumbers(null, "6505555555"));
203         assertFalse(mBuilder.equalNumbers("6505555555", null));
204         assertFalse(mBuilder.equalNumbers(null, "6505555555@host.com"));
205         assertFalse(mBuilder.equalNumbers("6505555555@host.com", null));
206     }
207 
testCompareSipAddresses()208     public void testCompareSipAddresses() {
209         // Identical.
210         assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@host.com"));
211         assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@host.com"));
212         // Host is case insensitive.
213         assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@HOST.COM"));
214         assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@HOST.COM"));
215         // Userinfo is case sensitive.
216         assertFalse(mBuilder.compareSipAddresses("USER@host.com", "user@host.com"));
217         // Different hosts.
218         assertFalse(mBuilder.compareSipAddresses("user@host.com", "user@host1.com"));
219         // Different users.
220         assertFalse(mBuilder.compareSipAddresses("user1@host.com", "user@host.com"));
221         // Nulls.
222         assertTrue(mBuilder.compareSipAddresses(null, null));
223         assertFalse(mBuilder.compareSipAddresses(null, "6505555555@host.com"));
224         assertFalse(mBuilder.compareSipAddresses("6505555555@host.com", null));
225     }
226 
227     /** Creates (or recreates) the cursor used to store the call log content for the tests. */
createCursor()228     private void createCursor() {
229         mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
230     }
231 
232     /** Clears the content of the {@link FakeGroupCreator} used in the tests. */
clearFakeGroupCreator()233     private void clearFakeGroupCreator() {
234         mFakeGroupCreator.groups.clear();
235     }
236 
237     /** Asserts that calls of the given types are grouped together into a single group. */
assertCallsAreGrouped(int... types)238     private void assertCallsAreGrouped(int... types) {
239         createCursor();
240         clearFakeGroupCreator();
241         addMultipleOldCallLogEntries(TEST_NUMBER1, types);
242         mBuilder.addGroups(mCursor);
243         assertEquals(1, mFakeGroupCreator.groups.size());
244         assertGroupIs(0, types.length, false, mFakeGroupCreator.groups.get(0));
245 
246     }
247 
248     /** Asserts that calls of the given types are not grouped together at all. */
assertCallsAreNotGrouped(int... types)249     private void assertCallsAreNotGrouped(int... types) {
250         createCursor();
251         clearFakeGroupCreator();
252         addMultipleOldCallLogEntries(TEST_NUMBER1, types);
253         mBuilder.addGroups(mCursor);
254         assertEquals(0, mFakeGroupCreator.groups.size());
255     }
256 
257     /** Adds a set of calls with the given types, all from the same number, in the old section. */
addMultipleOldCallLogEntries(String number, int... types)258     private void addMultipleOldCallLogEntries(String number, int... types) {
259         for (int type : types) {
260             addOldCallLogEntry(number, type);
261         }
262     }
263 
264     /** Adds a call with the given number and type to the old section of the call log. */
addOldCallLogEntry(String number, int type)265     private void addOldCallLogEntry(String number, int type) {
266         addCallLogEntry(number, type, CallLogQuery.SECTION_OLD_ITEM);
267     }
268 
269     /** Adds a call with the given number and type to the new section of the call log. */
addNewCallLogEntry(String number, int type)270     private void addNewCallLogEntry(String number, int type) {
271         addCallLogEntry(number, type, CallLogQuery.SECTION_NEW_ITEM);
272     }
273 
274     /** Adds a call log entry with the given number and type to the cursor. */
addCallLogEntry(String number, int type, int section)275     private void addCallLogEntry(String number, int type, int section) {
276         if (section != CallLogQuery.SECTION_NEW_ITEM
277                 && section != CallLogQuery.SECTION_OLD_ITEM) {
278             throw new IllegalArgumentException("not an item section: " + section);
279         }
280         mCursor.moveToNext();
281         Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
282         values[CallLogQuery.ID] = mCursor.getPosition();
283         values[CallLogQuery.NUMBER] = number;
284         values[CallLogQuery.CALL_TYPE] = type;
285         values[CallLogQuery.SECTION] = section;
286         mCursor.addRow(values);
287     }
288 
289     /** Adds the old section header to the call log. */
addOldCallLogHeader()290     private void addOldCallLogHeader() {
291         addCallLogHeader(CallLogQuery.SECTION_OLD_HEADER);
292     }
293 
294     /** Adds the new section header to the call log. */
addNewCallLogHeader()295     private void addNewCallLogHeader() {
296         addCallLogHeader(CallLogQuery.SECTION_NEW_HEADER);
297     }
298 
299     /** Adds a call log entry with a header to the cursor. */
addCallLogHeader(int section)300     private void addCallLogHeader(int section) {
301         if (section != CallLogQuery.SECTION_NEW_HEADER
302                 && section != CallLogQuery.SECTION_OLD_HEADER) {
303             throw new IllegalArgumentException("not a header section: " + section);
304         }
305         mCursor.moveToNext();
306         Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
307         values[CallLogQuery.ID] = mCursor.getPosition();
308         values[CallLogQuery.SECTION] = section;
309         mCursor.addRow(values);
310     }
311 
312     /** Asserts that the group matches the given values. */
assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group)313     private void assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group) {
314         assertEquals(cursorPosition, group.cursorPosition);
315         assertEquals(size, group.size);
316         assertEquals(expanded, group.expanded);
317     }
318 
319     /** Defines an added group. Used by the {@link FakeGroupCreator}. */
320     private static class GroupSpec {
321         /** The starting position of the group. */
322         public final int cursorPosition;
323         /** The number of elements in the group. */
324         public final int size;
325         /** Whether the group should be initially expanded. */
326         public final boolean expanded;
327 
GroupSpec(int cursorPosition, int size, boolean expanded)328         public GroupSpec(int cursorPosition, int size, boolean expanded) {
329             this.cursorPosition = cursorPosition;
330             this.size = size;
331             this.expanded = expanded;
332         }
333     }
334 
335     /** Fake implementation of a GroupCreator which stores the created groups in a member field. */
336     private static class FakeGroupCreator implements CallLogGroupBuilder.GroupCreator {
337         /** The list of created groups. */
338         public final List<GroupSpec> groups = newArrayList();
339 
340         @Override
addGroup(int cursorPosition, int size, boolean expanded)341         public void addGroup(int cursorPosition, int size, boolean expanded) {
342             groups.add(new GroupSpec(cursorPosition, size, expanded));
343         }
344     }
345 }
346