Add device and SIM to AccountTypeManager
This makes these account types available throughout the app rather than
just the Nav drawer.
Test:
Added unit tests for new classes; run with:
$ adb shell am instrument -w \
com.google.android.tests/android.test.InstrumentationTestRunner
Manually on Nexus 6, LG G5 and Samsung S7 with device and SIM contacts
in CP2 by verifying "Device" and "SIM" options were available in
* nav drawer
* account list accessed by Pressing FAB without default account set
* editor account dropdown for new contact
* editor account label when editing existing contact
* picker for default account in settings
* settings customize screen account list
Bug 30867780
Change-Id: I329381ccc58d59f2e27f65a3d9dc0164fb20c971
diff --git a/tests/src/com/android/contacts/common/model/AccountWithDataSetTest.java b/tests/src/com/android/contacts/common/model/AccountWithDataSetTest.java
index e28f09e..7bfb922 100644
--- a/tests/src/com/android/contacts/common/model/AccountWithDataSetTest.java
+++ b/tests/src/com/android/contacts/common/model/AccountWithDataSetTest.java
@@ -58,6 +58,14 @@
MoreAsserts.assertNotEqual(a3, a2r);
}
+ public void testStringifyAndUnstringifyLocalAccount() {
+ final String stringified = AccountWithDataSet.getLocalAccount().stringify();
+
+ final AccountWithDataSet restored = AccountWithDataSet.unstringify(stringified);
+
+ assertEquals(AccountWithDataSet.getLocalAccount(), restored);
+ }
+
public void testStringifyListAndUnstringify() {
AccountWithDataSet a1 = new AccountWithDataSet("name1", "typeA", null);
AccountWithDataSet a2 = new AccountWithDataSet("name2", "typeB", null);
diff --git a/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java b/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java
new file mode 100644
index 0000000..e03c3e5
--- /dev/null
+++ b/tests/src/com/android/contacts/common/model/DeviceLocalAccountLocatorTests.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.common.model;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.CancellationSignal;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.RawContacts;
+import android.support.annotation.Nullable;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.contacts.common.model.DeviceLocalAccountLocator;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.test.mocks.MockContentProvider;
+import com.android.contacts.common.util.DeviceLocalAccountTypeFactory;
+import com.android.contacts.tests.FakeDeviceAccountTypeFactory;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+@SmallTest
+public class DeviceLocalAccountLocatorTests extends AndroidTestCase {
+
+ // Basic smoke test that just checks that it doesn't throw when loading from CP2. We don't
+ // care what CP2 actually contains for this.
+ public void testShouldNotCrash() {
+ final DeviceLocalAccountLocator sut = new DeviceLocalAccountLocator(
+ getContext().getContentResolver(),
+ new DeviceLocalAccountTypeFactory.Default(getContext()),
+ Collections.<AccountWithDataSet>emptyList());
+ sut.getDeviceLocalAccounts();
+ // We didn't throw so it passed
+ }
+
+ public void test_getDeviceLocalAccounts_returnsEmptyListWhenNoRawContactsHaveDeviceType() {
+ final DeviceLocalAccountLocator sut = createWithQueryResult(queryResult(
+ "user", "com.example",
+ "user", "com.example",
+ "user", "com.example"));
+ assertTrue(sut.getDeviceLocalAccounts().isEmpty());
+ }
+
+ public void test_getDeviceLocalAccounts_returnsListWithItemForNullAccount() {
+ final DeviceLocalAccountLocator sut = createWithQueryResult(queryResult(
+ "user", "com.example",
+ null, null,
+ "user", "com.example",
+ null, null));
+
+ assertEquals(1, sut.getDeviceLocalAccounts().size());
+ }
+
+ public void test_getDeviceLocalAccounts_containsItemForEachDeviceAccount() {
+ final DeviceLocalAccountTypeFactory stubFactory = new FakeDeviceAccountTypeFactory()
+ .withDeviceTypes(null, "vnd.sec.contact.phone")
+ .withSimTypes("vnd.sec.contact.sim");
+ final DeviceLocalAccountLocator sut = new DeviceLocalAccountLocator(
+ createStubResolverWithContentQueryResult(queryResult(
+ "user", "com.example",
+ "user", "com.example",
+ "phone_account", "vnd.sec.contact.phone",
+ null, null,
+ "phone_account", "vnd.sec.contact.phone",
+ "user", "com.example",
+ null, null,
+ "sim_account", "vnd.sec.contact.sim",
+ "sim_account_2", "vnd.sec.contact.sim"
+ )), stubFactory,
+ Collections.<AccountWithDataSet>emptyList());
+
+ assertEquals(4, sut.getDeviceLocalAccounts().size());
+ }
+
+ public void test_getDeviceLocalAccounts_doesNotContainItemsForKnownAccounts() {
+ final DeviceLocalAccountLocator sut = new DeviceLocalAccountLocator(
+ getContext().getContentResolver(), new FakeDeviceAccountTypeFactory(),
+ Arrays.asList(new AccountWithDataSet("user", "com.example", null),
+ new AccountWithDataSet("user1", "com.example", null),
+ new AccountWithDataSet("user", "com.example.1", null)));
+
+ assertTrue("Selection should filter known accounts", sut.getSelection().contains("NOT IN (?,?)"));
+
+ final List<String> args = Arrays.asList(sut.getSelectionArgs());
+ assertEquals(2, args.size());
+ assertTrue("Selection args is missing an expected value", args.contains("com.example"));
+ assertTrue("Selection args is missing an expected value", args.contains("com.example.1"));
+ }
+
+ private DeviceLocalAccountLocator createWithQueryResult(
+ Cursor cursor) {
+ final DeviceLocalAccountLocator locator = new DeviceLocalAccountLocator(
+ createStubResolverWithContentQueryResult(cursor),
+ new DeviceLocalAccountTypeFactory.Default(getContext()),
+ Collections.<AccountWithDataSet>emptyList());
+ return locator;
+ }
+
+
+ private ContentResolver createStubResolverWithContentQueryResult(Cursor cursor) {
+ final MockContentResolver resolver = new MockContentResolver();
+ resolver.addProvider(ContactsContract.AUTHORITY, new FakeContactsProvider(cursor));
+ return resolver;
+ }
+
+ private Cursor queryResult(String... nameTypePairs) {
+ final MatrixCursor cursor = new MatrixCursor(new String[]
+ { RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE, RawContacts.DATA_SET });
+ for (int i = 0; i < nameTypePairs.length; i+=2) {
+ cursor.newRow().add(nameTypePairs[i]).add(nameTypePairs[i+1])
+ .add(null);
+ }
+ return cursor;
+ }
+
+ private static class FakeContactsProvider extends MockContentProvider {
+ public Cursor mNextQueryResult;
+
+ public FakeContactsProvider() {}
+
+ public FakeContactsProvider(Cursor result) {
+ mNextQueryResult = result;
+ }
+
+ public void setNextQueryResult(Cursor result) {
+ mNextQueryResult = result;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return query(uri, projection, selection, selectionArgs, sortOrder, null);
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder, CancellationSignal cancellationSignal) {
+ return mNextQueryResult;
+ }
+ }
+}
diff --git a/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java b/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java
index 26e811d..bbbd65c 100644
--- a/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java
+++ b/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java
@@ -142,9 +142,11 @@
.thenReturn(new AccountWithDataSet("name1", "type1", "dataset1").stringify(),
new AccountWithDataSet("name2", "type2", "dataset2").stringify());
- Assert.assertEquals("name1", mContactsPreferences.getDefaultAccount());
+ Assert.assertEquals(new AccountWithDataSet("name1", "type1", "dataset1"),
+ mContactsPreferences.getDefaultAccount());
mContactsPreferences.refreshValue(ACCOUNT_KEY);
- Assert.assertEquals("name2", mContactsPreferences.getDefaultAccount());
+ Assert.assertEquals(new AccountWithDataSet("name2", "type2", "dataset2"),
+ mContactsPreferences.getDefaultAccount());
}
}
diff --git a/tests/src/com/android/contacts/common/util/DeviceLocalContactsFilterProviderTests.java b/tests/src/com/android/contacts/common/util/DeviceLocalContactsFilterProviderTests.java
deleted file mode 100644
index d776ab8..0000000
--- a/tests/src/com/android/contacts/common/util/DeviceLocalContactsFilterProviderTests.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.contacts.common.util;
-
-import android.content.ContentProvider;
-import android.content.Context;
-import android.content.CursorLoader;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.CancellationSignal;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.RawContacts;
-import android.support.annotation.Nullable;
-import android.test.LoaderTestCase;
-import android.test.mock.MockContentResolver;
-import android.test.mock.MockContext;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.common.test.mocks.MockContentProvider;
-
-import org.mockito.Mockito;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import static org.mockito.Mockito.when;
-
-@SmallTest
-public class DeviceLocalContactsFilterProviderTests extends LoaderTestCase {
-
- // Basic smoke test that just checks that it doesn't throw when loading from CP2. We don't
- // care what CP2 actually contains for this.
- public void testShouldNotCrash() {
- final DeviceLocalContactsFilterProvider sut = new DeviceLocalContactsFilterProvider(
- getContext(), DeviceAccountFilter.ONLY_NULL);
- final CursorLoader loader = sut.onCreateLoader(0, null);
- getLoaderResultSynchronously(loader);
- // We didn't throw so it passed
- }
-
- public void testCreatesNoFiltersIfNoRawContactsHaveDeviceAccountType() {
- final DeviceLocalContactsFilterProvider sut = createWithFilterAndLoaderResult(
- DeviceAccountFilter.ONLY_NULL, queryResult(
- "user", "com.example",
- "user", "com.example",
- "user", "com.example"));
- sut.setKnownAccountTypes("com.example");
-
- doLoad(sut);
-
- assertEquals(0, sut.getListFilters().size());
- }
-
- public void testCreatesOneFilterForDeviceAccount() {
- final DeviceLocalContactsFilterProvider sut = createWithFilterAndLoaderResult(
- DeviceAccountFilter.ONLY_NULL, queryResult(
- "user", "com.example",
- "user", "com.example",
- null, null,
- "user", "com.example",
- null, null));
- sut.setKnownAccountTypes("com.example");
-
- doLoad(sut);
-
- assertEquals(1, sut.getListFilters().size());
- assertEquals(ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS,
- sut.getListFilters().get(0).filterType);
- }
-
- public void testCreatesOneFilterForEachDeviceAccount() {
- final DeviceLocalContactsFilterProvider sut = createWithFilterAndLoaderResult(
- filterAllowing(null, "vnd.sec.contact.phone", "vnd.sec.contact.sim"), queryResult(
- "sim_account", "vnd.sec.contact.sim",
- "user", "com.example",
- "user", "com.example",
- "phone_account", "vnd.sec.contact.phone",
- null, null,
- "phone_account", "vnd.sec.contact.phone",
- "user", "com.example",
- null, null,
- "sim_account", "vnd.sec.contact.sim",
- "sim_account_2", "vnd.sec.contact.sim"
- ));
- sut.setKnownAccountTypes("com.example");
-
- doLoad(sut);
-
- assertEquals(4, sut.getListFilters().size());
- }
-
- public void testFilterIsUpdatedWhenLoaderReloads() {
- final FakeContactsProvider provider = new FakeContactsProvider();
- final DeviceLocalContactsFilterProvider sut = new DeviceLocalContactsFilterProvider(
- createStubContextWithContactsProvider(provider), DeviceAccountFilter.ONLY_NULL);
- sut.setKnownAccountTypes("com.example");
-
- provider.setNextQueryResult(queryResult(
- null, null,
- "user", "com.example",
- "user", "com.example"
- ));
- doLoad(sut);
-
- assertFalse(sut.getListFilters().isEmpty());
-
- provider.setNextQueryResult(queryResult(
- "user", "com.example",
- "user", "com.example"
- ));
- doLoad(sut);
-
- assertTrue(sut.getListFilters().isEmpty());
- }
-
- public void testDoesNotCreateFiltersForKnownAccounts() {
- final DeviceLocalContactsFilterProvider sut = new DeviceLocalContactsFilterProvider(
- getContext(), DeviceAccountFilter.ONLY_NULL);
- sut.setKnownAccountTypes("com.example", "maybe_syncable_device_account_type");
-
- final CursorLoader loader = sut.onCreateLoader(0, null);
-
- // The filtering is done at the DB level rather than in the code so just verify that
- // selection is about right.
- assertTrue("Loader selection is wrong", loader.getSelection().contains("NOT IN (?,?)"));
- assertEquals("com.example", loader.getSelectionArgs()[0]);
- assertEquals("maybe_syncable_device_account_type", loader.getSelectionArgs()[1]);
- }
-
- private void doLoad(DeviceLocalContactsFilterProvider loaderCallbacks) {
- final CursorLoader loader = loaderCallbacks.onCreateLoader(0, null);
- final Cursor cursor = getLoaderResultSynchronously(loader);
- loaderCallbacks.onLoadFinished(loader, cursor);
- }
-
- private DeviceLocalContactsFilterProvider createWithFilterAndLoaderResult(
- DeviceAccountFilter filter, Cursor cursor) {
- final DeviceLocalContactsFilterProvider result = new DeviceLocalContactsFilterProvider(
- createStubContextWithContentQueryResult(cursor), filter);
- return result;
- }
-
- private Context createStubContextWithContentQueryResult(final Cursor cursor) {
- return createStubContextWithContactsProvider(new FakeContactsProvider(cursor));
- }
-
- private Context createStubContextWithContactsProvider(ContentProvider contactsProvider) {
- final MockContentResolver resolver = new MockContentResolver();
- resolver.addProvider(ContactsContract.AUTHORITY, contactsProvider);
-
- final Context context = Mockito.mock(MockContext.class);
- when(context.getContentResolver()).thenReturn(resolver);
-
- // The loader pulls out the application context instead of usign the context directly
- when(context.getApplicationContext()).thenReturn(context);
-
- return context;
- }
-
- private Cursor queryResult(String... typeNamePairs) {
- final MatrixCursor cursor = new MatrixCursor(new String[]
- { RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE });
- for (int i = 0; i < typeNamePairs.length; i += 2) {
- cursor.newRow().add(typeNamePairs[i]).add(typeNamePairs[i+1]);
- }
- return cursor;
- }
-
- private DeviceAccountFilter filterAllowing(String... accountTypes) {
- final Set<String> allowed = new HashSet<>(Arrays.asList(accountTypes));
- return new DeviceAccountFilter() {
- @Override
- public boolean isDeviceAccountType(String accountType) {
- return allowed.contains(accountType);
- }
- };
- }
-
- private static class FakeContactsProvider extends MockContentProvider {
- public Cursor mNextQueryResult;
-
- public FakeContactsProvider() {}
-
- public FakeContactsProvider(Cursor result) {
- mNextQueryResult = result;
- }
-
- public void setNextQueryResult(Cursor result) {
- mNextQueryResult = result;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return query(uri, projection, selection, selectionArgs, sortOrder, null);
- }
-
- @Nullable
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder, CancellationSignal cancellationSignal) {
- return mNextQueryResult;
- }
- }
-}
diff --git a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
index 2e0306a..b5df8c9 100644
--- a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
+++ b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
@@ -272,7 +272,7 @@
assertTrue(mTarget.shouldShowAccountChangedNotification());
// We show the notification here, and user clicked "keep local" and saved an contact.
- mTarget.saveDefaultAndAllAccounts(null);
+ mTarget.saveDefaultAndAllAccounts(AccountWithDataSet.getLocalAccount());
// Now there are no accounts, and default account is null.
diff --git a/tests/src/com/android/contacts/editor/EditorUiUtilsTest.java b/tests/src/com/android/contacts/editor/EditorUiUtilsTest.java
index 19f28d3..e68511f 100644
--- a/tests/src/com/android/contacts/editor/EditorUiUtilsTest.java
+++ b/tests/src/com/android/contacts/editor/EditorUiUtilsTest.java
@@ -16,10 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.GoogleAccountType;
-
import android.content.Context;
import android.media.RingtoneManager;
import android.net.Uri;
@@ -27,7 +23,11 @@
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Pair;
+
+import com.android.contacts.common.model.account.AccountDisplayInfo;
+import com.android.contacts.R;
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.AccountWithDataSet;
/**
* Tests {@link EditorUiUtils}.
@@ -43,6 +43,11 @@
private static final String RINGTONE = "content://media/external/audio/media/31";
+ private static final AccountWithDataSet ACCOUNT =
+ new AccountWithDataSet(ACCOUNT_NAME, "some.account.type", null);
+ private static final AccountWithDataSet GOOGLE_ACCOUNT =
+ new AccountWithDataSet(ACCOUNT_NAME, "com.google", null);
+
private static final class MockAccountType extends AccountType {
private final String mDisplayLabel;
@@ -67,86 +72,65 @@
}
}
- public void testGetProfileAccountInfo_AccountName() {
- final Pair pair = EditorUiUtils.getLocalAccountInfo(getContext(),
- ACCOUNT_NAME, new MockAccountType(DISPLAY_LABEL));
+ public void testGetProfileAccountInfo_NonLocalAccount() {
+ final AccountDisplayInfo account = new AccountDisplayInfo(ACCOUNT, ACCOUNT_NAME,
+ DISPLAY_LABEL, /*icon*/ null, /*isDeviceAccount*/ false);
- assertNotNull(pair);
- assertEquals(ACCOUNT_NAME, pair.first);
- assertEquals(getContext().getString(R.string.external_profile_title, DISPLAY_LABEL),
- pair.second); // My LunkedIn profile
+ final String label = EditorUiUtils.getAccountHeaderLabelForMyProfile(getContext(),
+ account);
+
+ // My LunkedIn profile
+ final String expected = getContext()
+ .getString(R.string.external_profile_title, DISPLAY_LABEL);
+ assertEquals(expected, label);
}
- public void testGetProfileAccountInfo_NoAccountName() {
- final Pair pair = EditorUiUtils.getLocalAccountInfo(getContext(),
- /* accountName =*/ null, new MockAccountType(DISPLAY_LABEL));
- assertNotNull(pair);
- assertNull(pair.first);
- assertEquals(getContext().getString(R.string.local_profile_title),
- pair.second); // "My local profile
+ public void testGetProfileAccountInfo_DeviceLocalAccount() {
+ final AccountDisplayInfo account = new AccountDisplayInfo(ACCOUNT, "Device",
+ "Device", null, true);
+
+ final String label = EditorUiUtils.getAccountHeaderLabelForMyProfile(getContext(),
+ account);
+
+ // "My local profile"
+ final String expected = getContext().getString(R.string.local_profile_title);
+ assertEquals(expected, label);
}
- public void testGetAccountInfo_AccountName_DisplayLabel() {
- final Pair pair = EditorUiUtils.getAccountInfo(getContext(),
- ACCOUNT_NAME, new MockAccountType(DISPLAY_LABEL));
+ public void testGetAccountInfo_AccountType_NonGoogle() {
+ final AccountDisplayInfo account = new AccountDisplayInfo(ACCOUNT, ACCOUNT_NAME,
+ DISPLAY_LABEL, /*icon*/ null, /*isDeviceAccount*/ false);
- assertNotNull(pair);
- assertEquals(getContext().getString(R.string.from_account_format, ACCOUNT_NAME),
- pair.first); // somebody@lunkedin.com
- assertEquals(getContext().getString(R.string.account_type_format, DISPLAY_LABEL),
- pair.second); // LunkedIn Contact
+ final String label = EditorUiUtils.getAccountTypeHeaderLabel(getContext(), account);
+
+ // LunkedIn Contact
+ final String expected = getContext().getString(R.string.account_type_format, DISPLAY_LABEL);
+ assertEquals(expected, label);
}
- public void testGetAccountInfo_AccountName_DisplayLabel_GoogleAccountType() {
- final AccountType accountType = new MockAccountType(GOOGLE_DISPLAY_LABEL);
- accountType.accountType = GoogleAccountType.ACCOUNT_TYPE;
- final Pair pair = EditorUiUtils.getAccountInfo(getContext(),
- GOOGLE_ACCOUNT_NAME, accountType);
+ public void testGetAccountInfo_AccountType_Google() {
+ final AccountDisplayInfo account = new AccountDisplayInfo(GOOGLE_ACCOUNT, ACCOUNT_NAME,
+ GOOGLE_DISPLAY_LABEL, /*icon*/ null, /*isDeviceAccount*/ false);
- assertNotNull(pair);
- assertEquals(getContext().getString(R.string.from_account_format, GOOGLE_ACCOUNT_NAME),
- pair.first); // somebody@gmail.com
- assertEquals(
- getContext().getString(R.string.google_account_type_format, GOOGLE_DISPLAY_LABEL),
- pair.second); // Google Account
+ final String label = EditorUiUtils.getAccountTypeHeaderLabel(getContext(), account);
+
+ // Google Account
+ final String expected = getContext().getString(R.string.google_account_type_format,
+ GOOGLE_DISPLAY_LABEL);
+ assertEquals(expected, label);
}
- public void testGetAccountInfo_AccountName_NoDisplayLabel() {
- final Pair pair = EditorUiUtils.getAccountInfo(getContext(),
- ACCOUNT_NAME, new MockAccountType(/* displayLabel =*/ null));
+ public void testGetAccountInfo_AccountType_DeviceAccount() {
+ final AccountWithDataSet deviceAccount = AccountWithDataSet.getLocalAccount();
+ final AccountDisplayInfo account = new AccountDisplayInfo(deviceAccount, "Device",
+ "Device", /*icon*/ null, /*isDeviceAccount*/ true);
- assertNotNull(pair);
- assertEquals(getContext().getString(R.string.from_account_format, ACCOUNT_NAME),
- pair.first); // somebody@lunkedin.com
- assertEquals(getContext().getString(R.string.account_phone), pair.second); // Device
- }
+ final String label = EditorUiUtils.getAccountTypeHeaderLabel(getContext(), account);
- public void testGetAccountInfo_NoAccountName_DisplayLabel() {
- final Pair pair = EditorUiUtils.getAccountInfo(getContext(),
- /* accountName =*/ null, new MockAccountType(DISPLAY_LABEL));
-
- assertNotNull(pair);
- assertNull(pair.first);
- assertEquals(getContext().getString(R.string.account_type_format, DISPLAY_LABEL),
- pair.second); // LunkedIn contact
-
- final Pair pairDevice = EditorUiUtils.getAccountInfo(
- getContext(),
- /* accountName =*/ null,
- new MockAccountType(getContext().getString(R.string.account_phone)));
- assertNotNull(pairDevice);
- assertNull(pairDevice.first);
- assertEquals(getContext().getString(R.string.account_phone), pairDevice.second); // Device
- }
-
- public void testGetAccountInfo_NoAccountName_NoDisplayLabel() {
- final Pair pair = EditorUiUtils.getAccountInfo(getContext(),
- /* accountName =*/ null, new MockAccountType(/* displayLabel =*/ null));
-
- assertNotNull(pair);
- assertNull(pair.first);
- assertEquals(getContext().getString(R.string.account_phone), pair.second); // Device
+ // "Device"
+ final String expected = getContext().getString(R.string.account_phone);
+ assertEquals(expected, label);
}
public void testGetRingtongStrFromUri_lessThanOrEqualsToM() {
@@ -185,4 +169,8 @@
currentVersion));
}
+ private AccountDisplayInfo createDisplayableAccount() {
+ return new AccountDisplayInfo(ACCOUNT, ACCOUNT_NAME, DISPLAY_LABEL, null, false);
+ }
+
}
diff --git a/tests/src/com/android/contacts/tests/FakeAccountType.java b/tests/src/com/android/contacts/tests/FakeAccountType.java
new file mode 100644
index 0000000..59327d8
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/FakeAccountType.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.tests;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+
+public class FakeAccountType extends AccountType {
+ public boolean areContactsWritable = false;
+ public boolean isGroupMembershipEditable = false;
+ public String displayLabel = "The Default Label";
+ public Drawable displayIcon = new Drawable() {
+ @Override
+ public void draw(Canvas canvas) {
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.OPAQUE;
+ }
+ };
+
+ public FakeAccountType() {
+ }
+
+ public FakeAccountType(String type) {
+ accountType = type;
+ }
+
+ @Override
+ public Drawable getDisplayIcon(Context context) {
+ return displayIcon;
+ }
+
+ @Override
+ public String getDisplayLabel(Context context) {
+ return displayLabel;
+ }
+
+ @Override
+ public boolean areContactsWritable() {
+ return areContactsWritable;
+ }
+
+ @Override
+ public boolean isGroupMembershipEditable() {
+ return isGroupMembershipEditable;
+ }
+
+ public static FakeAccountType create(String accountType, String label) {
+ final FakeAccountType result = new FakeAccountType();
+ result.accountType = accountType;
+ result.displayLabel = label;
+ return result;
+ }
+
+ public static FakeAccountType create(String accountType, String label, Drawable icon) {
+ final FakeAccountType result = new FakeAccountType();
+ result.accountType = accountType;
+ result.displayIcon = icon;
+ result.displayLabel = label;
+ return result;
+ }
+
+ public static AccountType create(AccountWithDataSet account, String label, Drawable icon) {
+ final FakeAccountType result = create(account.type, label, icon);
+ result.accountType = account.type;
+ result.dataSet = account.dataSet;
+ return result;
+ }
+}
diff --git a/tests/src/com/android/contacts/tests/FakeDeviceAccountTypeFactory.java b/tests/src/com/android/contacts/tests/FakeDeviceAccountTypeFactory.java
new file mode 100644
index 0000000..6a500ec
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/FakeDeviceAccountTypeFactory.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.tests;
+
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.FallbackAccountType;
+import com.android.contacts.common.util.DeviceLocalAccountTypeFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class FakeDeviceAccountTypeFactory implements DeviceLocalAccountTypeFactory {
+
+ private final Map<String, AccountType> mDeviceAccountTypes = new HashMap<>();
+ private final Map<String, AccountType> mSimAccountTypes = new HashMap<>();
+
+ @Override
+ public int classifyAccount(String accountType) {
+ if (mDeviceAccountTypes.containsKey(accountType)) {
+ return TYPE_DEVICE;
+ } else if (mSimAccountTypes.containsKey(accountType)) {
+ return TYPE_SIM;
+ } else {
+ return TYPE_OTHER;
+ }
+ }
+
+ @Override
+ public AccountType getAccountType(String accountType) {
+ final AccountType type = mDeviceAccountTypes.get(accountType);
+ return type == null ? mSimAccountTypes.get(accountType) : type;
+ }
+
+ public FakeDeviceAccountTypeFactory withSimTypes(String... types) {
+ for (String type : types) {
+ mSimAccountTypes.put(type, new FakeAccountType(type));
+ }
+ return this;
+ }
+
+ public FakeDeviceAccountTypeFactory withSimTypes(AccountType... types) {
+ for (AccountType type : types) {
+ mSimAccountTypes.put(type.accountType, type);
+ }
+ return this;
+ }
+
+ public FakeDeviceAccountTypeFactory withDeviceTypes(String... types) {
+ for (String type : types) {
+ mDeviceAccountTypes.put(type, new FakeAccountType(type));
+ }
+ return this;
+ }
+
+ public FakeDeviceAccountTypeFactory withDeviceTypes(AccountType... types) {
+ for (AccountType type : types) {
+ mDeviceAccountTypes.put(type.accountType, type);
+ }
+ return this;
+ }
+}
diff --git a/tests/src/com/android/contacts/util/AccountDisplayInfoFactoryTests.java b/tests/src/com/android/contacts/util/AccountDisplayInfoFactoryTests.java
new file mode 100644
index 0000000..875f40e
--- /dev/null
+++ b/tests/src/com/android/contacts/util/AccountDisplayInfoFactoryTests.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.util;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.account.AccountDisplayInfo;
+import com.android.contacts.common.model.account.AccountDisplayInfoFactory;
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.test.mocks.MockAccountTypeManager;
+import com.android.contacts.common.util.DeviceLocalAccountTypeFactory;
+import com.android.contacts.tests.FakeAccountType;
+import com.android.contacts.tests.FakeDeviceAccountTypeFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+@SmallTest
+public class AccountDisplayInfoFactoryTests extends AndroidTestCase {
+
+ private Map<AccountWithDataSet, AccountType> mKnownTypes;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mKnownTypes = new HashMap<>();
+ }
+
+ public void test_displayableAccount_hasIconFromAccountType() {
+ final Drawable comExampleIcon = someDrawable();
+
+ addTypeMapping(account("user", "com.example"), "title", comExampleIcon);
+ addTypeMapping(account(null, null), "device", someDrawable());
+ addTypeMapping(account("foo", "bar.type"), "bar", someDrawable());
+ addTypeMapping(account("user2", "com.example"), "title", comExampleIcon);
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes();
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account("user", "com.example"));
+ assertEquals(comExampleIcon, displayable.getIcon());
+ }
+
+ public void test_displayableAccount_hasNameFromAccount() {
+ final Drawable comExampleIcon = someDrawable();
+
+ addTypeMapping(account("user@example.com", "com.example"), "title", comExampleIcon);
+ addTypeMapping(account(null, null), "device", someDrawable());
+ addTypeMapping(account("foo", "bar.type"), "bar", someDrawable());
+ addTypeMapping(account("user2@example.com", "com.example"), "title", comExampleIcon);
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes();
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account("user@example.com", "com.example"));
+ assertEquals("user@example.com", displayable.getNameLabel());
+ }
+
+ public void test_displayableAccountForNullAccount_hasNameFromAccountType() {
+ addSomeKnownAccounts();
+ addTypeMapping(account(null, null), "Device Display Label", someDrawable());
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes();
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account(null, null));
+ assertEquals("Device Display Label", displayable.getNameLabel());
+ }
+
+ public void test_displayableAccountForDeviceAccount_hasNameFromAccountType() {
+ addSomeKnownAccounts();
+ addTypeMapping(account("some.device.account.name", "device.account.type"), "Device Label",
+ someDrawable());
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes(
+ new FakeDeviceAccountTypeFactory().withDeviceTypes("device.account.type"));
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account("some.device.account.name", "device.account.type"));
+ assertEquals("Device Label", displayable.getNameLabel());
+ }
+
+ public void test_displayableAccountForDeviceAccountWhenMultiple_hasNameFromAccount() {
+ addSomeKnownAccounts();
+ addTypeMapping(account("first.device.account.name", "a.device.account.type"),
+ "Device Display Label", someDrawable());
+ addTypeMapping(account("second.device.account.name", "b.device.account.type"),
+ "Device Display Label", someDrawable());
+ addTypeMapping(account("another.device.account.name", "a.device.account.type"),
+ "Device Display Label", someDrawable());
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes(
+ new FakeDeviceAccountTypeFactory().withDeviceTypes("a.device.account.type",
+ "b.device.account.type"));
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account("first.device.account.name", "a.device.account.type"));
+ assertEquals("first.device.account.name", displayable.getNameLabel());
+
+ final AccountDisplayInfo displayable2 = sut.getAccountDisplayInfo(
+ account("second.device.account.name", "b.device.account.type"));
+ assertEquals("second.device.account.name", displayable2.getNameLabel());
+ }
+
+ public void test_displayableAccountForSimAccount_hasNameFromAccountType() {
+ addSomeKnownAccounts();
+ addTypeMapping(account("sim.account.name", "sim.account.type"), "SIM", someDrawable());
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes(
+ new FakeDeviceAccountTypeFactory().withSimTypes("sim.account.type"));
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account("sim.account.name", "sim.account.type"));
+ assertEquals("SIM", displayable.getNameLabel());
+ }
+
+ public void test_displayableAccountForSimAccountWhenMultiple_hasNameFromAccount() {
+ addSomeKnownAccounts();
+ addTypeMapping(account("sim.account.name", "sim.account.type"), "SIM", someDrawable());
+ addTypeMapping(account("sim2.account.name", "sim.account.type"), "SIM", someDrawable());
+
+ final AccountDisplayInfoFactory sut = createFactoryForKnownTypes(
+ new FakeDeviceAccountTypeFactory().withSimTypes("sim.account.type"));
+
+ final AccountDisplayInfo displayable = sut.getAccountDisplayInfo(
+ account("sim.account.name", "sim.account.type"));
+ assertEquals("sim.account.name", displayable.getNameLabel());
+ }
+
+ private void addSomeKnownAccounts() {
+ final Drawable comExampleIcon = someDrawable();
+ addTypeMapping(account("user@example.com", "com.example"), "Example Title", comExampleIcon);
+ addTypeMapping(account("foo", "bar.type"), "Bar", someDrawable());
+ addTypeMapping(account("user2@example.com", "com.example"), "Example Title", comExampleIcon);
+ addTypeMapping(account("user", "com.example.two"), "Some Account", someDrawable());
+ }
+
+ private AccountDisplayInfoFactory createFactoryForKnownTypes() {
+ return createFactoryForKnownTypes(new DeviceLocalAccountTypeFactory.Default(getContext()));
+ }
+
+ private AccountDisplayInfoFactory createFactoryForKnownTypes(DeviceLocalAccountTypeFactory
+ typeFactory) {
+ return new AccountDisplayInfoFactory(getContext(),
+ createFakeAccountTypeManager(mKnownTypes), typeFactory,
+ new ArrayList<>(mKnownTypes.keySet()));
+ }
+
+ private AccountWithDataSet account(String name, String type) {
+ return new AccountWithDataSet(name, type, /* dataSet */ null);
+ }
+
+ private void addTypeMapping(AccountWithDataSet account, String label, Drawable icon) {
+ mKnownTypes.put(account, FakeAccountType.create(account, label, icon));
+ }
+
+ private AccountTypeManager createFakeAccountTypeManager(
+ final Map<AccountWithDataSet, AccountType> mapping) {
+ return new MockAccountTypeManager(mapping.values().toArray(new AccountType[mapping.size()]),
+ mapping.keySet().toArray(new AccountWithDataSet[mapping.size()]));
+ }
+
+ private Drawable someDrawable() {
+ return new Drawable() {
+ @Override
+ public void draw(Canvas canvas) {
+ }
+
+ @Override
+ public void setAlpha(int i) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.OPAQUE;
+ }
+ };
+ }
+
+}