1a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov/*
2a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project
3a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov *
4a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
5a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * you may not use this file except in compliance with the License.
6a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * You may obtain a copy of the License at
7a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov *
8a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
9a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov *
10a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
11a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
12a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * See the License for the specific language governing permissions and
14a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * limitations under the License.
15a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov */
168920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens
17a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovpackage com.android.providers.contacts;
18a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
196bc46c9f22aaa9e68f344b171426fc686d3b536aDmitri Plotnikovimport android.accounts.Account;
20a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovimport android.app.SearchManager;
21a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovimport android.content.ContentValues;
22a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovimport android.database.Cursor;
23a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovimport android.net.Uri;
24a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovimport android.provider.ContactsContract;
25244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
26174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikovimport android.provider.ContactsContract.Contacts;
27244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikovimport android.provider.ContactsContract.Data;
2882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
29583b1364980fd46a5012825886af3160752ff19cMakoto Onukiimport android.test.suitebuilder.annotation.MediumTest;
30a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DataUtil;
328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.RawContactUtil;
338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
34a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov/**
35a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * Unit tests for {@link GlobalSearchSupport}.
365b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill * <p>
37a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov * Run the test like this:
385b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill * <p>
395b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill * <code><pre>
408920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * adb shell am instrument -e class com.android.providers.contacts.GlobalSearchSupportTest -w \
41a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
425b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill * </pre></code>
43a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov */
44583b1364980fd46a5012825886af3160752ff19cMakoto Onuki@MediumTest
45a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikovpublic class GlobalSearchSupportTest extends BaseContactsProvider2Test {
465b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
47244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov    public void testSearchSuggestionsNotInDefaultDirectory() throws Exception {
486bc46c9f22aaa9e68f344b171426fc686d3b536aDmitri Plotnikov        Account account = new Account("actname", "acttype");
49244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov
50244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov        // Creating an AUTO_ADD group will exclude all ungrouped contacts from global search
51244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov        createGroup(account, "any", "any", 0 /* visible */, true /* auto-add */, false /* fav */);
52244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov
538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, account);
548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Deer", "Dough");
55a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
56244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov        // Remove the new contact from all groups
57244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov        mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
58244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov                + " AND " + Data.MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE + "'", null);
59244f914757fef93841d33a300a1b42a77ac80b2eDmitri Plotnikov
60a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov        Uri searchUri = new Uri.Builder().scheme("content").authority(ContactsContract.AUTHORITY)
61a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath("D").build();
62a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
63a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov        // If the contact is not in the "my contacts" group, nothing should be found
64a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov        Cursor c = mResolver.query(searchUri, null, null, null, null);
65a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov        assertEquals(0, c.getCount());
66a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov        c.close();
67a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov    }
68a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
695b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    public void testSearchSuggestionsByNameWithPhoto() throws Exception {
705b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").photo(
715b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                loadTestPhoto()).build();
725b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        new SuggestionTesterBuilder(contact).query("D").expectIcon1Uri(true).expectedText1(
735b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                "Deer Dough").build().test();
74a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov    }
75a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
769a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov    public void testSearchSuggestionsByEmailWithPhoto() {
779a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").photo(
789a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov                loadTestPhoto()).email("foo@acme.com").build();
799a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov        new SuggestionTesterBuilder(contact).query("foo@ac").expectIcon1Uri(true).expectedIcon2(
809a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov                String.valueOf(StatusUpdates.getPresenceIconResourceId(StatusUpdates.OFFLINE)))
819a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov                .expectedText1("Deer Dough").expectedText2("foo@acme.com").build().test();
829a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov    }
839a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov
84174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov    public void testSearchSuggestionsByName() {
855b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").company("Google")
865b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                .build();
875b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        new SuggestionTesterBuilder(contact).query("D").expectedText1("Deer Dough").expectedText2(
88174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                null).build().test();
895b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    }
90a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
91174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov    public void testSearchByNickname() {
925b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").nickname(
935b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                "Little Fawn").company("Google").build();
945b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        new SuggestionTesterBuilder(contact).query("L").expectedText1("Deer Dough").expectedText2(
95174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                "Little Fawn").build().test();
965b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    }
97a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
985b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    public void testSearchByCompany() {
995b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").company("Google")
1005b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                .build();
1015b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        new SuggestionTesterBuilder(contact).query("G").expectedText1("Deer Dough").expectedText2(
1025b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                "Google").build().test();
1035b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    }
104b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov
1055b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    public void testSearchByTitleWithCompany() {
1065b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").company("Google")
1075b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                .title("Software Engineer").build();
1085b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        new SuggestionTesterBuilder(contact).query("S").expectIcon1Uri(false).expectedText1(
109174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                "Deer Dough").expectedText2("Software Engineer, Google").build().test();
110a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov    }
111a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov
1129a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov    public void testSearchSuggestionsByPhoneNumberOnNonPhone() throws Exception {
1139a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov        getContactsProvider().setIsPhone(false);
1149a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov
1159a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov        GoldenContact contact = new GoldenContactBuilder().name("Deer", "Dough").photo(
1169a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov                loadTestPhoto()).phone("1-800-4664-411").build();
1179a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov        new SuggestionTesterBuilder(contact).query("1800").expectIcon1Uri(true).expectedText1(
118084a9d5ee564c758ff7709690ab404d6ac58e78dMathew Inwood                "Deer Dough").expectedText2("1-800-4664-411").build().test();
1199a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov    }
1209a6be1610fdf40c2f7f04cfe4b66fde3a35940dcDmitri Plotnikov
1215b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    /**
1222d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill     * Tests that the quick search suggestion returns the expected contact
1235b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill     * information.
1245b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill     */
1255b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    private final class SuggestionTester {
1265b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1275b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final GoldenContact contact;
1285b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1295b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final String query;
1305b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1315b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final boolean expectIcon1Uri;
1325b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1335b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final String expectedIcon2;
1345b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1355b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final String expectedText1;
1365b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1375b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final String expectedText2;
1385b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1395b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTester(SuggestionTesterBuilder builder) {
1405b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            contact = builder.contact;
1415b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            query = builder.query;
1425b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectIcon1Uri = builder.expectIcon1Uri;
1435b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectedIcon2 = builder.expectedIcon2;
1445b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectedText1 = builder.expectedText1;
1455b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectedText2 = builder.expectedText2;
1465b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
1475b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1482d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        /**
1492d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * Tests suggest and refresh queries from quick search box, then deletes the contact from
1502d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * the data base.
1512d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         */
1525b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public void test() {
1535b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1542d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            testQsbSuggest();
1552d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            testContactIdQsbRefresh();
1562d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            testLookupKeyQsbRefresh();
1572d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
1582d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            // Cleanup
1592d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            contact.delete();
1602d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        }
1612d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
1622d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        /**
1632d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * Tests that the contacts provider return the appropriate information from the golden
1642d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * contact in response to the suggestion query from the quick search box.
1652d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         */
1662d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        private void testQsbSuggest() {
1672d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
1685b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            Uri searchUri = new Uri.Builder().scheme("content").authority(
1695b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                    ContactsContract.AUTHORITY).appendPath(SearchManager.SUGGEST_URI_PATH_QUERY)
1705b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                    .appendPath(query).build();
1715b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1725b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            Cursor c = mResolver.query(searchUri, null, null, null, null);
173084a9d5ee564c758ff7709690ab404d6ac58e78dMathew Inwood            assertEquals(1, c.getCount());
1745b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            c.moveToFirst();
1755b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1765b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            String icon1 = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1));
1775b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            if (expectIcon1Uri) {
1785b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                assertTrue(icon1.startsWith("content:"));
1795b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            } else {
1805b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                assertEquals(String.valueOf(com.android.internal.R.drawable.ic_contact_picture),
1815b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                        icon1);
1825b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            }
1835b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
1842d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            // SearchManager does not declare a constant for _id
1852d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            ContentValues values = getContactValues();
1865b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            assertCursorValues(c, values);
187fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
1885b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            c.close();
1892d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        }
1902d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
1912d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        /**
1922d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * Returns the expected Quick Search Box content values for the golden contact.
1932d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         */
1942d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        private ContentValues getContactValues() {
1952d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
1962d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            ContentValues values = new ContentValues();
1972d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            values.put("_id", contact.getContactId());
1982d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, expectedText1);
1992d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, expectedText2);
2002d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
2012d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            values.put(SearchManager.SUGGEST_COLUMN_ICON_2, expectedIcon2);
202174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA,
203174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                    Contacts.getLookupUri(contact.getContactId(), contact.getLookupKey())
204174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                            .toString());
205174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, contact.getLookupKey());
206174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, query);
207174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            return values;
208174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov        }
209174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov
210174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov        /**
211174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov         * Returns the expected Quick Search Box content values for the golden contact.
212174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov         */
213174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov        private ContentValues getRefreshValues() {
214174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov
215174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            ContentValues values = new ContentValues();
216174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put("_id", contact.getContactId());
217174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, expectedText1);
218174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, expectedText2);
219174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov
220174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov            values.put(SearchManager.SUGGEST_COLUMN_ICON_2, expectedIcon2);
2212d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, contact.getLookupKey());
2222d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            values.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, contact.getLookupKey());
2232d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            return values;
2242d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        }
2252d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
2262d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        /**
2272d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * Performs the refresh query and returns a cursor to the results.
2282d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         *
2292d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * @param refreshId the final component path of the refresh query, which identifies which
2302d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         *        contact to refresh.
2312d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         */
2322d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        private Cursor refreshQuery(String refreshId) {
2335b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2345b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            // See if the same result is returned by a shortcut refresh
2352d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            Uri refershUri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath(
2362d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill                    SearchManager.SUGGEST_URI_PATH_SHORTCUT)
237174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                    .appendPath(refreshId)
238174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                    .appendQueryParameter(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, query)
239174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                    .build();
2405b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2415b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            String[] projection = new String[] {
2425b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                    SearchManager.SUGGEST_COLUMN_ICON_1, SearchManager.SUGGEST_COLUMN_ICON_2,
2435b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                    SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2,
2445b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                    SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,
2455b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                    SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "_id",
2465b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            };
2475b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2482d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            return mResolver.query(refershUri, projection, null, null, null);
2492d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        }
2502d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
2512d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        /**
2522d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * Tests that the contacts provider returns an empty result in response to a refresh query
2532d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * from the quick search box that uses the contact id to identify the contact.  The empty
2542d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * result indicates that the shortcut is no longer valid, and the QSB will replace it with
2552d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * a new-style shortcut the next time they click on the contact.
2562d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         *
2572d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * @see #testLookupKeyQsbRefresh()
2582d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         */
2592d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        private void testContactIdQsbRefresh() {
2602d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
2612d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            Cursor c = refreshQuery(String.valueOf(contact.getContactId()));
2622d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            try {
2632d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill                assertEquals("Record count", 0, c.getCount());
2642d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            } finally {
2652d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill                c.close();
2662d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            }
2672d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        }
2682d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
2692d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        /**
2702d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * Tests that the contacts provider return the appropriate information from the golden
2712d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * contact in response to the refresh query from the quick search box.  The refresh query
2722d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * uses the currently-supported mechanism of identifying the contact by the lookup key,
2732d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * which is more stable than the previously used contact id.
2742d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         */
2752d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        private void testLookupKeyQsbRefresh() {
2762d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill
2772d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill            Cursor c = refreshQuery(contact.getLookupKey());
2785b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            try {
2795b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                assertEquals("Record count", 1, c.getCount());
2805b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                c.moveToFirst();
281174f7d319b987aa2aeeb6f2563f4b939acb8d791Dmitri Plotnikov                assertCursorValues(c, getRefreshValues());
2825b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            } finally {
2835b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill                c.close();
2845b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            }
2855b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
2865b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    }
2875b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2885b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    /**
2895b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill     * Builds {@link SuggestionTester} objects. Unspecified boolean objects default to
2905b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill     * false. Unspecified String objects default to null.
2915b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill     */
2925b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    private final class SuggestionTesterBuilder {
2935b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2945b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private final GoldenContact contact;
2955b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2965b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private String query;
2975b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
2985b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private boolean expectIcon1Uri;
2995b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3005b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private String expectedIcon2;
3015b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3025b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private String expectedText1;
3035b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3045b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        private String expectedText2;
3055b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3065b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTesterBuilder(GoldenContact contact) {
3075b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            this.contact = contact;
3085b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3095b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3105b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        /**
3115b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * Builds the {@link SuggestionTester} specified by this builder.
3125b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         */
3135b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTester build() {
3145b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            return new SuggestionTester(this);
3155b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3165b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3175b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        /**
3182d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill         * The text of the user's query to quick search (i.e., what they typed
3195b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * in the search box).
3205b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         */
3215b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTesterBuilder query(String value) {
3225b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            query = value;
3235b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            return this;
3245b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3255b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3265b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        /**
3275b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * Whether to set Icon1, which in practice is the contact's photo.
3285b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * <p>
3295b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * TODO(tomo): Replace with actual expected value? This might be hard
3305b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * because the values look non-deterministic, such as
3315b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * "content://com.android.contacts/contacts/2015/photo"
3325b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         */
3335b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTesterBuilder expectIcon1Uri(boolean value) {
3345b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectIcon1Uri = value;
3355b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            return this;
3365b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3375b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3385b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        /**
3395b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * The value for Icon2, which in practice is the contact's Chat status
3405b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * (available, busy, etc.)
3415b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         */
3425b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTesterBuilder expectedIcon2(String value) {
3435b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectedIcon2 = value;
3445b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            return this;
3455b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3465b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3475b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        /**
3485b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * First line of suggestion text expected to be returned (required).
3495b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         */
3505b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTesterBuilder expectedText1(String value) {
3515b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectedText1 = value;
3525b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            return this;
3535b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3545b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill
3555b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        /**
3565b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         * Second line of suggestion text expected to return (optional).
3575b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill         */
3585b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        public SuggestionTesterBuilder expectedText2(String value) {
3595b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            expectedText2 = value;
3605b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill            return this;
3615b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill        }
3625b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill    }
3635b3b3ec368625c07a2c94d2199a75099d4d9b8a9Tom O'Neill}
364