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