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.attachmentchooser; 18 19 import android.app.Fragment; 20 import android.test.suitebuilder.annotation.LargeTest; 21 import android.widget.CheckBox; 22 23 import com.android.messaging.FakeFactory; 24 import com.android.messaging.R; 25 import com.android.messaging.datamodel.DataModel; 26 import com.android.messaging.datamodel.data.DraftMessageData; 27 import com.android.messaging.datamodel.data.MessageData; 28 import com.android.messaging.datamodel.data.MessagePartData; 29 import com.android.messaging.datamodel.data.TestDataFactory; 30 import com.android.messaging.ui.FragmentTestCase; 31 import com.android.messaging.ui.TestActivity; 32 import com.android.messaging.ui.TestActivity.FragmentEventListener; 33 import com.android.messaging.ui.attachmentchooser.AttachmentChooserFragment; 34 import com.android.messaging.ui.attachmentchooser.AttachmentGridItemView; 35 import com.android.messaging.ui.attachmentchooser.AttachmentGridView; 36 import com.android.messaging.ui.attachmentchooser.AttachmentChooserFragment.AttachmentChooserFragmentHost; 37 import com.android.messaging.ui.conversationlist.ConversationListFragment; 38 39 import org.mockito.Matchers; 40 import org.mockito.Mock; 41 import org.mockito.Mockito; 42 import org.mockito.compat.ArgumentMatcher; 43 44 import java.util.Arrays; 45 import java.util.HashSet; 46 import java.util.List; 47 import java.util.Set; 48 49 50 /** 51 * Unit tests for {@link ConversationListFragment}. 52 */ 53 @LargeTest 54 public class AttachmentChooserFragmentTest extends FragmentTestCase<AttachmentChooserFragment> { 55 56 @Mock protected DataModel mockDataModel; 57 @Mock protected DraftMessageData mockDraftMessageData; 58 @Mock protected AttachmentChooserFragmentHost mockHost; 59 60 private static final String CONVERSATION_ID = "cid"; 61 62 /** A custom argument matcher that checks whether the set argument passed in is a set 63 * with identical attachment data as the given set. 64 */ 65 private class IsSetOfGivenAttachments extends ArgumentMatcher<Set<MessagePartData>> { 66 private final Set<MessagePartData> mGivenParts; IsSetOfGivenAttachments(final Set<MessagePartData> givenParts)67 public IsSetOfGivenAttachments(final Set<MessagePartData> givenParts) { 68 mGivenParts = givenParts; 69 } 70 71 @Override matchesObject(final Object set)72 public boolean matchesObject(final Object set) { 73 @SuppressWarnings("unchecked") 74 final Set<MessagePartData> actualSet = (Set<MessagePartData>) set; 75 if (actualSet.size() != mGivenParts.size()) { 76 return false; 77 } 78 return mGivenParts.containsAll(actualSet) && actualSet.containsAll(mGivenParts); 79 } 80 } 81 AttachmentChooserFragmentTest()82 public AttachmentChooserFragmentTest() { 83 super(AttachmentChooserFragment.class); 84 } 85 86 @Override setUp()87 protected void setUp() throws Exception { 88 super.setUp(); 89 FakeFactory.register(this.getInstrumentation().getTargetContext()) 90 .withDataModel(mockDataModel); 91 } 92 loadWith(final List<MessagePartData> attachments)93 private void loadWith(final List<MessagePartData> attachments) { 94 Mockito.when(mockDraftMessageData.isBound(Matchers.anyString())) 95 .thenReturn(true); 96 Mockito.doReturn(mockDraftMessageData) 97 .when(mockDataModel) 98 .createDraftMessageData(Mockito.anyString()); 99 Mockito.doReturn(attachments) 100 .when(mockDraftMessageData) 101 .getReadOnlyAttachments(); 102 Mockito.when(mockDataModel.createDraftMessageData( 103 Matchers.anyString())) 104 .thenReturn(mockDraftMessageData); 105 106 // Create fragment synchronously to avoid need for volatile, synchronization etc. 107 final AttachmentChooserFragment fragment = getFragment(); 108 // Binding to model happens when attaching fragment to activity, so hook into test 109 // activity to do so. 110 getActivity().setFragmentEventListener(new FragmentEventListener() { 111 @Override 112 public void onAttachFragment(final Fragment attachedFragment) { 113 if (fragment == attachedFragment) { 114 fragment.setConversationId(CONVERSATION_ID); 115 } 116 } 117 }); 118 119 getActivity().runOnUiThread(new Runnable() { 120 @Override 121 public void run() { 122 fragment.setHost(mockHost); 123 getActivity().setFragment(fragment); 124 Mockito.verify(mockDataModel).createDraftMessageData( 125 Mockito.matches(CONVERSATION_ID)); 126 Mockito.verify(mockDraftMessageData).loadFromStorage( 127 Matchers.eq(fragment.mBinding), Matchers.eq((MessageData) null), 128 Matchers.eq(false)); 129 } 130 }); 131 // Now load the cursor 132 getActivity().runOnUiThread(new Runnable() { 133 @Override 134 public void run() { 135 fragment.onDraftChanged(mockDraftMessageData, DraftMessageData.ALL_CHANGED); 136 } 137 }); 138 getInstrumentation().waitForIdleSync(); 139 } 140 testUnselect()141 public void testUnselect() { 142 final List<MessagePartData> attachments = TestDataFactory.getTestDraftAttachments(); 143 loadWith(attachments); 144 final AttachmentGridView attachmentGridView = (AttachmentGridView) 145 getFragment().getView().findViewById(R.id.grid); 146 assertEquals("bad view count", attachments.size(), 147 attachmentGridView.getAdapter().getCount()); 148 149 final AttachmentGridItemView itemView = (AttachmentGridItemView) 150 attachmentGridView.getChildAt(0); 151 assertEquals(attachmentGridView, itemView.testGetHostInterface()); 152 final CheckBox checkBox = (CheckBox) itemView.findViewById(R.id.checkbox); 153 assertEquals(true, checkBox.isChecked()); 154 assertEquals(true, attachmentGridView.isItemSelected(itemView.mAttachmentData)); 155 clickButton(checkBox); 156 assertEquals(false, checkBox.isChecked()); 157 assertEquals(false, attachmentGridView.isItemSelected(itemView.mAttachmentData)); 158 159 final AttachmentGridItemView itemView2 = (AttachmentGridItemView) 160 attachmentGridView.getChildAt(1); 161 final CheckBox checkBox2 = (CheckBox) itemView2.findViewById(R.id.checkbox); 162 clickButton(checkBox2); 163 164 getFragment().confirmSelection(); 165 final MessagePartData[] attachmentsToRemove = new MessagePartData[] { 166 itemView.mAttachmentData, itemView2.mAttachmentData }; 167 Mockito.verify(mockDraftMessageData).removeExistingAttachments(Matchers.argThat( 168 new IsSetOfGivenAttachments(new HashSet<>(Arrays.asList(attachmentsToRemove))))); 169 Mockito.verify(mockDraftMessageData).saveToStorage(Matchers.eq(getFragment().mBinding)); 170 Mockito.verify(mockHost).onConfirmSelection(); 171 } 172 } 173