| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.dialer.calllog; |
| |
| import static com.google.common.collect.Lists.newArrayList; |
| |
| import android.database.MatrixCursor; |
| import android.provider.CallLog.Calls; |
| import android.test.AndroidTestCase; |
| import android.test.suitebuilder.annotation.SmallTest; |
| |
| import java.util.List; |
| |
| /** |
| * Unit tests for {@link CallLogGroupBuilder} |
| */ |
| @SmallTest |
| public class CallLogGroupBuilderTest extends AndroidTestCase { |
| /** A phone number for testing. */ |
| private static final String TEST_NUMBER1 = "14125551234"; |
| /** A phone number for testing. */ |
| private static final String TEST_NUMBER2 = "14125555555"; |
| |
| /** The object under test. */ |
| private CallLogGroupBuilder mBuilder; |
| /** Records the created groups. */ |
| private FakeGroupCreator mFakeGroupCreator; |
| /** Cursor to store the values. */ |
| private MatrixCursor mCursor; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| mFakeGroupCreator = new FakeGroupCreator(); |
| mBuilder = new CallLogGroupBuilder(mFakeGroupCreator); |
| createCursor(); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| mCursor = null; |
| mBuilder = null; |
| mFakeGroupCreator = null; |
| super.tearDown(); |
| } |
| |
| public void testAddGroups_NoCalls() { |
| mBuilder.addGroups(mCursor); |
| assertEquals(0, mFakeGroupCreator.groups.size()); |
| } |
| |
| public void testAddGroups_OneCall() { |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| mBuilder.addGroups(mCursor); |
| assertEquals(0, mFakeGroupCreator.groups.size()); |
| } |
| |
| public void testAddGroups_TwoCallsNotMatching() { |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addOldCallLogEntry(TEST_NUMBER2, Calls.INCOMING_TYPE); |
| mBuilder.addGroups(mCursor); |
| assertEquals(0, mFakeGroupCreator.groups.size()); |
| } |
| |
| public void testAddGroups_ThreeCallsMatching() { |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| mBuilder.addGroups(mCursor); |
| assertEquals(1, mFakeGroupCreator.groups.size()); |
| assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0)); |
| } |
| |
| public void testAddGroups_MatchingIncomingAndOutgoing() { |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addOldCallLogEntry(TEST_NUMBER1, Calls.OUTGOING_TYPE); |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| mBuilder.addGroups(mCursor); |
| assertEquals(1, mFakeGroupCreator.groups.size()); |
| assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0)); |
| } |
| |
| public void testAddGroups_HeaderSplitsGroups() { |
| addNewCallLogHeader(); |
| addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addOldCallLogHeader(); |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE); |
| mBuilder.addGroups(mCursor); |
| assertEquals(2, mFakeGroupCreator.groups.size()); |
| assertGroupIs(1, 2, false, mFakeGroupCreator.groups.get(0)); |
| assertGroupIs(4, 2, false, mFakeGroupCreator.groups.get(1)); |
| } |
| |
| public void testAddGroups_Voicemail() { |
| // Does not group with other types of calls, include voicemail themselves. |
| assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE); |
| //assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE); |
| assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.VOICEMAIL_TYPE); |
| assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE); |
| assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE); |
| } |
| |
| public void testAddGroups_Missed() { |
| // Groups with one or more missed calls. |
| assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE); |
| assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE); |
| // Does not group with other types of calls. |
| assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.VOICEMAIL_TYPE); |
| assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE); |
| assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE); |
| } |
| |
| public void testAddGroups_Incoming() { |
| // Groups with one or more incoming or outgoing. |
| assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE); |
| assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE); |
| assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE); |
| assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE); |
| assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE); |
| // Does not group with voicemail and missed calls. |
| assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE); |
| } |
| |
| public void testAddGroups_Outgoing() { |
| // Groups with one or more incoming or outgoing. |
| assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE); |
| assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE); |
| assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE); |
| assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE); |
| assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE); |
| // Does not group with voicemail and missed calls. |
| assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE); |
| } |
| |
| public void testAddGroups_Mixed() { |
| addMultipleOldCallLogEntries(TEST_NUMBER1, |
| Calls.VOICEMAIL_TYPE, // Stand-alone |
| Calls.INCOMING_TYPE, // Group 1: 1-4 |
| Calls.OUTGOING_TYPE, |
| Calls.MISSED_TYPE, |
| Calls.MISSED_TYPE, |
| Calls.VOICEMAIL_TYPE, // Stand-alone |
| Calls.INCOMING_TYPE, // Stand-alone |
| Calls.VOICEMAIL_TYPE, // Stand-alone |
| Calls.MISSED_TYPE, // Group 2: 8-10 |
| Calls.MISSED_TYPE, |
| Calls.OUTGOING_TYPE); |
| mBuilder.addGroups(mCursor); |
| assertEquals(2, mFakeGroupCreator.groups.size()); |
| assertGroupIs(1, 4, false, mFakeGroupCreator.groups.get(0)); |
| assertGroupIs(8, 3, false, mFakeGroupCreator.groups.get(1)); |
| } |
| |
| public void testEqualPhoneNumbers() { |
| // Identical. |
| assertTrue(mBuilder.equalNumbers("6505555555", "6505555555")); |
| assertTrue(mBuilder.equalNumbers("650 555 5555", "650 555 5555")); |
| // Formatting. |
| assertTrue(mBuilder.equalNumbers("6505555555", "650 555 5555")); |
| assertTrue(mBuilder.equalNumbers("6505555555", "(650) 555-5555")); |
| assertTrue(mBuilder.equalNumbers("650 555 5555", "(650) 555-5555")); |
| // Short codes. |
| assertTrue(mBuilder.equalNumbers("55555", "55555")); |
| assertTrue(mBuilder.equalNumbers("55555", "555 55")); |
| // Different numbers. |
| assertFalse(mBuilder.equalNumbers("6505555555", "650555555")); |
| assertFalse(mBuilder.equalNumbers("6505555555", "6505555551")); |
| assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 555")); |
| assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 5551")); |
| assertFalse(mBuilder.equalNumbers("55555", "5555")); |
| assertFalse(mBuilder.equalNumbers("55555", "55551")); |
| // SIP addresses. |
| assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@host.com")); |
| assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@HOST.COM")); |
| assertTrue(mBuilder.equalNumbers("user@host.com", "user@host.com")); |
| assertTrue(mBuilder.equalNumbers("user@host.com", "user@HOST.COM")); |
| assertFalse(mBuilder.equalNumbers("USER@host.com", "user@host.com")); |
| assertFalse(mBuilder.equalNumbers("user@host.com", "user@host1.com")); |
| // SIP address vs phone number. |
| assertFalse(mBuilder.equalNumbers("6505555555@host.com", "6505555555")); |
| assertFalse(mBuilder.equalNumbers("6505555555", "6505555555@host.com")); |
| assertFalse(mBuilder.equalNumbers("user@host.com", "6505555555")); |
| assertFalse(mBuilder.equalNumbers("6505555555", "user@host.com")); |
| // Nulls. |
| assertTrue(mBuilder.equalNumbers(null, null)); |
| assertFalse(mBuilder.equalNumbers(null, "6505555555")); |
| assertFalse(mBuilder.equalNumbers("6505555555", null)); |
| assertFalse(mBuilder.equalNumbers(null, "6505555555@host.com")); |
| assertFalse(mBuilder.equalNumbers("6505555555@host.com", null)); |
| } |
| |
| public void testCompareSipAddresses() { |
| // Identical. |
| assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@host.com")); |
| assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@host.com")); |
| // Host is case insensitive. |
| assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@HOST.COM")); |
| assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@HOST.COM")); |
| // Userinfo is case sensitive. |
| assertFalse(mBuilder.compareSipAddresses("USER@host.com", "user@host.com")); |
| // Different hosts. |
| assertFalse(mBuilder.compareSipAddresses("user@host.com", "user@host1.com")); |
| // Different users. |
| assertFalse(mBuilder.compareSipAddresses("user1@host.com", "user@host.com")); |
| // Nulls. |
| assertTrue(mBuilder.compareSipAddresses(null, null)); |
| assertFalse(mBuilder.compareSipAddresses(null, "6505555555@host.com")); |
| assertFalse(mBuilder.compareSipAddresses("6505555555@host.com", null)); |
| } |
| |
| /** Creates (or recreates) the cursor used to store the call log content for the tests. */ |
| private void createCursor() { |
| mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION); |
| } |
| |
| /** Clears the content of the {@link FakeGroupCreator} used in the tests. */ |
| private void clearFakeGroupCreator() { |
| mFakeGroupCreator.groups.clear(); |
| } |
| |
| /** Asserts that calls of the given types are grouped together into a single group. */ |
| private void assertCallsAreGrouped(int... types) { |
| createCursor(); |
| clearFakeGroupCreator(); |
| addMultipleOldCallLogEntries(TEST_NUMBER1, types); |
| mBuilder.addGroups(mCursor); |
| assertEquals(1, mFakeGroupCreator.groups.size()); |
| assertGroupIs(0, types.length, false, mFakeGroupCreator.groups.get(0)); |
| |
| } |
| |
| /** Asserts that calls of the given types are not grouped together at all. */ |
| private void assertCallsAreNotGrouped(int... types) { |
| createCursor(); |
| clearFakeGroupCreator(); |
| addMultipleOldCallLogEntries(TEST_NUMBER1, types); |
| mBuilder.addGroups(mCursor); |
| assertEquals(0, mFakeGroupCreator.groups.size()); |
| } |
| |
| /** Adds a set of calls with the given types, all from the same number, in the old section. */ |
| private void addMultipleOldCallLogEntries(String number, int... types) { |
| for (int type : types) { |
| addOldCallLogEntry(number, type); |
| } |
| } |
| |
| /** Adds a call with the given number and type to the old section of the call log. */ |
| private void addOldCallLogEntry(String number, int type) { |
| addCallLogEntry(number, type, CallLogQuery.SECTION_OLD_ITEM); |
| } |
| |
| /** Adds a call with the given number and type to the new section of the call log. */ |
| private void addNewCallLogEntry(String number, int type) { |
| addCallLogEntry(number, type, CallLogQuery.SECTION_NEW_ITEM); |
| } |
| |
| /** Adds a call log entry with the given number and type to the cursor. */ |
| private void addCallLogEntry(String number, int type, int section) { |
| if (section != CallLogQuery.SECTION_NEW_ITEM |
| && section != CallLogQuery.SECTION_OLD_ITEM) { |
| throw new IllegalArgumentException("not an item section: " + section); |
| } |
| mCursor.moveToNext(); |
| Object[] values = CallLogQueryTestUtils.createTestExtendedValues(); |
| values[CallLogQuery.ID] = mCursor.getPosition(); |
| values[CallLogQuery.NUMBER] = number; |
| values[CallLogQuery.CALL_TYPE] = type; |
| values[CallLogQuery.SECTION] = section; |
| mCursor.addRow(values); |
| } |
| |
| /** Adds the old section header to the call log. */ |
| private void addOldCallLogHeader() { |
| addCallLogHeader(CallLogQuery.SECTION_OLD_HEADER); |
| } |
| |
| /** Adds the new section header to the call log. */ |
| private void addNewCallLogHeader() { |
| addCallLogHeader(CallLogQuery.SECTION_NEW_HEADER); |
| } |
| |
| /** Adds a call log entry with a header to the cursor. */ |
| private void addCallLogHeader(int section) { |
| if (section != CallLogQuery.SECTION_NEW_HEADER |
| && section != CallLogQuery.SECTION_OLD_HEADER) { |
| throw new IllegalArgumentException("not a header section: " + section); |
| } |
| mCursor.moveToNext(); |
| Object[] values = CallLogQueryTestUtils.createTestExtendedValues(); |
| values[CallLogQuery.ID] = mCursor.getPosition(); |
| values[CallLogQuery.SECTION] = section; |
| mCursor.addRow(values); |
| } |
| |
| /** Asserts that the group matches the given values. */ |
| private void assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group) { |
| assertEquals(cursorPosition, group.cursorPosition); |
| assertEquals(size, group.size); |
| assertEquals(expanded, group.expanded); |
| } |
| |
| /** Defines an added group. Used by the {@link FakeGroupCreator}. */ |
| private static class GroupSpec { |
| /** The starting position of the group. */ |
| public final int cursorPosition; |
| /** The number of elements in the group. */ |
| public final int size; |
| /** Whether the group should be initially expanded. */ |
| public final boolean expanded; |
| |
| public GroupSpec(int cursorPosition, int size, boolean expanded) { |
| this.cursorPosition = cursorPosition; |
| this.size = size; |
| this.expanded = expanded; |
| } |
| } |
| |
| /** Fake implementation of a GroupCreator which stores the created groups in a member field. */ |
| private static class FakeGroupCreator implements CallLogGroupBuilder.GroupCreator { |
| /** The list of created groups. */ |
| public final List<GroupSpec> groups = newArrayList(); |
| |
| @Override |
| public void addGroup(int cursorPosition, int size, boolean expanded) { |
| groups.add(new GroupSpec(cursorPosition, size, expanded)); |
| } |
| } |
| } |