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.interactions;
18
19import android.content.ContentUris;
20import android.net.Uri;
21import android.os.AsyncTask;
22import android.provider.ContactsContract.Contacts;
23import android.provider.ContactsContract.Contacts.Entity;
24import android.test.ActivityInstrumentationTestCase2;
25import android.test.suitebuilder.annotation.SmallTest;
26
27import com.android.contacts.ContactsApplication;
28import com.android.contacts.R;
29import com.android.contacts.common.test.FragmentTestActivity;
30import com.android.contacts.common.test.IntegrationTestUtils;
31import com.android.contacts.common.test.mocks.ContactsMockContext;
32import com.android.contacts.common.test.mocks.MockContentProvider;
33import com.android.contacts.common.test.mocks.MockContentProvider.Query;
34import com.android.contacts.common.model.AccountTypeManager;
35import com.android.contacts.common.model.account.AccountType;
36import com.android.contacts.common.model.account.BaseAccountType;
37import com.android.contacts.test.InjectedServices;
38import com.android.contacts.tests.mocks.MockAccountTypeManager;
39
40/**
41 * Tests for {@link ContactDeletionInteraction}.
42 *
43 * Running all tests:
44 *
45 *   runtest contacts
46 * or
47 *   adb shell am instrument \
48 *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
49 */
50@SmallTest
51public class ContactDeletionInteractionTest
52        extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
53
54    static {
55        // AsyncTask class needs to be initialized on the main thread.
56        AsyncTask.init();
57    }
58
59    private static final Uri CONTACT_URI = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
60    private static final Uri ENTITY_URI = Uri.withAppendedPath(
61            CONTACT_URI, Entity.CONTENT_DIRECTORY);
62
63    public static final String WRITABLE_ACCOUNT_TYPE = "writable";
64    public static final String READONLY_ACCOUNT_TYPE = "readonly";
65
66    private ContactsMockContext mContext;
67    private MockContentProvider mContactsProvider;
68    private ContactDeletionInteraction mFragment;
69    private IntegrationTestUtils mUtils;
70
71    public ContactDeletionInteractionTest() {
72        super(FragmentTestActivity.class);
73    }
74
75    @Override
76    protected void setUp() throws Exception {
77        super.setUp();
78        // This test requires that the screen be turned on.
79        mUtils = new IntegrationTestUtils(getInstrumentation());
80        mUtils.acquireScreenWakeLock(getInstrumentation().getTargetContext());
81
82        mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
83        InjectedServices services = new InjectedServices();
84        services.setContentResolver(mContext.getContentResolver());
85
86        AccountType readOnlyAccountType = new BaseAccountType() {
87            @Override
88            public boolean areContactsWritable() {
89                return false;
90            }
91        };
92        readOnlyAccountType.accountType = READONLY_ACCOUNT_TYPE;
93
94        AccountType writableAccountType = new BaseAccountType() {
95            @Override
96            public boolean areContactsWritable() {
97                return true;
98            }
99        };
100        writableAccountType.accountType = WRITABLE_ACCOUNT_TYPE;
101        ContactsApplication.injectServices(services);
102
103        final MockAccountTypeManager mockManager = new MockAccountTypeManager(
104                new AccountType[] { writableAccountType, readOnlyAccountType }, null);
105        AccountTypeManager.setInstanceForTest(mockManager);
106        mContactsProvider = mContext.getContactsProvider();
107    }
108
109    @Override
110    protected void tearDown() throws Exception {
111        ContactsApplication.injectServices(null);
112        mUtils.releaseScreenWakeLock();
113        super.tearDown();
114    }
115
116    public void testSingleWritableRawContact() {
117        expectQuery().returnRow(1, WRITABLE_ACCOUNT_TYPE, null, 13, "foo");
118        assertWithMessageId(R.string.deleteConfirmation);
119    }
120
121    public void testReadOnlyRawContacts() {
122        expectQuery().returnRow(1, READONLY_ACCOUNT_TYPE, null, 13, "foo");
123        assertWithMessageId(R.string.readOnlyContactWarning);
124    }
125
126    public void testMixOfWritableAndReadOnlyRawContacts() {
127        expectQuery()
128                .returnRow(1, WRITABLE_ACCOUNT_TYPE, null, 13, "foo")
129                .returnRow(2, READONLY_ACCOUNT_TYPE, null, 13, "foo");
130        assertWithMessageId(R.string.readOnlyContactDeleteConfirmation);
131    }
132
133    public void testMultipleWritableRawContacts() {
134        expectQuery()
135                .returnRow(1, WRITABLE_ACCOUNT_TYPE, null, 13, "foo")
136                .returnRow(2, WRITABLE_ACCOUNT_TYPE, null, 13, "foo");
137        assertWithMessageId(R.string.multipleContactDeleteConfirmation);
138    }
139
140    private Query expectQuery() {
141        return mContactsProvider.expectQuery(ENTITY_URI).withProjection(
142                Entity.RAW_CONTACT_ID, Entity.ACCOUNT_TYPE, Entity.DATA_SET, Entity.CONTACT_ID,
143                Entity.LOOKUP_KEY);
144    }
145
146    private void assertWithMessageId(int messageId) {
147        final FragmentTestActivity activity = getActivity();
148
149        final TestLoaderManager mockLoaderManager = new TestLoaderManager();
150        getInstrumentation().runOnMainSync(new Runnable() {
151            @Override
152            public void run() {
153                mFragment = ContactDeletionInteraction.startWithTestLoaderManager(
154                        activity, CONTACT_URI, false, mockLoaderManager);
155            }
156        });
157
158        getInstrumentation().waitForIdleSync();
159
160        mockLoaderManager.waitForLoaders(R.id.dialog_delete_contact_loader_id);
161
162        getInstrumentation().waitForIdleSync();
163
164        mContext.verify();
165
166        assertEquals(messageId, mFragment.mMessageId);
167    }
168}
169