1 /* 2 * Copyright (C) 2017 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 package com.android.emergency.preferences; 17 18 import static com.google.common.truth.Truth.assertThat; 19 import static org.mockito.Matchers.any; 20 import static org.mockito.Matchers.anyString; 21 import static org.mockito.Matchers.eq; 22 import static org.mockito.Mockito.doNothing; 23 import static org.mockito.Mockito.doReturn; 24 import static org.mockito.Mockito.mock; 25 import static org.mockito.Mockito.spy; 26 import static org.mockito.Mockito.when; 27 28 import android.content.ContextWrapper; 29 import android.content.SharedPreferences; 30 import android.content.pm.PackageManager; 31 import android.net.Uri; 32 import android.support.v7.preference.PreferenceGroup; 33 import android.support.v7.preference.PreferenceManager; 34 import android.support.v7.preference.PreferenceScreen; 35 36 import com.android.emergency.ContactTestUtils; 37 import com.android.emergency.EmergencyContactManager; 38 import com.android.emergency.PreferenceKeys; 39 import com.android.emergency.TestConfig; 40 41 import java.util.ArrayList; 42 import java.util.List; 43 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.Mock; 48 import org.mockito.MockitoAnnotations; 49 import org.robolectric.RobolectricTestRunner; 50 import org.robolectric.RuntimeEnvironment; 51 import org.robolectric.annotation.Config; 52 53 /** Unit tests for {@link EmergencyContactsPreference}. */ 54 @RunWith(RobolectricTestRunner.class) 55 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 56 public class EmergencyContactsPreferenceTest { 57 @Mock private PackageManager mPackageManager; 58 @Mock private PreferenceManager mPreferenceManager; 59 @Mock private SharedPreferences mSharedPreferences; 60 @Mock private EmergencyContactsPreference.ContactValidator mContactValidator; 61 @Mock private ContactPreference.ContactFactory mContactFactory; 62 private ContextWrapper mContext; 63 private EmergencyContactsPreference mPreference; 64 65 @Before 66 public void setUp() { 67 MockitoAnnotations.initMocks(this); 68 69 when(mPreferenceManager.getSharedPreferences()).thenReturn(mSharedPreferences); 70 71 mContext = spy(RuntimeEnvironment.application); 72 doReturn(mPackageManager).when(mContext).getPackageManager(); 73 74 mPreference = spy(new EmergencyContactsPreference(RuntimeEnvironment.application, 75 null /* attrs */, mContactValidator, mContactFactory)); 76 77 PreferenceGroup prefRoot = spy(new PreferenceScreen(mContext, null /* attrs */)); 78 when(prefRoot.getPreferenceManager()).thenReturn(mPreferenceManager); 79 prefRoot.addPreference(mPreference); 80 } 81 82 @Test 83 public void testDefaultProperties() { 84 assertThat(mPreference.isPersistent()).isTrue(); 85 assertThat(mPreference.isNotSet()).isTrue(); 86 assertThat(mPreference.getEmergencyContacts()).isEmpty(); 87 assertThat(mPreference.getPreferenceCount()).isEqualTo(0); 88 } 89 90 @Test 91 public void testAddAndRemoveEmergencyContact() throws Throwable { 92 final String name = "Jane"; 93 final String phoneNumber = "456"; 94 95 when(mContactValidator.isValidEmergencyContact(any(), any())).thenReturn(true); 96 97 EmergencyContactManager.Contact contact = mock(EmergencyContactManager.Contact.class); 98 when(mContactFactory.getContact(any(), any())).thenReturn(contact); 99 when(contact.getName()).thenReturn(name); 100 when(contact.getPhoneNumber()).thenReturn(phoneNumber); 101 102 Uri uri = mock(Uri.class); 103 when(contact.getPhoneUri()).thenReturn(uri); 104 105 mPreference.addNewEmergencyContact(uri); 106 107 assertThat(mPreference.getEmergencyContacts()).hasSize(1); 108 assertThat(mPreference.getPreferenceCount()).isEqualTo(1); 109 ContactPreference contactPreference = (ContactPreference) mPreference.getPreference(0); 110 111 assertThat(contactPreference.getPhoneUri()).isEqualTo(uri); 112 assertThat(contactPreference.getTitle()).isEqualTo(name); 113 assertThat((String) contactPreference.getSummary()).contains(phoneNumber); 114 115 mPreference.onRemoveContactPreference((ContactPreference) mPreference.getPreference(0)); 116 117 assertThat(mPreference.getEmergencyContacts()).isEmpty(); 118 assertThat(mPreference.getPreferenceCount()).isEqualTo(0); 119 } 120 121 @Test 122 public void testReloadFromPreference() throws Throwable { 123 final String nameJane = "Jane"; 124 final String phoneNumberJane = "456"; 125 Uri contactUriJane = Uri.parse("tel:" + phoneNumberJane); 126 EmergencyContactManager.Contact contactJane = mock(EmergencyContactManager.Contact.class); 127 when(mContactFactory.getContact(any(), eq(contactUriJane))).thenReturn(contactJane); 128 when(contactJane.getName()).thenReturn(nameJane); 129 when(contactJane.getPhoneNumber()).thenReturn(phoneNumberJane); 130 when(contactJane.getPhoneUri()).thenReturn(contactUriJane); 131 132 final String nameJohn = "John"; 133 final String phoneNumberJohn = "123"; 134 Uri contactUriJohn = Uri.parse("tel:" + phoneNumberJohn); 135 EmergencyContactManager.Contact contactJohn = mock(EmergencyContactManager.Contact.class); 136 when(mContactFactory.getContact(any(), eq(contactUriJohn))).thenReturn(contactJohn); 137 when(contactJohn.getName()).thenReturn(nameJohn); 138 when(contactJohn.getPhoneNumber()).thenReturn(phoneNumberJohn); 139 when(contactJohn.getPhoneUri()).thenReturn(contactUriJohn); 140 141 final List<Uri> emergencyContacts = new ArrayList<>(); 142 emergencyContacts.add(contactUriJane); 143 emergencyContacts.add(contactUriJohn); 144 mPreference.setEmergencyContacts(emergencyContacts); 145 146 assertThat(mPreference.getEmergencyContacts().size()).isEqualTo(2); 147 assertThat(mPreference.getPreferenceCount()).isEqualTo(2); 148 149 // "Delete" Jane by reloading from preferences. The mock SharedPreferences still have both 150 // contacts stored, but the validator only believes John is valid. 151 mPreference.setKey(PreferenceKeys.KEY_EMERGENCY_CONTACTS); 152 when(mSharedPreferences.getString(eq(mPreference.getKey()), any())) 153 .thenReturn(mPreference.serialize(emergencyContacts)); 154 when(mContactValidator.isValidEmergencyContact(any(), eq(contactUriJane))) 155 .thenReturn(false); 156 when(mContactValidator.isValidEmergencyContact(any(), eq(contactUriJohn))).thenReturn(true); 157 // Override the preference's persist behavior, to avoid EmergencyContactsPreference 158 // attempting to write to SharedPreferences. (Preference's default behavior is unmockable.) 159 doNothing().when(mPreference).persistEmergencyContacts(any()); 160 mPreference.reloadFromPreference(); 161 162 // Assert the only remaining contact is John 163 assertThat(mPreference.getEmergencyContacts()).hasSize(1); 164 assertThat(mPreference.getPreferenceCount()).isEqualTo(1); 165 ContactPreference contactPreference = (ContactPreference) mPreference.getPreference(0); 166 assertThat(contactPreference.getPhoneUri()).isEqualTo(contactUriJohn); 167 } 168 } 169