Home | History | Annotate | Download | only in editor
      1 /*
      2  * Copyright (C) 2011 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 
     17 package com.android.contacts.editor;
     18 
     19 import static junit.framework.Assert.assertEquals;
     20 import static junit.framework.Assert.assertFalse;
     21 import static junit.framework.Assert.assertNull;
     22 import static org.junit.Assert.assertTrue;
     23 
     24 import android.support.test.InstrumentationRegistry;
     25 import android.support.test.filters.SmallTest;
     26 import android.support.test.runner.AndroidJUnit4;
     27 
     28 import com.android.contacts.model.account.AccountType;
     29 import com.android.contacts.model.account.AccountWithDataSet;
     30 
     31 import org.junit.Before;
     32 import org.junit.Test;
     33 import org.junit.runner.RunWith;
     34 
     35 import java.util.ArrayList;
     36 import java.util.Arrays;
     37 import java.util.Collections;
     38 import java.util.List;
     39 
     40 /**
     41  * Test case for {@link ContactEditorUtils}.
     42  *
     43  * adb shell am instrument -w -e class com.android.contacts.editor.ContactEditorUtilsTest \
     44        com.android.contacts.tests/android.test.InstrumentationTestRunner
     45 
     46  * <p>It may make sense to just delete or move these tests since the code under test just forwards
     47  * calls to {@link com.android.contacts.preference.ContactsPreferences} and that logic is already
     48  * covered by {@link com.android.contacts.preference.ContactsPreferencesTest}
     49  * </p>
     50  */
     51 @SmallTest
     52 @RunWith(AndroidJUnit4.class)
     53 public class ContactEditorUtilsTest {
     54     private ContactEditorUtils mTarget;
     55 
     56     private static final String TYPE1 = "type1";
     57     private static final String TYPE2 = "type2";
     58     private static final String TYPE2_EXT = "ext";
     59 
     60     private static final AccountWithDataSet ACCOUNT_1_A = new AccountWithDataSet("a", TYPE1, null);
     61     private static final AccountWithDataSet ACCOUNT_1_B = new AccountWithDataSet("b", TYPE1, null);
     62 
     63     private static final AccountWithDataSet ACCOUNT_2_A = new AccountWithDataSet("a", TYPE2, null);
     64     private static final AccountWithDataSet ACCOUNT_2EX_A = new AccountWithDataSet(
     65             "a", TYPE2, TYPE2_EXT);
     66 
     67     @Before
     68     public void setUp() throws Exception {
     69         mTarget = ContactEditorUtils.create(InstrumentationRegistry.getTargetContext());
     70 
     71         // Clear the preferences.
     72         mTarget.cleanupForTest();
     73     }
     74 
     75     /**
     76      * Test for
     77      * - {@link ContactEditorUtils#saveDefaultAccount}
     78      * - {@link ContactEditorUtils#getOnlyOrDefaultAccount}
     79      */
     80     @Test
     81     public void testSaveDefaultAccount() {
     82         mTarget.saveDefaultAccount(null);
     83         assertNull(mTarget.getOnlyOrDefaultAccount(Collections.<AccountWithDataSet>emptyList()));
     84 
     85         mTarget.saveDefaultAccount(ACCOUNT_1_A);
     86         assertEquals(ACCOUNT_1_A, mTarget.getOnlyOrDefaultAccount(Collections.
     87                 <AccountWithDataSet>emptyList()));
     88     }
     89 
     90     /**
     91      * Tests for
     92      * {@link ContactEditorUtils#shouldShowAccountChangedNotification(List<AccountWithDataSet>)},
     93      * starting with 0 accounts.
     94      */
     95     @Test
     96     public void testShouldShowAccountChangedNotification_0Accounts() {
     97         List<AccountWithDataSet> currentAccounts = new ArrayList<>();
     98         assertTrue(mTarget.shouldShowAccountChangedNotification(currentAccounts));
     99 
    100         // We show the notification here, and user clicked "add account"
    101         currentAccounts.add(ACCOUNT_1_A);
    102 
    103         // Now we open the contact editor with the new account.
    104 
    105         // When closing the editor, we save the default account.
    106         mTarget.saveDefaultAccount(ACCOUNT_1_A);
    107 
    108         // Next time the user creates a contact, we don't show the notification.
    109         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    110 
    111         // User added a new writable account, ACCOUNT_1_B.
    112         currentAccounts.add(ACCOUNT_1_B);
    113 
    114         // Since default account is still ACCOUNT_1_A, we don't show the notification.
    115         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    116 
    117         // User saved a new contact.  We update the account list and the default account.
    118         mTarget.saveDefaultAccount(ACCOUNT_1_B);
    119 
    120         // User created another contact.  Now we don't show the notification.
    121         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    122 
    123         // User installed a new contact sync adapter...
    124 
    125         // Add new accounts: ACCOUNT_2_A, ACCOUNT_2EX_A.
    126         currentAccounts.add(ACCOUNT_2_A);
    127         currentAccounts.add(ACCOUNT_2EX_A);
    128 
    129         // New added account but default account is still not changed, so no notification.
    130         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    131 
    132         // User saves a new contact, with a different default account.
    133         mTarget.saveDefaultAccount(ACCOUNT_2_A);
    134 
    135         // Next time user creates a contact, no notification.
    136         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    137 
    138         // Remove ACCOUNT_2EX_A.
    139         currentAccounts.remove(ACCOUNT_2EX_A);
    140 
    141         // ACCOUNT_2EX_A was not default, so no notification either.
    142         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    143 
    144         // Remove ACCOUNT_2_A, which is default.
    145         currentAccounts.remove(ACCOUNT_2_A);
    146 
    147         // Now we show the notification.
    148         assertTrue(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    149 
    150         // Do not save the default account, and add a new account now.
    151         currentAccounts.add(ACCOUNT_2EX_A);
    152 
    153         // No default account, so show notification.
    154         assertTrue(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    155     }
    156 
    157     /**
    158      * Tests for
    159      * {@link ContactEditorUtils#shouldShowAccountChangedNotification(List<AccountWithDataSet>)},
    160      * starting with 1 accounts.
    161      */
    162     @Test
    163     public void testShouldShowAccountChangedNotification_1Account() {
    164         // Always returns false when 1 writable account.
    165         assertFalse(mTarget.shouldShowAccountChangedNotification(
    166                 Collections.singletonList(ACCOUNT_1_A)));
    167 
    168         // User saves a new contact.
    169         mTarget.saveDefaultAccount(ACCOUNT_1_A);
    170 
    171         // Next time, no notification.
    172         assertFalse(mTarget.shouldShowAccountChangedNotification(
    173                 Collections.singletonList(ACCOUNT_1_A)));
    174 
    175         // The rest is the same...
    176     }
    177 
    178     /**
    179      * Tests for
    180      * {@link ContactEditorUtils#shouldShowAccountChangedNotification(List<AccountWithDataSet>)},
    181      * starting with 0 accounts, and the user selected "local only".
    182      */
    183     @Test
    184     public void testShouldShowAccountChangedNotification_0Account_localOnly() {
    185         // First launch -- always true.
    186         assertTrue(mTarget.shouldShowAccountChangedNotification(Collections.
    187                 <AccountWithDataSet>emptyList()));
    188 
    189         // We show the notification here, and user clicked "keep local" and saved an contact.
    190         mTarget.saveDefaultAccount(AccountWithDataSet.getNullAccount());
    191 
    192         // Now there are no accounts, and default account is null.
    193 
    194         // The user created another contact, but this we shouldn't show the notification.
    195         assertFalse(mTarget.shouldShowAccountChangedNotification(Collections.
    196                 <AccountWithDataSet>emptyList()));
    197     }
    198 
    199     @Test
    200     public void testShouldShowAccountChangedNotification_sanity_check() {
    201         // Prepare 1 account and save it as the default.
    202         mTarget.saveDefaultAccount(ACCOUNT_1_A);
    203 
    204         // Right after a save, the dialog shouldn't show up.
    205         assertFalse(mTarget.shouldShowAccountChangedNotification(
    206                 Collections.singletonList(ACCOUNT_1_A)));
    207 
    208         // Remove the default account to emulate broken preferences.
    209         mTarget.removeDefaultAccountForTest();
    210 
    211         // The dialog shouldn't show up.
    212         // The logic is, if there's a writable account, we'll pick it as default
    213         assertFalse(mTarget.shouldShowAccountChangedNotification(
    214                 Collections.singletonList(ACCOUNT_1_A)));
    215     }
    216 
    217     @Test
    218     public void testShouldShowAccountChangedNotification_nullAccount() {
    219         final List<AccountWithDataSet> currentAccounts = new ArrayList<>();
    220         final AccountWithDataSet nullAccount = AccountWithDataSet.getNullAccount();
    221         currentAccounts.add(nullAccount);
    222 
    223         assertTrue(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    224 
    225         // User chooses to keep the "device" account as the default
    226         mTarget.saveDefaultAccount(nullAccount);
    227 
    228         // Right after a save, the dialog shouldn't show up.
    229         assertFalse(mTarget.shouldShowAccountChangedNotification(currentAccounts));
    230     }
    231 
    232     private static class MockAccountType extends AccountType {
    233         private boolean mAreContactsWritable;
    234 
    235         public MockAccountType(String accountType, String dataSet, boolean areContactsWritable) {
    236             this.accountType = accountType;
    237             this.dataSet = dataSet;
    238             mAreContactsWritable = areContactsWritable;
    239         }
    240 
    241         @Override
    242         public boolean areContactsWritable() {
    243             return mAreContactsWritable;
    244         }
    245 
    246         @Override
    247         public boolean isGroupMembershipEditable() {
    248             return true;
    249         }
    250     }
    251 }
    252