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.ContentValues;
     20 import android.net.Uri;
     21 import android.net.Uri.Builder;
     22 import android.provider.ContactsContract.CommonDataKinds.Im;
     23 import android.provider.ContactsContract.CommonDataKinds.Organization;
     24 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
     25 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
     26 import android.provider.ContactsContract.Contacts;
     27 import android.provider.ContactsContract.SearchSnippetColumns;
     28 import android.test.suitebuilder.annotation.MediumTest;
     29 import android.test.suitebuilder.annotation.Suppress;
     30 
     31 import java.text.Collator;
     32 import java.util.Arrays;
     33 import java.util.Locale;
     34 
     35 /**
     36  * Unit tests for {@link SearchIndexManager}.
     37  *
     38  * Run the test like this:
     39  * <code>
     40  * adb shell am instrument -e class com.android.providers.contacts.SearchIndexManagerTest -w \
     41  *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
     42  * </code>
     43  */
     44 @MediumTest
     45 public class SearchIndexManagerTest extends BaseContactsProvider2Test {
     46 
     47     public void testSearchIndexForStructuredName() {
     48         long rawContactId = createRawContact();
     49         long contactId = queryContactId(rawContactId);
     50         insertStructuredName(rawContactId, "John", "Doe");
     51         ContentValues values = new ContentValues();
     52         values.put(StructuredName.DISPLAY_NAME, "Bob I. Parr");
     53         insertStructuredName(rawContactId, values);
     54         values.clear();
     55         values.put(StructuredName.PREFIX, "Mrs.");
     56         values.put(StructuredName.GIVEN_NAME, "Helen");
     57         values.put(StructuredName.MIDDLE_NAME, "I.");
     58         values.put(StructuredName.FAMILY_NAME, "Parr");
     59         values.put(StructuredName.SUFFIX, "PhD");
     60         values.put(StructuredName.PHONETIC_FAMILY_NAME, "par");
     61         values.put(StructuredName.PHONETIC_GIVEN_NAME, "helen");
     62         insertStructuredName(rawContactId, values);
     63 
     64         assertSearchIndex(
     65                 contactId, null, "John Doe Bob I Parr Helen I Parr PhD par helen parhelen", null);
     66     }
     67 
     68     public void testSearchIndexForChineseName() {
     69         // Only run this test when Chinese collation is supported
     70         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
     71             return;
     72         }
     73 
     74         long rawContactId = createRawContact();
     75         long contactId = queryContactId(rawContactId);
     76         ContentValues values = new ContentValues();
     77         values.put(StructuredName.DISPLAY_NAME, "\u695A\u8FAD");    // CHUCI
     78         insertStructuredName(rawContactId, values);
     79 
     80         assertSearchIndex(
     81                 contactId, null, "\u695A\u8FAD \u695A\u8FAD CI \u8FAD CHUCI CC C", null);
     82     }
     83 
     84     public void testSearchByChineseName() {
     85         // Only run this test when Chinese collation is supported
     86         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
     87             return;
     88         }
     89 
     90         long rawContactId = createRawContact();
     91         ContentValues values = new ContentValues();
     92         values.put(StructuredName.DISPLAY_NAME, "\u695A\u8FAD");    // CHUCI
     93         insertStructuredName(rawContactId, values);
     94 
     95         assertStoredValue(buildSearchUri("\u695A\u8FAD"), SearchSnippetColumns.SNIPPET, null);
     96         assertStoredValue(buildSearchUri("\u8FAD"), SearchSnippetColumns.SNIPPET, null);
     97         assertStoredValue(buildSearchUri("CI"), SearchSnippetColumns.SNIPPET, null);
     98         assertStoredValue(buildSearchUri("CHUCI"), SearchSnippetColumns.SNIPPET, null);
     99         assertStoredValue(buildSearchUri("CC"), SearchSnippetColumns.SNIPPET, null);
    100         assertStoredValue(buildSearchUri("C"), SearchSnippetColumns.SNIPPET, null);
    101     }
    102 
    103     public void testSearchIndexForKoreanName() {
    104         // Only run this test when Korean collation is supported
    105         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.KOREA)) {
    106             return;
    107         }
    108 
    109         long rawContactId = createRawContact();
    110         long contactId = queryContactId(rawContactId);
    111         ContentValues values = new ContentValues();
    112         values.put(StructuredName.DISPLAY_NAME, "\uC774\uC0C1\uC77C");    // Lee Sang Il
    113         insertStructuredName(rawContactId, values);
    114 
    115         assertSearchIndex(contactId, null,
    116                 "\uC774\uC0C1\uC77C \uC0C1\uC77C \u1109\u110B \u110B\u1109\u110B", null);
    117     }
    118 
    119     public void testSearchByKoreanName() {
    120         // Only run this test when Korean collation is supported
    121         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.KOREA)) {
    122             return;
    123         }
    124 
    125         long rawContactId = createRawContact();
    126         ContentValues values = new ContentValues();
    127         values.put(StructuredName.DISPLAY_NAME, "\uC774\uC0C1\uC77C");   // Lee Sang Il
    128         insertStructuredName(rawContactId, values);
    129 
    130         // Full name: Lee Sang Il
    131         assertStoredValue(buildSearchUri("\uC774\uC0C1\uC77C"), SearchSnippetColumns.SNIPPET, null);
    132 
    133         // Given name: Sang Il
    134         assertStoredValue(buildSearchUri("\uC0C1\uC77C"), SearchSnippetColumns.SNIPPET, null);
    135 
    136         // Consonants of given name: SIOS IEUNG
    137         assertStoredValue(buildSearchUri("\u1109\u110B"), SearchSnippetColumns.SNIPPET, null);
    138 
    139         // Consonants of full name: RIEUL SIOS IEUNG
    140         assertStoredValue(buildSearchUri("\u110B\u1109\u110B"), SearchSnippetColumns.SNIPPET, null);
    141     }
    142 
    143     public void testSearchByKoreanNameWithTwoCharactersFamilyName() {
    144         // Only run this test when Korean collation is supported.
    145         if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.KOREA)) {
    146             return;
    147         }
    148 
    149         long rawContactId = createRawContact();
    150 
    151         // Sun Woo Young Nyeu
    152         ContentValues values = new ContentValues();
    153         values.put(StructuredName.DISPLAY_NAME, "\uC120\uC6B0\uC6A9\uB140");
    154 
    155         insertStructuredName(rawContactId, values);
    156 
    157         // Full name: Sun Woo Young Nyeu
    158         assertStoredValue(
    159                 buildSearchUri("\uC120\uC6B0\uC6A9\uB140"), SearchSnippetColumns.SNIPPET, null);
    160 
    161         // Given name: Young Nyeu
    162         assertStoredValue(buildSearchUri("\uC6A9\uB140"), SearchSnippetColumns.SNIPPET, null);
    163 
    164         // Consonants of given name: IEUNG NIEUN
    165         assertStoredValue(buildSearchUri("\u110B\u1102"), SearchSnippetColumns.SNIPPET, null);
    166 
    167         // Consonants of full name: SIOS IEUNG IEUNG NIEUN
    168         assertStoredValue(
    169                 buildSearchUri("\u1109\u110B\u110B\u1102"), SearchSnippetColumns.SNIPPET, null);
    170     }
    171 
    172     public void testSearchIndexForOrganization() {
    173         long rawContactId = createRawContact();
    174         long contactId = queryContactId(rawContactId);
    175         ContentValues values = new ContentValues();
    176         values.put(Organization.COMPANY, "Acme Inc.");
    177         values.put(Organization.TITLE, "Director");
    178         values.put(Organization.DEPARTMENT, "Phones and tablets");
    179         values.put(Organization.JOB_DESCRIPTION, "full text search");
    180         values.put(Organization.SYMBOL, "ACME");
    181         values.put(Organization.PHONETIC_NAME, "ack-me");
    182         values.put(Organization.OFFICE_LOCATION, "virtual");
    183         insertOrganization(rawContactId, values);
    184 
    185         assertSearchIndex(contactId,
    186                 "Director, Acme Inc. (ack-me) (ACME)/Phones and tablets/virtual/full text search",
    187                 null, null);
    188     }
    189 
    190     public void testSearchIndexForPhoneNumber() {
    191         long rawContactId = createRawContact();
    192         long contactId = queryContactId(rawContactId);
    193         insertPhoneNumber(rawContactId, "800555GOOG");
    194         insertPhoneNumber(rawContactId, "8005551234");
    195 
    196         assertSearchIndex(contactId, null, null, "8005554664 +18005554664 8005551234 +18005551234");
    197     }
    198 
    199     public void testSearchIndexForEmail() {
    200         long rawContactId = createRawContact();
    201         long contactId = queryContactId(rawContactId);
    202         insertEmail(rawContactId, "Bob Parr <incredible (at) android.com>");
    203         insertEmail(rawContactId, "bob_parr (at) android.com");
    204 
    205         assertSearchIndex(contactId, "Bob Parr <incredible (at) android.com>\nbob_parr (at) android.com",
    206                 null, null);
    207     }
    208 
    209     public void testSearchIndexForNickname() {
    210         long rawContactId = createRawContact();
    211         long contactId = queryContactId(rawContactId);
    212         insertNickname(rawContactId, "incredible");
    213 
    214         assertSearchIndex(contactId, "incredible", null, null);
    215     }
    216 
    217     public void testSearchIndexForStructuredPostal() {
    218         long rawContactId = createRawContact();
    219         long contactId = queryContactId(rawContactId);
    220         insertPostalAddress(rawContactId, "1600 Amphitheatre Pkwy\nMountain View, CA 94043");
    221         ContentValues values = new ContentValues();
    222         values.put(StructuredPostal.CITY, "London");
    223         values.put(StructuredPostal.STREET, "76 Buckingham Palace Road");
    224         values.put(StructuredPostal.POSTCODE, "SW1W 9TQ");
    225         values.put(StructuredPostal.COUNTRY, "United Kingdom");
    226         insertPostalAddress(rawContactId, values);
    227 
    228         assertSearchIndex(contactId, "1600 Amphitheatre Pkwy Mountain View, CA 94043\n"
    229                 + "76 Buckingham Palace Road London SW1W 9TQ United Kingdom", null, null);
    230     }
    231 
    232     public void testSearchIndexForIm() {
    233         long rawContactId = createRawContact();
    234         long contactId = queryContactId(rawContactId);
    235         insertImHandle(rawContactId, Im.PROTOCOL_JABBER, null, "bp (at) android.com");
    236         insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "android_im", "android (at) android.com");
    237 
    238         assertSearchIndex(
    239                 contactId, "Jabber/bp@android.com\nandroid_im/android@android.com", null, null);
    240     }
    241 
    242     public void testSearchIndexForNote() {
    243         long rawContactId = createRawContact();
    244         long contactId = queryContactId(rawContactId);
    245         insertNote(rawContactId, "Please note: three notes or more make up a chord.");
    246 
    247         assertSearchIndex(
    248                 contactId, "Please note: three notes or more make up a chord.", null, null);
    249     }
    250 
    251     public void testSnippetArgs() {
    252         long rawContactId = createRawContact();
    253         insertNote(rawContactId, "Please note: three notes or more make up a chord.");
    254 
    255         assertStoredValue(
    256                 buildSearchUri("thr", "[,],-,2", false), SearchSnippetColumns.SNIPPET,
    257                 "-note: [three]-");
    258     }
    259 
    260     public void testEmptyFilter() {
    261         createRawContactWithName("John", "Doe");
    262         assertEquals(0, getCount(buildSearchUri(""), null, null));
    263     }
    264 
    265     public void testSearchByName() {
    266         createRawContactWithName("John Jay", "Doe");
    267 
    268         // We are supposed to find the contact, but return a null snippet
    269         assertStoredValue(buildSearchUri("john"), SearchSnippetColumns.SNIPPET, null);
    270         assertStoredValue(buildSearchUri("jay"), SearchSnippetColumns.SNIPPET, null);
    271         assertStoredValue(buildSearchUri("doe"), SearchSnippetColumns.SNIPPET, null);
    272     }
    273 
    274     public void testSearchByPrefixName() {
    275         createRawContactWithName("John Jay", "Doe");
    276 
    277         // prefix searches
    278         assertStoredValue(buildSearchUri("jo ja"), SearchSnippetColumns.SNIPPET, null);
    279         assertStoredValue(buildSearchUri("J D"), SearchSnippetColumns.SNIPPET, null);
    280         assertStoredValue(buildSearchUri("Doe, John"), SearchSnippetColumns.SNIPPET, null);
    281     }
    282 
    283     public void testGermanUmlautFullameCapitalizationSearch() {
    284         createRawContactWithName("Matthus BJRN Bnyamin", "Reier");
    285 
    286         // make sure we can find those, independent of the capitalization
    287         assertStoredValue(buildSearchUri("matthus"), SearchSnippetColumns.SNIPPET, null);
    288         assertStoredValue(buildSearchUri("Matthus"), SearchSnippetColumns.SNIPPET, null);
    289         assertStoredValue(buildSearchUri("MATTHUS"), SearchSnippetColumns.SNIPPET, null);
    290 
    291         assertStoredValue(buildSearchUri("bjrn"), SearchSnippetColumns.SNIPPET, null);
    292         assertStoredValue(buildSearchUri("Bjrn"), SearchSnippetColumns.SNIPPET, null);
    293         assertStoredValue(buildSearchUri("BJRN"), SearchSnippetColumns.SNIPPET, null);
    294 
    295         assertStoredValue(buildSearchUri("bnyamin"), SearchSnippetColumns.SNIPPET, null);
    296         assertStoredValue(buildSearchUri("Bnyamin"), SearchSnippetColumns.SNIPPET, null);
    297         assertStoredValue(buildSearchUri("BUNYAMIN"), SearchSnippetColumns.SNIPPET, null);
    298 
    299         // There is no capital version of . It is capitalized as double-S instead
    300         assertStoredValue(buildSearchUri("Reier"), SearchSnippetColumns.SNIPPET, null);
    301         assertStoredValue(buildSearchUri("Reisser"), SearchSnippetColumns.SNIPPET, null);
    302         assertStoredValue(buildSearchUri("REISSER"), SearchSnippetColumns.SNIPPET, null);
    303     }
    304 
    305     public void testHangulNameLeadConsonantAsYouTypeSearch() {
    306         createRawContactWithDisplayName("");
    307         // the korean name uses three compound characters. this test makes sure
    308         // that the name can be found by typing in only the lead consonant
    309         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    310         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    311         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    312 
    313         // same again, this time only for the first name
    314         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    315         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    316     }
    317 
    318     public void testHangulNameFullAsYouTypeSearch() {
    319         createRawContactWithDisplayName("");
    320 
    321         // the korean name uses three compound characters. this test makes sure
    322         // that the name can be found by typing in the full nine letters. the search string
    323         // shows the name is being built "as you type"
    324         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    325         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    326         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    327         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    328         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    329         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    330         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    331         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    332         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    333 
    334         // same again, this time only for the first name
    335         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    336         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    337         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    338         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    339         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    340         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    341     }
    342 
    343 
    344     /** Decomposed Hangul is not yet supported. This text is how we would test it */
    345     @Suppress
    346     public void testHangulNameDecomposedSearch() {
    347         createRawContactWithDisplayName("");
    348 
    349         // the korean name uses three compound characters. this test makes sure
    350         // that the name can be found by typing each syllable as a single character.
    351         // This can be achieved using the Korean IM by pressing , space, backspace,  and so on
    352         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    353         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    354         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    355         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    356         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    357         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    358         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    359         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    360         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    361 
    362         // same again, this time only for the first name
    363         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    364         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    365         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    366         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    367         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    368         assertStoredValue(buildSearchUri(""), SearchSnippetColumns.SNIPPET, null);
    369     }
    370 
    371     public void testNameWithHyphen() {
    372         createRawContactWithName("First", "Last-name");
    373 
    374         assertStoredValue(buildSearchUri("First"), SearchSnippetColumns.SNIPPET, null);
    375         assertStoredValue(buildSearchUri("Last"), SearchSnippetColumns.SNIPPET, null);
    376         assertStoredValue(buildSearchUri("Last-"), SearchSnippetColumns.SNIPPET, null);
    377         assertStoredValue(buildSearchUri("Last-n"), SearchSnippetColumns.SNIPPET, null);
    378         assertStoredValue(buildSearchUri("Last-name"), SearchSnippetColumns.SNIPPET, null);
    379 
    380         // With the current implementation this even works, but this may stop working when we
    381         // fix the "O'Neill" case below.
    382         assertStoredValue(buildSearchUri("name"), SearchSnippetColumns.SNIPPET, null);
    383     }
    384 
    385     /** Same as {@link #testNameWithHyphen} except the name has double hyphens. */
    386     public void testNameWithDoubleHyphens() {
    387         createRawContactWithName("First", "Last--name");
    388 
    389         assertStoredValue(buildSearchUri("First"), SearchSnippetColumns.SNIPPET, null);
    390         assertStoredValue(buildSearchUri("Last"), SearchSnippetColumns.SNIPPET, null);
    391         assertStoredValue(buildSearchUri("Last-"), SearchSnippetColumns.SNIPPET, null);
    392         assertStoredValue(buildSearchUri("Last-n"), SearchSnippetColumns.SNIPPET, null);
    393         assertStoredValue(buildSearchUri("Last-name"), SearchSnippetColumns.SNIPPET, null);
    394     }
    395 
    396     /**
    397      * Probably both "oneill" and "o'neill" should match "o'neill", but at this point only "oneill"
    398      * works.
    399      */
    400     @Suppress
    401     public void testNameWithPunctuations() {
    402         createRawContactWithName("First", "O'Neill");
    403 
    404         assertStoredValue(buildSearchUri("first"), SearchSnippetColumns.SNIPPET, null);
    405         assertStoredValue(buildSearchUri("oneill"), SearchSnippetColumns.SNIPPET, null);
    406         assertStoredValue(buildSearchUri("o'neill"), SearchSnippetColumns.SNIPPET, null);
    407     }
    408 
    409     public void testSearchByEmailAddress() {
    410         long rawContactId = createRawContact();
    411         insertPhoneNumber(rawContactId, "1234567890");
    412         insertEmail(rawContactId, "john (at) doe.com");
    413         insertNote(rawContactId, "a hundred dollar note for doe (at) john.com and bob parr");
    414 
    415         assertStoredValue(buildSearchUri("john@d", true), SearchSnippetColumns.SNIPPET,
    416                 "[john (at) doe.com]");
    417         assertStoredValue(buildSearchUri("doe@j", true), SearchSnippetColumns.SNIPPET,
    418                 "...note for [doe (at) john.com] and bob...");
    419         assertStoredValue(buildSearchUri("bob@p", true), SearchSnippetColumns.SNIPPET, null);
    420     }
    421 
    422     public void testSearchByPhoneNumber() {
    423         long rawContactId = createRawContact();
    424         insertPhoneNumber(rawContactId, "330142685300");
    425         insertPhoneNumber(rawContactId, "(800)GOOG-123");
    426         insertEmail(rawContactId, "john (at) doe.com");
    427         insertNote(rawContactId, "the eighteenth episode of Seinfeld, 650-253-0000");
    428 
    429         assertStoredValue(buildSearchUri("33 (0)1 42 68 53 00"), SearchSnippetColumns.SNIPPET,
    430                 "[330142685300]");
    431         assertStoredValue(buildSearchUri("8004664"), SearchSnippetColumns.SNIPPET,
    432                 "[(800)GOOG-123]");
    433         assertStoredValue(buildSearchUri("650-2"), SearchSnippetColumns.SNIPPET,
    434                 "...doe.com\nthe eighteenth episode of Seinfeld, [650]-[253]-0000");
    435 
    436         // for numbers outside of the real phone field, any order (and prefixing) is allowed
    437         assertStoredValue(buildSearchUri("25 650"), SearchSnippetColumns.SNIPPET,
    438                 "...doe.com\nthe eighteenth episode of Seinfeld, [650]-[253]-0000");
    439     }
    440 
    441     private Uri buildSearchUri(String filter) {
    442         return buildSearchUri(filter, false);
    443     }
    444 
    445     private Uri buildSearchUri(String filter, boolean deferredSnippeting) {
    446         return buildSearchUri(filter, null, deferredSnippeting);
    447     }
    448 
    449     private Uri buildSearchUri(String filter, String args, boolean deferredSnippeting) {
    450         Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon().appendPath(filter);
    451         if (args != null) {
    452             builder.appendQueryParameter(SearchSnippetColumns.SNIPPET_ARGS_PARAM_KEY, args);
    453         }
    454         if (deferredSnippeting) {
    455             builder.appendQueryParameter(SearchSnippetColumns.DEFERRED_SNIPPETING_KEY, "1");
    456         }
    457         return builder.build();
    458     }
    459 
    460     private void createRawContactWithDisplayName(String name) {
    461         long rawContactId = createRawContact();
    462         ContentValues values = new ContentValues();
    463         values.put(StructuredName.DISPLAY_NAME, name);
    464         insertStructuredName(rawContactId, values);
    465     }
    466 
    467     // TODO: expectedName must be tested. Many tests in here are quite useless at the moment
    468     private void assertSearchIndex(
    469             long contactId, String expectedContent, String expectedName, String expectedTokens) {
    470         ContactsDatabaseHelper dbHelper = (ContactsDatabaseHelper) getContactsProvider()
    471                 .getDatabaseHelper();
    472         assertEquals(expectedContent, dbHelper.querySearchIndexContentForTest(contactId));
    473         assertEquals(expectedTokens, dbHelper.querySearchIndexTokensForTest(contactId));
    474     }
    475 }
    476 
    477