1/*
2 * Copyright (C) 2010 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
17package com.android.contacts.activities;
18
19import android.content.ContentValues;
20import android.content.Intent;
21import android.content.Loader;
22import android.net.Uri;
23import android.os.AsyncTask;
24import android.provider.ContactsContract;
25import android.provider.ContactsContract.ContactCounts;
26import android.provider.ContactsContract.Contacts;
27import android.provider.ContactsContract.Directory;
28import android.provider.ContactsContract.Groups;
29import android.provider.ContactsContract.ProviderStatus;
30import android.provider.Settings;
31import android.test.ActivityInstrumentationTestCase2;
32import android.test.suitebuilder.annotation.SmallTest;
33import android.widget.TextView;
34
35import com.android.contacts.ContactsApplication;
36import com.android.contacts.R;
37import com.android.contacts.common.ContactPhotoManager;
38import com.android.contacts.common.test.mocks.ContactsMockContext;
39import com.android.contacts.common.test.mocks.MockContentProvider;
40import com.android.contacts.common.test.mocks.MockContentProvider.Query;
41import com.android.contacts.detail.ContactDetailFragment;
42import com.android.contacts.interactions.TestLoaderManager;
43import com.android.contacts.list.ContactBrowseListFragment;
44import com.android.contacts.common.model.AccountTypeManager;
45import com.android.contacts.common.model.account.AccountType;
46import com.android.contacts.common.model.account.AccountWithDataSet;
47import com.android.contacts.common.model.account.BaseAccountType;
48import com.android.contacts.test.InjectedServices;
49import com.android.contacts.tests.mocks.MockAccountTypeManager;
50import com.android.contacts.tests.mocks.MockContactPhotoManager;
51import com.android.contacts.tests.mocks.MockSharedPreferences;
52import com.android.contacts.util.PhoneCapabilityTester;
53
54/**
55 * This test is so outdated that it's disabled temporarily.  TODO Update the test and re-enable it.
56 *
57 * Tests for {@link PeopleActivity}.
58 *
59 * Running all tests:
60 *
61 *   runtest contacts
62 * or
63 *   adb shell am instrument \
64 *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
65 *
66 */
67@SmallTest
68public class PeopleActivityTest
69        extends ActivityInstrumentationTestCase2<PeopleActivity>
70{
71    static {
72        // AsyncTask class needs to be initialized on the main thread.
73        AsyncTask.init();
74    }
75
76    private static final String TEST_ACCOUNT = "testAccount";
77    private static final String TEST_ACCOUNT_TYPE = "testAccountType";
78
79    private ContactsMockContext mContext;
80    private MockContentProvider mContactsProvider;
81    private MockContentProvider mSettingsProvider;
82
83    public PeopleActivityTest() {
84        super(PeopleActivity.class);
85    }
86
87    @Override
88    public void setUp() {
89        mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
90        mContactsProvider = mContext.getContactsProvider();
91        mSettingsProvider = mContext.getSettingsProvider();
92        InjectedServices services = new InjectedServices();
93        services.setContentResolver(mContext.getContentResolver());
94        services.setSharedPreferences(new MockSharedPreferences());
95        services.setSystemService(ContactPhotoManager.CONTACT_PHOTO_SERVICE,
96                new MockContactPhotoManager());
97        AccountType accountType = new BaseAccountType() {
98            @Override
99            public boolean areContactsWritable() {
100                return false;
101            }
102        };
103        accountType.accountType = TEST_ACCOUNT_TYPE;
104
105        AccountWithDataSet account = new AccountWithDataSet(TEST_ACCOUNT, TEST_ACCOUNT_TYPE, null);
106        ContactsApplication.injectServices(services);
107
108        final MockAccountTypeManager mockManager = new MockAccountTypeManager(
109                        new AccountType[] { accountType }, new AccountWithDataSet[] { account });
110        AccountTypeManager.setInstanceForTest(mockManager);
111    }
112
113    @Override
114    protected void tearDown() throws Exception {
115        ContactsApplication.injectServices(null);
116        super.tearDown();
117    }
118
119    public void testSingleAccountNoGroups() {
120
121        if (true) { // Need this to avoid "unreachable statement"
122            return; // Disabled for now.
123        }
124
125        // This two-pane UI test only makes sense if we run with two panes.
126        // Let's ignore this in the single pane case
127        if (!PhoneCapabilityTester.isUsingTwoPanes(mContext)) return;
128
129        expectSettingsQueriesAndReturnDefault();
130        expectProviderStatusQueryAndReturnNormal();
131        expectGroupsQueryAndReturnEmpty();
132        expectContactListQuery(100);
133        expectContactLookupQuery("lu1", 1, "lu1", 1);
134        expectContactEntityQuery("lu1", 1);
135
136        setActivityIntent(new Intent(Intent.ACTION_DEFAULT));
137
138        PeopleActivity activity = getActivity();
139
140        getInstrumentation().waitForIdleSync();
141
142        ContactBrowseListFragment listFragment = activity.getListFragment();
143        ContactDetailFragment detailFragment = activity.getDetailFragment();
144
145        Loader<?> filterLoader =
146                activity.getLoaderManager().getLoader(R.id.contact_list_filter_loader);
147        Loader<?> listLoader =
148                listFragment.getLoaderManager().getLoader(0);
149
150        // TODO: wait for detail loader
151        // TODO: wait for lookup key loading
152        TestLoaderManager.waitForLoaders(filterLoader, listLoader);
153
154        getInstrumentation().waitForIdleSync();
155
156        mContext.verify();
157
158        TextView nameText = (TextView) detailFragment.getView().findViewById(R.id.name);
159        assertEquals("Contact 1", nameText.getText());
160    }
161
162    private void expectSettingsQueriesAndReturnDefault() {
163        mSettingsProvider
164                .expectQuery(Settings.System.CONTENT_URI)
165                .withProjection(Settings.System.VALUE)
166                .withSelection(Settings.System.NAME + "=?",
167                        ContactsContract.Preferences.DISPLAY_ORDER)
168                .returnRow(ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY)
169                .anyNumberOfTimes();
170        mSettingsProvider
171                .expectQuery(Settings.System.CONTENT_URI)
172                .withProjection(Settings.System.VALUE)
173                .withSelection(Settings.System.NAME + "=?",
174                        ContactsContract.Preferences.SORT_ORDER)
175                .returnRow(ContactsContract.Preferences.SORT_ORDER_PRIMARY)
176                .anyNumberOfTimes();
177    }
178
179    private void expectProviderStatusQueryAndReturnNormal() {
180        mContactsProvider
181                .expectQuery(ProviderStatus.CONTENT_URI)
182                .withProjection(ProviderStatus.STATUS, ProviderStatus.DATA1)
183                .returnRow(ProviderStatus.STATUS_NORMAL, null)
184                .anyNumberOfTimes();
185    }
186
187    private void expectGroupsQueryAndReturnEmpty() {
188        mContactsProvider
189                .expectQuery(Groups.CONTENT_URI)
190                .withAnyProjection()
191                .withAnySelection()
192                .returnEmptyCursor()
193                .anyNumberOfTimes();
194    }
195
196    private void expectContactListQuery(int count) {
197        Uri uri = Contacts.CONTENT_URI.buildUpon()
198                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true")
199                .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
200                        String.valueOf(Directory.DEFAULT))
201                .build();
202
203        Query query = mContactsProvider
204                .expectQuery(uri)
205                .withAnyProjection()
206                .withSortOrder(Contacts.SORT_KEY_PRIMARY);
207        for (int i = 1; i <= count; i++) {
208            ContentValues values = new ContentValues();
209            values.put(Contacts._ID, i);
210            values.put(Contacts.DISPLAY_NAME, "Contact " + i);
211            values.put(Contacts.SORT_KEY_PRIMARY, "contact " + i);
212            values.put(Contacts.LOOKUP_KEY, "lu" + i);
213            query.returnRow(values);
214        }
215    }
216
217    private void expectContactLookupQuery(
218            String lookupKey, long id, String returnLookupKey, long returnId) {
219        Uri uri = Contacts.getLookupUri(id, lookupKey);
220        mContactsProvider.expectTypeQuery(uri, Contacts.CONTENT_ITEM_TYPE);
221        mContactsProvider
222                .expectQuery(uri)
223                .withProjection(Contacts._ID, Contacts.LOOKUP_KEY)
224                .returnRow(returnId, returnLookupKey);
225    }
226
227    private void expectContactEntityQuery(String lookupKey, int contactId) {
228        Uri uri = Uri.withAppendedPath(
229                Contacts.getLookupUri(contactId, lookupKey), Contacts.Entity.CONTENT_DIRECTORY);
230        ContentValues row1 = new ContentValues();
231        row1.put(Contacts.Entity.DATA_ID, 1);
232        row1.put(Contacts.Entity.LOOKUP_KEY, lookupKey);
233        row1.put(Contacts.Entity.CONTACT_ID, contactId);
234        row1.put(Contacts.Entity.DISPLAY_NAME, "Contact " + contactId);
235        row1.put(Contacts.Entity.ACCOUNT_NAME, TEST_ACCOUNT);
236        row1.put(Contacts.Entity.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE);
237        mContactsProvider
238                .expectQuery(uri)
239                .withAnyProjection()
240                .withAnySortOrder()
241                .returnRow(row1)
242                .anyNumberOfTimes();
243    }
244}
245