Home | History | Annotate | Download | only in contacts
      1 /*
      2  * Copyright (C) 2009 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.providers.contacts;
     18 
     19 import android.content.ContentUris;
     20 import android.net.Uri;
     21 import android.provider.ContactsContract.AggregationExceptions;
     22 import android.provider.ContactsContract.Contacts;
     23 import android.provider.ContactsContract.RawContacts;
     24 import android.test.suitebuilder.annotation.MediumTest;
     25 
     26 import com.android.providers.contacts.ContactLookupKey.LookupKeySegment;
     27 import com.android.providers.contacts.testutil.RawContactUtil;
     28 
     29 import java.util.ArrayList;
     30 
     31 /**
     32  * Unit tests for {@link ContactLookupKey}.
     33  *
     34  * Run the test like this:
     35  * <code>
     36  * adb shell am instrument -e class com.android.providers.contacts.ContactLookupKeyTest -w \
     37  *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
     38  * </code>
     39  */
     40 @MediumTest
     41 public class ContactLookupKeyTest extends BaseContactsProvider2Test {
     42 
     43     public void testLookupKeyUsingDisplayNameAndNoAccount() {
     44         long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
     45         long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "johndoe", null);
     46         setAggregationException(
     47                 AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
     48 
     49         // Normalized display name
     50         String normalizedName = NameNormalizer.normalize("johndoe");
     51         String expectedLookupKey = "0r" + rawContactId1 + "-" + normalizedName + ".0r"
     52                 + rawContactId2 + "-" + normalizedName;
     53 
     54         long contactId = queryContactId(rawContactId1);
     55         assertStoredValue(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
     56                 Contacts.LOOKUP_KEY, expectedLookupKey);
     57 
     58         // Find the contact using lookup key by itself
     59         Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, expectedLookupKey);
     60         assertStoredValue(lookupUri, Contacts._ID, contactId);
     61 
     62         // Find the contact using both the lookup key and the correct contact ID
     63         assertStoredValue(ContentUris.withAppendedId(lookupUri, contactId),
     64                 Contacts._ID, contactId);
     65 
     66         // Find the contact using both the lookup key and an incorrect contact ID
     67         assertStoredValue(ContentUris.withAppendedId(lookupUri, contactId + 1),
     68                 Contacts._ID, contactId);
     69     }
     70 
     71     public void testLookupKeyUsingSourceIdAndNoAccount() {
     72         long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
     73         storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.SOURCE_ID, "123");
     74 
     75         long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "johndoe", null);
     76         storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.SOURCE_ID, "4.5.6");
     77 
     78         long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "john", "dough");
     79         storeValue(RawContacts.CONTENT_URI, rawContactId3, RawContacts.SOURCE_ID, "http://foo?bar");
     80 
     81         setAggregationException(
     82                 AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
     83         setAggregationException(
     84                 AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId3);
     85 
     86         // Two source ids, of them escaped
     87         String expectedLookupKey = "0i123.0e4..5..6.0ihttp%3A%2F%2Ffoo%3Fbar";
     88 
     89         long contactId = queryContactId(rawContactId1);
     90         assertStoredValue(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
     91                 Contacts.LOOKUP_KEY, expectedLookupKey);
     92 
     93         Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, expectedLookupKey);
     94         assertStoredValue(lookupUri, Contacts._ID, contactId);
     95     }
     96 
     97     public void testLookupKeySameSourceIdDifferentAccounts() {
     98         long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Dear", "Doe");
     99         storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.ACCOUNT_TYPE, "foo");
    100         storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.ACCOUNT_NAME, "FOO");
    101         storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.SOURCE_ID, "1");
    102 
    103         long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Deer", "Dough");
    104         storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.ACCOUNT_TYPE, "bar");
    105         storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.ACCOUNT_NAME, "BAR");
    106         storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.SOURCE_ID, "1");
    107 
    108         assertNotAggregated(rawContactId1, rawContactId2);
    109 
    110         int accountHashCode1 = ContactLookupKey.getAccountHashCode("foo", "FOO");
    111         int accountHashCode2 = ContactLookupKey.getAccountHashCode("bar", "BAR");
    112 
    113         long contactId1 = queryContactId(rawContactId1);
    114         assertStoredValue(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
    115                 Contacts.LOOKUP_KEY, accountHashCode1 + "i1");
    116 
    117         long contactId2 = queryContactId(rawContactId2);
    118         assertStoredValue(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
    119                 Contacts.LOOKUP_KEY, accountHashCode2 + "i1");
    120 
    121         Uri lookupUri1 = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, accountHashCode1 + "i1");
    122         assertStoredValue(lookupUri1, Contacts._ID, contactId1);
    123 
    124         Uri lookupUri2 = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, accountHashCode2 + "i1");
    125         assertStoredValue(lookupUri2, Contacts._ID, contactId2);
    126     }
    127 
    128     public void testLookupKeyChoosingLargestContact() {
    129         long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
    130         storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.SOURCE_ID, "1");
    131 
    132         long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
    133         storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.SOURCE_ID, "2");
    134 
    135         long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
    136         storeValue(RawContacts.CONTENT_URI, rawContactId3, RawContacts.SOURCE_ID, "3");
    137         setAggregationException(
    138                 AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
    139         setAggregationException(
    140                 AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId3);
    141 
    142         String lookupKey = "0i1.0i2.0i3";
    143 
    144         long contactId = queryContactId(rawContactId1);
    145         assertStoredValue(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
    146                 Contacts.LOOKUP_KEY, lookupKey);
    147 
    148         setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE, rawContactId1,
    149                 rawContactId3);
    150         setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE, rawContactId2,
    151                 rawContactId3);
    152         assertAggregated(rawContactId1, rawContactId2);
    153         assertNotAggregated(rawContactId1, rawContactId3);
    154         assertNotAggregated(rawContactId2, rawContactId3);
    155 
    156         long largerContactId = queryContactId(rawContactId1);
    157         assertStoredValue(
    158                 ContentUris.withAppendedId(Contacts.CONTENT_URI, largerContactId),
    159                 Contacts.LOOKUP_KEY, "0i1.0i2");
    160         assertStoredValue(
    161                 ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId3)),
    162                 Contacts.LOOKUP_KEY, "0i3");
    163 
    164         Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
    165         assertStoredValue(lookupUri, Contacts._ID, largerContactId);
    166     }
    167 
    168     public void testGetLookupUri() {
    169         long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
    170         storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.SOURCE_ID, "1");
    171 
    172         long contactId = queryContactId(rawContactId1);
    173         String lookupUri = "content://com.android.contacts/contacts/lookup/0i1/" + contactId;
    174 
    175         Uri contentUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
    176         assertEquals(lookupUri,
    177                 Contacts.getLookupUri(mResolver, contentUri).toString());
    178 
    179         Uri staleLookupUri = ContentUris.withAppendedId(
    180                 Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, "0i1"),
    181                 contactId+2);
    182         assertEquals(lookupUri,
    183                 Contacts.getLookupUri(mResolver, staleLookupUri).toString());
    184     }
    185 
    186     public void testParseLookupKey() {
    187         // Display name
    188         assertLookupKey("123n1248AC",
    189                 new int[]{123},
    190                 new int[]{ContactLookupKey.LOOKUP_TYPE_DISPLAY_NAME},
    191                 new String[]{"1248AC"});
    192 
    193         // Raw contact ID + display name
    194         assertLookupKey("123r20-1248AC",
    195                 new int[]{123},
    196                 new int[]{ContactLookupKey.LOOKUP_TYPE_RAW_CONTACT_ID},
    197                 new String[]{"1248AC"});
    198 
    199         // Unescaped source ID
    200         assertLookupKey("0i1248AC-X",
    201                 new int[]{0},
    202                 new int[]{ContactLookupKey.LOOKUP_TYPE_SOURCE_ID},
    203                 new String[]{"1248AC-X"});
    204 
    205         // Escaped source ID
    206         assertLookupKey("432e12..48AC",
    207                 new int[]{432},
    208                 new int[]{ContactLookupKey.LOOKUP_TYPE_SOURCE_ID},
    209                 new String[]{"12.48AC"});
    210 
    211         // Compound lookup key
    212         assertLookupKey("123n1248AC.0i1248AC.432e12..48AC.123n1248AC.123r30-2184CA",
    213                 new int[]{123, 0, 432, 123},
    214                 new int[] {
    215                         ContactLookupKey.LOOKUP_TYPE_DISPLAY_NAME,
    216                         ContactLookupKey.LOOKUP_TYPE_SOURCE_ID,
    217                         ContactLookupKey.LOOKUP_TYPE_SOURCE_ID,
    218                         ContactLookupKey.LOOKUP_TYPE_DISPLAY_NAME,
    219                         ContactLookupKey.LOOKUP_TYPE_RAW_CONTACT_ID,
    220                 },
    221                 new String[]{"1248AC", "1248AC", "12.48AC", "1248AC", "2184CA"});
    222     }
    223 
    224     private void assertLookupKey(String lookupKey, int[] accountHashCodes, int[] types,
    225             String[] keys) {
    226         ContactLookupKey key = new ContactLookupKey();
    227         ArrayList<LookupKeySegment> list = key.parse(lookupKey);
    228         assertEquals(types.length, list.size());
    229 
    230         for (int i = 0; i < accountHashCodes.length; i++) {
    231             LookupKeySegment segment = list.get(i);
    232             assertEquals(accountHashCodes[i], segment.accountHashCode);
    233             assertEquals(types[i], segment.lookupType);
    234             assertEquals(keys[i], segment.key);
    235         }
    236     }
    237 }
    238 
    239