1 /*
2  * Copyright (C) 2015 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.messaging.ui.contact;
18 
19 import android.content.Context;
20 import android.database.Cursor;
21 import androidx.viewpager.widget.PagerAdapter;
22 import androidx.viewpager.widget.ViewPager;
23 import android.test.suitebuilder.annotation.LargeTest;
24 import android.view.View;
25 import android.widget.ListView;
26 
27 import com.android.messaging.FakeFactory;
28 import com.android.messaging.R;
29 import com.android.messaging.datamodel.FakeDataModel;
30 import com.android.messaging.datamodel.action.ActionTestHelpers;
31 import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService;
32 import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService.StubActionServiceCallLog;
33 import com.android.messaging.datamodel.action.GetOrCreateConversationAction;
34 import com.android.messaging.datamodel.data.ContactPickerData;
35 import com.android.messaging.datamodel.data.ParticipantData;
36 import com.android.messaging.datamodel.data.TestDataFactory;
37 import com.android.messaging.ui.CustomHeaderViewPagerAdapter;
38 import com.android.messaging.ui.FragmentTestCase;
39 import com.android.messaging.ui.UIIntents;
40 import com.android.messaging.ui.contact.ContactPickerFragment;
41 import com.android.messaging.ui.contact.ContactPickerFragment.ContactPickerFragmentHost;
42 
43 import org.mockito.Matchers;
44 import org.mockito.Mock;
45 import org.mockito.Mockito;
46 
47 import java.util.ArrayList;
48 import java.util.List;
49 
50 
51 /**
52  * Unit tests for {@link ContactPickerFragment}.
53  */
54 @LargeTest
55 public class ContactPickerFragmentTest
56     extends FragmentTestCase<ContactPickerFragment> {
57 
58     @Mock protected ContactPickerData mMockContactPickerData;
59     @Mock protected UIIntents mMockUIIntents;
60     @Mock protected ContactPickerFragmentHost mockHost;
61     protected FakeDataModel mFakeDataModel;
62     private ActionTestHelpers.StubActionService mService;
63 
ContactPickerFragmentTest()64     public ContactPickerFragmentTest() {
65         super(ContactPickerFragment.class);
66     }
67 
68     @Override
setUp()69     protected void setUp() throws Exception {
70         super.setUp();
71 
72         final Context context = getInstrumentation().getTargetContext();
73         mService = new StubActionService();
74         mFakeDataModel = new FakeDataModel(context)
75             .withContactPickerData(mMockContactPickerData)
76             .withActionService(mService);
77         FakeFactory.register(context)
78                 .withDataModel(mFakeDataModel)
79                 .withUIIntents(mMockUIIntents);
80     }
81 
82     /**
83      * Helper method to initialize the ContactPickerFragment and its data.
84      */
initFragment(final int initialMode)85     private ContactPickerFragmentTest initFragment(final int initialMode) {
86         Mockito.when(mMockContactPickerData.isBound(Matchers.anyString()))
87             .thenReturn(true);
88 
89         getActivity().runOnUiThread(new Runnable() {
90             @Override
91             public void run() {
92                 final ContactPickerFragment fragment = getFragment();
93                 fragment.setHost(mockHost);
94                 fragment.setContactPickingMode(initialMode, false);
95 
96                 getActivity().setFragment(fragment);
97                 Mockito.verify(mMockContactPickerData).init(fragment.getLoaderManager(),
98                         fragment.mBinding);
99             }
100         });
101         getInstrumentation().waitForIdleSync();
102         return this;
103     }
104 
105     /**
106      * Bind the datamodel with all contacts cursor to populate the all contacts list in the
107      * fragment.
108      */
loadWithAllContactsCursor(final Cursor cursor)109     private ContactPickerFragmentTest loadWithAllContactsCursor(final Cursor cursor) {
110         Mockito.when(mMockContactPickerData.isBound(Matchers.anyString()))
111             .thenReturn(true);
112 
113         getActivity().runOnUiThread(new Runnable() {
114             @Override
115             public void run() {
116                 getFragment().onAllContactsCursorUpdated(cursor);
117             }
118         });
119         getInstrumentation().waitForIdleSync();
120         return this;
121     }
122 
123     /**
124      * Bind the datamodel with frequent contacts cursor to populate the contacts list in the
125      * fragment.
126      */
loadWithFrequentContactsCursor(final Cursor cursor)127     private ContactPickerFragmentTest loadWithFrequentContactsCursor(final Cursor cursor) {
128         Mockito.when(mMockContactPickerData.isBound(Matchers.anyString()))
129             .thenReturn(true);
130         getActivity().runOnUiThread(new Runnable() {
131             @Override
132             public void run() {
133                 getFragment().onFrequentContactsCursorUpdated(cursor);
134             }
135         });
136         getInstrumentation().waitForIdleSync();
137         return this;
138     }
139 
140     /**
141      * Test the initial state of the fragment before loading data.
142      */
testInitialState()143     public void testInitialState() {
144         initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT);
145 
146         // Make sure that the frequent contacts view is shown by default.
147         final ViewPager pager = (ViewPager) getFragment().getView().findViewById(R.id.pager);
148         final View currentPagedView = pager.getChildAt(pager.getCurrentItem());
149         final View frequentContactsView = ((CustomHeaderViewPagerAdapter) pager.getAdapter())
150                 .getViewHolder(0).getView(null);
151         assertEquals(frequentContactsView, currentPagedView);
152     }
153 
154     /**
155      * Verifies that list view gets correctly populated given a cursor.
156      */
testLoadAllContactsList()157     public void testLoadAllContactsList() {
158         final Cursor cursor = TestDataFactory.getAllContactListCursor();
159         initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT)
160                 .loadWithAllContactsCursor(cursor);
161         final ListView listView = (ListView) getFragment().getView()
162                 .findViewById(R.id.all_contacts_list);
163         assertEquals(cursor.getCount(), listView.getCount());
164     }
165 
166     /**
167      * Verifies that list view gets correctly populated given a cursor.
168      */
testLoadFrequentContactsList()169     public void testLoadFrequentContactsList() {
170         final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
171         initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT)
172                 .loadWithFrequentContactsCursor(cursor);
173         final ListView listView = (ListView) getFragment().getView()
174                 .findViewById(R.id.frequent_contacts_list);
175         assertEquals(cursor.getCount(), listView.getCount());
176     }
177 
testPickInitialContact()178     public void testPickInitialContact() {
179         final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
180         initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT)
181                 .loadWithFrequentContactsCursor(cursor);
182         final ListView listView = (ListView) getFragment().getView()
183                 .findViewById(R.id.frequent_contacts_list);
184         // Click on the first contact to add it.
185         final ContactListItemView cliv = (ContactListItemView) listView.getChildAt(0);
186         clickButton(cliv);
187         final ContactRecipientAutoCompleteView chipsView = (ContactRecipientAutoCompleteView)
188                 getFragment().getView()
189                 .findViewById(R.id.recipient_text_view);
190         // Verify the contact is added to the chips view.
191         final List<ParticipantData> participants =
192                 chipsView.getRecipientParticipantDataForConversationCreation();
193         assertEquals(1, participants.size());
194         assertEquals(cliv.mData.getDestination(), participants.get(0).getSendDestination());
195         assertTrue(mService.getCalls().get(0).action instanceof GetOrCreateConversationAction);
196     }
197 
testLeaveChipsMode()198     public void testLeaveChipsMode() {
199         final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
200         initFragment(ContactPickerFragment.MODE_CHIPS_ONLY)
201                 .loadWithFrequentContactsCursor(cursor);
202         // Click on the add more participants button
203         // TODO: Figure out a way to click on the add more participants button now that
204         // it's part of the menu.
205         // final ImageButton AddMoreParticipantsButton = (ImageButton) getFragment().getView()
206         //         .findViewById(R.id.add_more_participants_button);
207         // clickButton(AddMoreParticipantsButton);
208         // Mockito.verify(mockHost).onInitiateAddMoreParticipants();
209     }
210 
testPickMoreContacts()211     public void testPickMoreContacts() {
212         final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
213         initFragment(ContactPickerFragment.MODE_PICK_MORE_CONTACTS)
214                 .loadWithFrequentContactsCursor(cursor);
215         final ListView listView = (ListView) getFragment().getView()
216                 .findViewById(R.id.frequent_contacts_list);
217         // Click on the first contact to add it.
218         final ContactListItemView cliv = (ContactListItemView) listView.getChildAt(0);
219         clickButton(cliv);
220         // Verify that we don't attempt to create a conversation right away.
221         assertEquals(0, mService.getCalls().size());
222     }
223 }
224