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.dialer.calllog; 18 19 import static com.google.common.collect.Lists.newArrayList; 20 21 import android.database.MatrixCursor; 22 import android.provider.CallLog.Calls; 23 import android.test.AndroidTestCase; 24 import android.test.suitebuilder.annotation.SmallTest; 25 26 import java.util.List; 27 28 /** 29 * Unit tests for {@link CallLogGroupBuilder} 30 */ 31 @SmallTest 32 public class CallLogGroupBuilderTest extends AndroidTestCase { 33 /** A phone number for testing. */ 34 private static final String TEST_NUMBER1 = "14125551234"; 35 /** A phone number for testing. */ 36 private static final String TEST_NUMBER2 = "14125555555"; 37 38 /** The object under test. */ 39 private CallLogGroupBuilder mBuilder; 40 /** Records the created groups. */ 41 private FakeGroupCreator mFakeGroupCreator; 42 /** Cursor to store the values. */ 43 private MatrixCursor mCursor; 44 45 @Override setUp()46 protected void setUp() throws Exception { 47 super.setUp(); 48 mFakeGroupCreator = new FakeGroupCreator(); 49 mBuilder = new CallLogGroupBuilder(mFakeGroupCreator); 50 createCursor(); 51 } 52 53 @Override tearDown()54 protected void tearDown() throws Exception { 55 mCursor = null; 56 mBuilder = null; 57 mFakeGroupCreator = null; 58 super.tearDown(); 59 } 60 testAddGroups_NoCalls()61 public void testAddGroups_NoCalls() { 62 mBuilder.addGroups(mCursor); 63 assertEquals(0, mFakeGroupCreator.groups.size()); 64 } 65 testAddGroups_OneCall()66 public void testAddGroups_OneCall() { 67 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 68 mBuilder.addGroups(mCursor); 69 assertEquals(0, mFakeGroupCreator.groups.size()); 70 } 71 testAddGroups_TwoCallsNotMatching()72 public void testAddGroups_TwoCallsNotMatching() { 73 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 74 addCallLogEntry(TEST_NUMBER2, Calls.INCOMING_TYPE); 75 mBuilder.addGroups(mCursor); 76 assertEquals(0, mFakeGroupCreator.groups.size()); 77 } 78 testAddGroups_ThreeCallsMatching()79 public void testAddGroups_ThreeCallsMatching() { 80 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 81 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 82 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 83 mBuilder.addGroups(mCursor); 84 assertEquals(1, mFakeGroupCreator.groups.size()); 85 assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0)); 86 } 87 testAddGroups_MatchingIncomingAndOutgoing()88 public void testAddGroups_MatchingIncomingAndOutgoing() { 89 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 90 addCallLogEntry(TEST_NUMBER1, Calls.OUTGOING_TYPE); 91 addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); 92 mBuilder.addGroups(mCursor); 93 assertEquals(1, mFakeGroupCreator.groups.size()); 94 assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0)); 95 } 96 testAddGroups_Voicemail()97 public void testAddGroups_Voicemail() { 98 // Does not group with other types of calls, include voicemail themselves. 99 assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE); 100 //assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE); 101 assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.VOICEMAIL_TYPE); 102 assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE); 103 assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE); 104 } 105 testAddGroups_Missed()106 public void testAddGroups_Missed() { 107 // Groups with one or more missed calls. 108 assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE); 109 assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE); 110 // Does not group with other types of calls. 111 assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.VOICEMAIL_TYPE); 112 assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE); 113 assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE); 114 } 115 testAddGroups_Incoming()116 public void testAddGroups_Incoming() { 117 // Groups with one or more incoming or outgoing. 118 assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE); 119 assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE); 120 assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE); 121 assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE); 122 assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE); 123 // Does not group with voicemail and missed calls. 124 assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE); 125 } 126 testAddGroups_Outgoing()127 public void testAddGroups_Outgoing() { 128 // Groups with one or more incoming or outgoing. 129 assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE); 130 assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE); 131 assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE); 132 assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE); 133 assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE); 134 // Does not group with voicemail and missed calls. 135 assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE); 136 } 137 testAddGroups_Mixed()138 public void testAddGroups_Mixed() { 139 addMultipleCallLogEntries(TEST_NUMBER1, 140 Calls.VOICEMAIL_TYPE, // Stand-alone 141 Calls.INCOMING_TYPE, // Group 1: 1-4 142 Calls.OUTGOING_TYPE, 143 Calls.MISSED_TYPE, 144 Calls.MISSED_TYPE, 145 Calls.VOICEMAIL_TYPE, // Stand-alone 146 Calls.INCOMING_TYPE, // Stand-alone 147 Calls.VOICEMAIL_TYPE, // Stand-alone 148 Calls.MISSED_TYPE, // Group 2: 8-10 149 Calls.MISSED_TYPE, 150 Calls.OUTGOING_TYPE); 151 mBuilder.addGroups(mCursor); 152 assertEquals(2, mFakeGroupCreator.groups.size()); 153 assertGroupIs(1, 4, false, mFakeGroupCreator.groups.get(0)); 154 assertGroupIs(8, 3, false, mFakeGroupCreator.groups.get(1)); 155 } 156 testEqualPhoneNumbers()157 public void testEqualPhoneNumbers() { 158 // Identical. 159 assertTrue(mBuilder.equalNumbers("6505555555", "6505555555")); 160 assertTrue(mBuilder.equalNumbers("650 555 5555", "650 555 5555")); 161 // Formatting. 162 assertTrue(mBuilder.equalNumbers("6505555555", "650 555 5555")); 163 assertTrue(mBuilder.equalNumbers("6505555555", "(650) 555-5555")); 164 assertTrue(mBuilder.equalNumbers("650 555 5555", "(650) 555-5555")); 165 // Short codes. 166 assertTrue(mBuilder.equalNumbers("55555", "55555")); 167 assertTrue(mBuilder.equalNumbers("55555", "555 55")); 168 // Different numbers. 169 assertFalse(mBuilder.equalNumbers("6505555555", "650555555")); 170 assertFalse(mBuilder.equalNumbers("6505555555", "6505555551")); 171 assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 555")); 172 assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 5551")); 173 assertFalse(mBuilder.equalNumbers("55555", "5555")); 174 assertFalse(mBuilder.equalNumbers("55555", "55551")); 175 // SIP addresses. 176 assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@host.com")); 177 assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@HOST.COM")); 178 assertTrue(mBuilder.equalNumbers("user@host.com", "user@host.com")); 179 assertTrue(mBuilder.equalNumbers("user@host.com", "user@HOST.COM")); 180 assertFalse(mBuilder.equalNumbers("USER@host.com", "user@host.com")); 181 assertFalse(mBuilder.equalNumbers("user@host.com", "user@host1.com")); 182 // SIP address vs phone number. 183 assertFalse(mBuilder.equalNumbers("6505555555@host.com", "6505555555")); 184 assertFalse(mBuilder.equalNumbers("6505555555", "6505555555@host.com")); 185 assertFalse(mBuilder.equalNumbers("user@host.com", "6505555555")); 186 assertFalse(mBuilder.equalNumbers("6505555555", "user@host.com")); 187 // Nulls. 188 assertTrue(mBuilder.equalNumbers(null, null)); 189 assertFalse(mBuilder.equalNumbers(null, "6505555555")); 190 assertFalse(mBuilder.equalNumbers("6505555555", null)); 191 assertFalse(mBuilder.equalNumbers(null, "6505555555@host.com")); 192 assertFalse(mBuilder.equalNumbers("6505555555@host.com", null)); 193 } 194 testCompareSipAddresses()195 public void testCompareSipAddresses() { 196 // Identical. 197 assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@host.com")); 198 assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@host.com")); 199 // Host is case insensitive. 200 assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@HOST.COM")); 201 assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@HOST.COM")); 202 // Userinfo is case sensitive. 203 assertFalse(mBuilder.compareSipAddresses("USER@host.com", "user@host.com")); 204 // Different hosts. 205 assertFalse(mBuilder.compareSipAddresses("user@host.com", "user@host1.com")); 206 // Different users. 207 assertFalse(mBuilder.compareSipAddresses("user1@host.com", "user@host.com")); 208 // Nulls. 209 assertTrue(mBuilder.compareSipAddresses(null, null)); 210 assertFalse(mBuilder.compareSipAddresses(null, "6505555555@host.com")); 211 assertFalse(mBuilder.compareSipAddresses("6505555555@host.com", null)); 212 } 213 214 /** Creates (or recreates) the cursor used to store the call log content for the tests. */ createCursor()215 private void createCursor() { 216 mCursor = new MatrixCursor(CallLogQuery._PROJECTION); 217 } 218 219 /** Clears the content of the {@link FakeGroupCreator} used in the tests. */ clearFakeGroupCreator()220 private void clearFakeGroupCreator() { 221 mFakeGroupCreator.groups.clear(); 222 } 223 224 /** Asserts that calls of the given types are grouped together into a single group. */ assertCallsAreGrouped(int... types)225 private void assertCallsAreGrouped(int... types) { 226 createCursor(); 227 clearFakeGroupCreator(); 228 addMultipleCallLogEntries(TEST_NUMBER1, types); 229 mBuilder.addGroups(mCursor); 230 assertEquals(1, mFakeGroupCreator.groups.size()); 231 assertGroupIs(0, types.length, false, mFakeGroupCreator.groups.get(0)); 232 233 } 234 235 /** Asserts that calls of the given types are not grouped together at all. */ assertCallsAreNotGrouped(int... types)236 private void assertCallsAreNotGrouped(int... types) { 237 createCursor(); 238 clearFakeGroupCreator(); 239 addMultipleCallLogEntries(TEST_NUMBER1, types); 240 mBuilder.addGroups(mCursor); 241 assertEquals(0, mFakeGroupCreator.groups.size()); 242 } 243 244 /** Adds a set of calls with the given types, all from the same number, in the old section. */ addMultipleCallLogEntries(String number, int... types)245 private void addMultipleCallLogEntries(String number, int... types) { 246 for (int type : types) { 247 addCallLogEntry(number, type); 248 } 249 } 250 /** Adds a call log entry with the given number and type to the cursor. */ addCallLogEntry(String number, int type)251 private void addCallLogEntry(String number, int type) { 252 mCursor.moveToNext(); 253 Object[] values = CallLogQueryTestUtils.createTestValues(); 254 values[CallLogQuery.ID] = mCursor.getPosition(); 255 values[CallLogQuery.NUMBER] = number; 256 values[CallLogQuery.CALL_TYPE] = type; 257 mCursor.addRow(values); 258 } 259 260 /** Adds a call log entry with a header to the cursor. */ addCallLogHeader(int section)261 private void addCallLogHeader(int section) { 262 mCursor.moveToNext(); 263 Object[] values = CallLogQueryTestUtils.createTestValues(); 264 values[CallLogQuery.ID] = mCursor.getPosition(); 265 mCursor.addRow(values); 266 } 267 268 /** Asserts that the group matches the given values. */ assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group)269 private void assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group) { 270 assertEquals(cursorPosition, group.cursorPosition); 271 assertEquals(size, group.size); 272 assertEquals(expanded, group.expanded); 273 } 274 275 /** Defines an added group. Used by the {@link FakeGroupCreator}. */ 276 private static class GroupSpec { 277 /** The starting position of the group. */ 278 public final int cursorPosition; 279 /** The number of elements in the group. */ 280 public final int size; 281 /** Whether the group should be initially expanded. */ 282 public final boolean expanded; 283 GroupSpec(int cursorPosition, int size, boolean expanded)284 public GroupSpec(int cursorPosition, int size, boolean expanded) { 285 this.cursorPosition = cursorPosition; 286 this.size = size; 287 this.expanded = expanded; 288 } 289 } 290 291 /** Fake implementation of a GroupCreator which stores the created groups in a member field. */ 292 private static class FakeGroupCreator implements CallLogGroupBuilder.GroupCreator { 293 /** The list of created groups. */ 294 public final List<GroupSpec> groups = newArrayList(); 295 296 @Override addGroup(int cursorPosition, int size, boolean expanded)297 public void addGroup(int cursorPosition, int size, boolean expanded) { 298 groups.add(new GroupSpec(cursorPosition, size, expanded)); 299 } 300 301 @Override setDayGroup(long rowId, int dayGroup)302 public void setDayGroup(long rowId, int dayGroup) { 303 //No-op 304 } 305 306 @Override clearDayGroups()307 public void clearDayGroups() { 308 //No-op 309 } 310 } 311 } 312