Fixing ContactBrowserActivityTest
Change-Id: Ie492eae15c7163d0f8a3577e73ae14b786709a35
diff --git a/src/com/android/contacts/ContactsActivity.java b/src/com/android/contacts/ContactsActivity.java
index 913bc4c..90a975f 100644
--- a/src/com/android/contacts/ContactsActivity.java
+++ b/src/com/android/contacts/ContactsActivity.java
@@ -16,13 +16,32 @@
package com.android.contacts;
+import com.android.contacts.test.InjectedServices;
+
import android.app.Activity;
+import android.content.ContentResolver;
/**
* A common superclass for Contacts activities that handles application-wide services.
*/
public abstract class ContactsActivity extends Activity {
+ private ContentResolver mContentResolver;
+
+ @Override
+ public ContentResolver getContentResolver() {
+ if (mContentResolver == null) {
+ InjectedServices services = ContactsApplication.getInjectedServices();
+ if (services != null) {
+ mContentResolver = services.getContentResolver();
+ }
+ if (mContentResolver == null) {
+ mContentResolver = super.getContentResolver();
+ }
+ }
+ return mContentResolver;
+ }
+
@Override
public Object getSystemService(String name) {
Object service = super.getSystemService(name);
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 268aa2f..288a3d7 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -37,6 +37,10 @@
sInjectedServices = services;
}
+ public static InjectedServices getInjectedServices() {
+ return sInjectedServices;
+ }
+
@Override
public ContentResolver getContentResolver() {
if (sInjectedServices != null) {
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index f7ab405..8bdf405 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -24,7 +24,6 @@
import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
-import android.app.ActionBar.OnNavigationListener;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
@@ -78,12 +77,17 @@
mQueryString = request.getQueryString();
}
- actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
+ if (actionBar != null) {
+ actionBar.setDisplayOptions(
+ ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
+ }
mNavigationBar = LayoutInflater.from(mContext).inflate(R.layout.navigation_bar, null);
LayoutParams layoutParams = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- actionBar.setCustomView(mNavigationBar, layoutParams);
+ if (actionBar != null) {
+ actionBar.setCustomView(mNavigationBar, layoutParams);
+ }
mFilterView = (ContactListFilterView) mNavigationBar.findViewById(R.id.filter_view);
mSearchLabel = (TextView) mNavigationBar.findViewById(R.id.search_label);
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
index 35e8e8d..4acaa92 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -21,30 +21,30 @@
import static android.content.ContentProviderOperation.TYPE_UPDATE;
import com.android.contacts.model.AccountType;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditType;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.model.EntityDeltaList;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
import com.google.android.collect.Lists;
-import android.accounts.Account;
import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
import android.os.Bundle;
-import android.provider.ContactsContract.Intents.Insert;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Intents.Insert;
+import android.provider.ContactsContract.RawContacts;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -71,31 +71,6 @@
private static final String TEST_ACCOUNT_NAME = "unittest@example.com";
private static final String TEST_ACCOUNT_TYPE = "com.example.unittest";
- private static class TestAccountTypeManager extends AccountTypeManager {
-
- private final AccountType[] mTypes;
-
- public TestAccountTypeManager(AccountType[] types) {
- this.mTypes = types;
- }
-
- @Override
- public AccountType getAccountType(String accountType) {
- for (AccountType type : mTypes) {
- if (accountType.equals(type.accountType)) {
- return type;
- }
- }
- return null;
- }
-
- @Override
- public ArrayList<Account> getAccounts(boolean writableOnly) {
- return null;
- }
-
- }
-
@Override
public void setUp() {
mContext = getContext();
@@ -170,7 +145,7 @@
* Build {@link AccountTypeManager} instance.
*/
protected AccountTypeManager getAccountTypes(AccountType... types) {
- return new TestAccountTypeManager(types);
+ return new MockAccountTypeManager(types, null);
}
/**
diff --git a/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java b/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java
index d06f910..a0c768d 100644
--- a/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java
+++ b/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java
@@ -16,14 +16,27 @@
package com.android.contacts.activities;
+import com.android.contacts.ContactsApplication;
import com.android.contacts.R;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.FallbackAccountType;
+import com.android.contacts.test.InjectedServices;
import com.android.contacts.tests.mocks.ContactsMockContext;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
import com.android.contacts.tests.mocks.MockContentProvider;
+import android.accounts.Account;
import android.content.Intent;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.ContactCounts;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Directory;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.ProviderStatus;
-import android.test.ActivityUnitTestCase;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
/**
* Tests for {@link ContactBrowserActivity}.
@@ -36,10 +49,11 @@
* -w com.android.contacts.tests/android.test.InstrumentationTestRunner
*/
public class ContactBrowserActivityTest
- extends ActivityUnitTestCase<ContactBrowserActivity>
+ extends ActivityInstrumentationTestCase2<ContactBrowserActivity>
{
private ContactsMockContext mContext;
private MockContentProvider mContactsProvider;
+ private MockContentProvider mSettingsProvider;
public ContactBrowserActivityTest() {
super(ContactBrowserActivity.class);
@@ -49,22 +63,32 @@
public void setUp() {
mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
mContactsProvider = mContext.getContactsProvider();
- setActivityContext(mContext);
+ mSettingsProvider = mContext.getSettingsProvider();
+ InjectedServices services = new InjectedServices();
+ services.setContentResolver(mContext.getContentResolver());
+
+ FallbackAccountType accountType = new FallbackAccountType();
+ accountType.accountType = "testAccountType";
+
+ Account account = new Account("testAccount", "testAccountType");
+
+ services.setSystemService(AccountTypeManager.ACCOUNT_TYPE_SERVICE,
+ new MockAccountTypeManager(
+ new AccountType[] { accountType }, new Account[] { account }));
+ ContactsApplication.injectServices(services);
}
public void testSingleAccountNoGroups() {
-
- // TODO: actually simulate a single account
-
+ expectSettingsQueriesAndReturnDefault();
expectProviderStatusQueryAndReturnNormal();
expectGroupsQueryAndReturnEmpty();
+ expectContactListAndReturnEmpty();
- Intent intent = new Intent(Intent.ACTION_DEFAULT);
+ setActivityIntent(new Intent(Intent.ACTION_DEFAULT));
- ContactBrowserActivity activity = startActivity(intent, null, null);
+ ContactBrowserActivity activity = getActivity();
- getInstrumentation().callActivityOnResume(activity);
- getInstrumentation().callActivityOnStart(activity);
+ getInstrumentation().waitForIdleSync();
mContext.waitForLoaders(activity.getLoaderManager(), R.id.contact_list_filter_loader);
@@ -73,11 +97,29 @@
mContext.verify();
}
+ private void expectSettingsQueriesAndReturnDefault() {
+ mSettingsProvider
+ .expectQuery(Settings.System.CONTENT_URI)
+ .withProjection(Settings.System.VALUE)
+ .withSelection(Settings.System.NAME + "=?",
+ ContactsContract.Preferences.DISPLAY_ORDER)
+ .returnRow(ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY)
+ .anyNumberOfTimes();
+ mSettingsProvider
+ .expectQuery(Settings.System.CONTENT_URI)
+ .withProjection(Settings.System.VALUE)
+ .withSelection(Settings.System.NAME + "=?",
+ ContactsContract.Preferences.SORT_ORDER)
+ .returnRow(ContactsContract.Preferences.SORT_ORDER_PRIMARY)
+ .anyNumberOfTimes();
+ }
+
private void expectProviderStatusQueryAndReturnNormal() {
mContactsProvider
.expectQuery(ProviderStatus.CONTENT_URI)
.withProjection(ProviderStatus.STATUS, ProviderStatus.DATA1)
- .returnRow(ProviderStatus.STATUS_NORMAL, null);
+ .returnRow(ProviderStatus.STATUS_NORMAL, null)
+ .anyNumberOfTimes();
}
private void expectGroupsQueryAndReturnEmpty() {
@@ -85,6 +127,22 @@
.expectQuery(Groups.CONTENT_URI)
.withAnyProjection()
.withAnySelection()
+ .returnEmptyCursor()
+ .anyNumberOfTimes();
+ }
+
+ private void expectContactListAndReturnEmpty() {
+ Uri uri = Contacts.CONTENT_URI.buildUpon()
+ .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true")
+ .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+ String.valueOf(Directory.DEFAULT))
+ .build();
+
+ mContactsProvider
+ .expectQuery(uri)
+ .withAnyProjection()
+ .withAnySelection()
+ .withAnySortOrder()
.returnEmptyCursor();
}
}
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index f63577b..eba60a9 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -18,7 +18,9 @@
import com.android.contacts.ContactsApplication;
import com.android.contacts.R;
+import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.FallbackAccountType;
import com.android.contacts.test.FragmentTestActivity;
import com.android.contacts.test.InjectedServices;
import com.android.contacts.tests.mocks.ContactsMockContext;
@@ -57,6 +59,9 @@
private static final Uri ENTITY_URI = Uri.withAppendedPath(
CONTACT_URI, Entity.CONTENT_DIRECTORY);
+ public static final String WRITABLE_ACCOUNT_TYPE = "writable";
+ public static final String READONLY_ACCOUNT_TYPE = "readonly";
+
private ContactsMockContext mContext;
private MockContentProvider mContactsProvider;
private ContactDeletionInteraction mFragment;
@@ -71,8 +76,17 @@
mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
InjectedServices services = new InjectedServices();
services.setContentResolver(mContext.getContentResolver());
+
+ FallbackAccountType readOnlyAccountType = new FallbackAccountType();
+ readOnlyAccountType.accountType = READONLY_ACCOUNT_TYPE;
+ readOnlyAccountType.readOnly = true;
+
+ FallbackAccountType writableAccountType = new FallbackAccountType();
+ writableAccountType.accountType = WRITABLE_ACCOUNT_TYPE;
+
services.setSystemService(AccountTypeManager.ACCOUNT_TYPE_SERVICE,
- new MockAccountTypeManager());
+ new MockAccountTypeManager(
+ new AccountType[] { writableAccountType, readOnlyAccountType }, null));
ContactsApplication.injectServices(services);
mContactsProvider = mContext.getContactsProvider();
}
@@ -84,26 +98,26 @@
}
public void testSingleWritableRawContact() {
- expectQuery().returnRow(1, MockAccountTypeManager.WRITABLE_ACCOUNT_TYPE, 13, "foo");
+ expectQuery().returnRow(1, WRITABLE_ACCOUNT_TYPE, 13, "foo");
assertWithMessageId(R.string.deleteConfirmation);
}
public void testReadOnlyRawContacts() {
- expectQuery().returnRow(1, MockAccountTypeManager.READONLY_ACCOUNT_TYPE, 13, "foo");
+ expectQuery().returnRow(1, READONLY_ACCOUNT_TYPE, 13, "foo");
assertWithMessageId(R.string.readOnlyContactWarning);
}
public void testMixOfWritableAndReadOnlyRawContacts() {
expectQuery()
- .returnRow(1, MockAccountTypeManager.WRITABLE_ACCOUNT_TYPE, 13, "foo")
- .returnRow(2, MockAccountTypeManager.READONLY_ACCOUNT_TYPE, 13, "foo");
+ .returnRow(1, WRITABLE_ACCOUNT_TYPE, 13, "foo")
+ .returnRow(2, READONLY_ACCOUNT_TYPE, 13, "foo");
assertWithMessageId(R.string.readOnlyContactDeleteConfirmation);
}
public void testMultipleWritableRawContacts() {
expectQuery()
- .returnRow(1, MockAccountTypeManager.WRITABLE_ACCOUNT_TYPE, 13, "foo")
- .returnRow(2, MockAccountTypeManager.WRITABLE_ACCOUNT_TYPE, 13, "foo");
+ .returnRow(1, WRITABLE_ACCOUNT_TYPE, 13, "foo")
+ .returnRow(2, WRITABLE_ACCOUNT_TYPE, 13, "foo");
assertWithMessageId(R.string.multipleContactDeleteConfirmation);
}
diff --git a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
index d15610b..2635a09 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
@@ -17,39 +17,37 @@
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.FallbackAccountType;
import android.accounts.Account;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* A mock {@link AccountTypeManager} class.
*/
public class MockAccountTypeManager extends AccountTypeManager {
- public static final String WRITABLE_ACCOUNT_TYPE = "writable";
- public static final String READONLY_ACCOUNT_TYPE = "readonly";
+ private final AccountType[] mTypes;
+ private Account[] mAccounts;
+
+ public MockAccountTypeManager(AccountType[] types, Account[] accounts) {
+ this.mTypes = types;
+ this.mAccounts = accounts;
+ }
@Override
public AccountType getAccountType(String accountType) {
- if (accountType.equals(WRITABLE_ACCOUNT_TYPE)) {
- AccountType source = new FallbackAccountType();
- source.readOnly = false;
- return source;
+ for (AccountType type : mTypes) {
+ if (accountType.equals(type.accountType)) {
+ return type;
+ }
}
-
- if (accountType.equals(READONLY_ACCOUNT_TYPE)) {
- AccountType source = new FallbackAccountType();
- source.readOnly = true;
- return source;
- }
-
return null;
}
@Override
public ArrayList<Account> getAccounts(boolean writableOnly) {
- throw new UnsupportedOperationException();
+ return new ArrayList<Account>(Arrays.asList(mAccounts));
}
}
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java b/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java
index 3acb52d..73414e5 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java
@@ -16,6 +16,9 @@
package com.android.contacts.tests.mocks;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
@@ -25,7 +28,8 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.LinkedList;
+import java.util.HashMap;
+import java.util.Iterator;
import junit.framework.Assert;
@@ -47,6 +51,9 @@
private boolean mAnyProjection;
private boolean mAnySelection;
private boolean mAnySortOrder;
+ private boolean mAnyNumberOfTimes;
+
+ private boolean mExecuted;
public Query(Uri uri) {
mUri = uri;
@@ -103,6 +110,11 @@
return this;
}
+ public Query anyNumberOfTimes() {
+ mAnyNumberOfTimes = true;
+ return this;
+ }
+
public boolean equals(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
if (!uri.equals(mUri)) {
@@ -199,8 +211,8 @@
}
}
- private LinkedList<Query> mExpectedQueries = new LinkedList<Query>();
- private LinkedList<TypeQuery> mExpectedTypeQueries = new LinkedList<TypeQuery>();
+ private ArrayList<Query> mExpectedQueries = new ArrayList<Query>();
+ private HashMap<Uri, String> mExpectedTypeQueries = Maps.newHashMap();
@Override
public boolean onCreate() {
@@ -209,30 +221,42 @@
public Query expectQuery(Uri contentUri) {
Query query = new Query(contentUri);
- mExpectedQueries.offer(query);
+ mExpectedQueries.add(query);
return query;
}
public void expectTypeQuery(Uri uri, String type) {
- TypeQuery result = new TypeQuery(uri, type);
- mExpectedTypeQueries.offer(result);
+ mExpectedTypeQueries.put(uri, type);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
+
+ for (Iterator<Query> iterator = mExpectedQueries.iterator(); iterator.hasNext();) {
+ Query query = iterator.next();
+ if (query.equals(uri, projection, selection, selectionArgs, sortOrder)) {
+ query.mExecuted = true;
+ if (!query.mAnyNumberOfTimes) {
+ iterator.remove();
+ }
+ return query.getResult();
+ }
+ }
+
if (mExpectedQueries.isEmpty()) {
Assert.fail("Unexpected query: "
+ queryToString(uri, projection, selection, selectionArgs, sortOrder));
- }
-
- Query query = mExpectedQueries.remove();
- if (!query.equals(uri, projection, selection, selectionArgs, sortOrder)) {
- Assert.fail("Incorrect query.\n Expected: " + query + "\n Actual: " +
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(mExpectedQueries.get(0));
+ for (int i = 1; i < mExpectedQueries.size(); i++) {
+ sb.append("\n ").append(mExpectedQueries.get(i));
+ }
+ Assert.fail("Incorrect query.\n Expected: " + sb + "\n Actual: " +
queryToString(uri, projection, selection, selectionArgs, sortOrder));
}
-
- return query.getResult();
+ return null;
}
@Override
@@ -246,12 +270,13 @@
Assert.fail("Unexpected getType query: " + uri);
}
- TypeQuery query = mExpectedTypeQueries.remove();
- if (!query.equals(uri)) {
- Assert.fail("Incorrect query.\n Expected: " + query + "\n Actual: " + uri);
+ String mimeType = mExpectedTypeQueries.get(uri);
+ if (mimeType != null) {
+ return mimeType;
}
- return query.getType();
+ Assert.fail("Unknown mime type for: " + uri);
+ return null;
}
@Override
@@ -288,9 +313,13 @@
}
public void verify() {
+ ArrayList<Query> mMissedQueries = Lists.newArrayList();
+ for (Query query : mExpectedQueries) {
+ if (!query.mExecuted) {
+ mMissedQueries.add(query);
+ }
+ }
Assert.assertTrue("Not all expected queries have been called: " +
- mExpectedQueries, mExpectedQueries.isEmpty());
- Assert.assertTrue("Not all expected getType-queries have been called: " +
- mExpectedQueries, mExpectedTypeQueries.isEmpty());
+ mMissedQueries, mMissedQueries.isEmpty());
}
}