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