1 /* 2 * Copyright (C) 2016 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.documentsui; 18 19 import static junit.framework.Assert.assertTrue; 20 import static junit.framework.Assert.fail; 21 22 import static org.junit.Assert.assertEquals; 23 24 import android.content.Intent; 25 import android.net.Uri; 26 import android.os.Parcelable; 27 import android.provider.DocumentsContract; 28 import android.provider.DocumentsContract.Path; 29 30 import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails; 31 import androidx.test.filters.MediumTest; 32 import androidx.test.runner.AndroidJUnit4; 33 34 import com.android.documentsui.base.DocumentStack; 35 import com.android.documentsui.base.RootInfo; 36 import com.android.documentsui.base.Shared; 37 import com.android.documentsui.files.LauncherActivity; 38 import com.android.documentsui.sorting.SortDimension; 39 import com.android.documentsui.sorting.SortModel; 40 import com.android.documentsui.testing.DocumentStackAsserts; 41 import com.android.documentsui.testing.Roots; 42 import com.android.documentsui.testing.TestEnv; 43 import com.android.documentsui.testing.TestEventHandler; 44 import com.android.documentsui.testing.TestProvidersAccess; 45 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 50 import java.util.Arrays; 51 import java.util.concurrent.CountDownLatch; 52 import java.util.concurrent.TimeUnit; 53 54 /** 55 * A unit test *for* AbstractActionHandler, not an abstract test baseclass. 56 */ 57 @RunWith(AndroidJUnit4.class) 58 @MediumTest 59 public class AbstractActionHandlerTest { 60 61 private TestActivity mActivity; 62 private TestEnv mEnv; 63 private AbstractActionHandler<TestActivity> mHandler; 64 65 @Before setUp()66 public void setUp() { 67 mEnv = TestEnv.create(); 68 mActivity = TestActivity.create(mEnv); 69 mHandler = new AbstractActionHandler<TestActivity>( 70 mActivity, 71 mEnv.state, 72 mEnv.providers, 73 mEnv.docs, 74 mEnv.searchViewManager, 75 mEnv::lookupExecutor, 76 mEnv.injector) { 77 78 @Override 79 public void openRoot(RootInfo root) { 80 throw new UnsupportedOperationException(); 81 } 82 83 @Override 84 public boolean openItem( 85 ItemDetails<String> doc, @ViewType int type, @ViewType int fallback) { 86 throw new UnsupportedOperationException(); 87 } 88 89 @Override 90 public void initLocation(Intent intent) { 91 throw new UnsupportedOperationException(); 92 } 93 94 @Override 95 protected void launchToDefaultLocation() { 96 throw new UnsupportedOperationException(); 97 } 98 }; 99 } 100 101 @Test testOpenNewWindow()102 public void testOpenNewWindow() { 103 DocumentStack path = new DocumentStack(Roots.create("123")); 104 mHandler.openInNewWindow(path); 105 106 Intent expected = LauncherActivity.createLaunchIntent(mActivity); 107 expected.putExtra(Shared.EXTRA_STACK, (Parcelable) path); 108 Intent actual = mActivity.startActivity.getLastValue(); 109 assertEquals(expected.toString(), actual.toString()); 110 } 111 112 @Test testOpensContainerDocuments_OpenFolderInSearch_JumpsToNewLocation()113 public void testOpensContainerDocuments_OpenFolderInSearch_JumpsToNewLocation() 114 throws Exception { 115 if (!mEnv.features.isLaunchToDocumentEnabled()) { 116 return; 117 } 118 119 mEnv.populateStack(); 120 121 mEnv.searchViewManager.isSearching = true; 122 mEnv.docs.nextIsDocumentsUri = true; 123 mEnv.docs.nextPath = new Path( 124 TestProvidersAccess.HOME.rootId, 125 Arrays.asList(TestEnv.FOLDER_1.documentId, TestEnv.FOLDER_2.documentId)); 126 mEnv.docs.nextDocuments = Arrays.asList(TestEnv.FOLDER_1, TestEnv.FOLDER_2); 127 128 mHandler.openContainerDocument(TestEnv.FOLDER_2); 129 130 mEnv.beforeAsserts(); 131 132 assertEquals(mEnv.docs.nextPath.getPath().size(), mEnv.state.stack.size()); 133 assertEquals(TestEnv.FOLDER_2, mEnv.state.stack.pop()); 134 assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.pop()); 135 } 136 137 138 @Test testOpensContainerDocuments_ClickFolderInSearch_PushToRootDoc_NoFindPathSupport()139 public void testOpensContainerDocuments_ClickFolderInSearch_PushToRootDoc_NoFindPathSupport() 140 throws Exception { 141 mEnv.populateStack(); 142 143 mEnv.searchViewManager.isSearching = true; 144 mEnv.docs.nextIsDocumentsUri = true; 145 mEnv.docs.nextDocuments = Arrays.asList(TestEnv.FOLDER_1, TestEnv.FOLDER_2); 146 147 mHandler.openContainerDocument(TestEnv.FOLDER_2); 148 149 mEnv.beforeAsserts(); 150 151 assertEquals(2, mEnv.state.stack.size()); 152 assertEquals(TestEnv.FOLDER_2, mEnv.state.stack.pop()); 153 assertEquals(TestEnv.FOLDER_0, mEnv.state.stack.pop()); 154 } 155 156 @Test testOpensContainerDocuments_ClickArchiveInSearch_opensArchiveInArchiveProvider()157 public void testOpensContainerDocuments_ClickArchiveInSearch_opensArchiveInArchiveProvider() 158 throws Exception { 159 if (!mEnv.features.isLaunchToDocumentEnabled()) { 160 return; 161 } 162 163 mEnv.populateStack(); 164 165 mEnv.searchViewManager.isSearching = true; 166 mEnv.docs.nextIsDocumentsUri = true; 167 mEnv.docs.nextPath = new Path( 168 TestProvidersAccess.HOME.rootId, 169 Arrays.asList(TestEnv.FOLDER_1.documentId, TestEnv.FOLDER_2.documentId, 170 TestEnv.FILE_ARCHIVE.documentId)); 171 mEnv.docs.nextDocuments = Arrays.asList( 172 TestEnv.FOLDER_1, TestEnv.FOLDER_2, TestEnv.FILE_ARCHIVE); 173 mEnv.docs.nextDocument = TestEnv.FILE_IN_ARCHIVE; 174 175 mHandler.openContainerDocument(TestEnv.FILE_ARCHIVE); 176 177 mEnv.beforeAsserts(); 178 179 assertEquals(mEnv.docs.nextPath.getPath().size(), mEnv.state.stack.size()); 180 assertEquals(TestEnv.FILE_IN_ARCHIVE, mEnv.state.stack.pop()); 181 assertEquals(TestEnv.FOLDER_2, mEnv.state.stack.pop()); 182 assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.pop()); 183 } 184 185 @Test testOpensDocument_ExceptionIfAlreadyInStack()186 public void testOpensDocument_ExceptionIfAlreadyInStack() throws Exception { 187 mEnv.populateStack(); 188 try { 189 mEnv.state.stack.push(TestEnv.FOLDER_0); 190 fail("Should have thrown IllegalArgumentException."); 191 } catch (IllegalArgumentException expected) { 192 } 193 } 194 195 @Test testLaunchToDocuments()196 public void testLaunchToDocuments() throws Exception { 197 if (!mEnv.features.isLaunchToDocumentEnabled()) { 198 return; 199 } 200 201 mEnv.docs.nextIsDocumentsUri = true; 202 mEnv.docs.nextPath = new Path( 203 TestProvidersAccess.HOME.rootId, 204 Arrays.asList( 205 TestEnv.FOLDER_0.documentId, 206 TestEnv.FOLDER_1.documentId, 207 TestEnv.FILE_GIF.documentId)); 208 mEnv.docs.nextDocuments = 209 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1, TestEnv.FILE_GIF); 210 211 mActivity.refreshCurrentRootAndDirectory.assertNotCalled(); 212 assertTrue(mHandler.launchToDocument(TestEnv.FILE_GIF.derivedUri)); 213 214 mEnv.beforeAsserts(); 215 216 DocumentStackAsserts.assertEqualsTo(mEnv.state.stack, TestProvidersAccess.HOME, 217 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1)); 218 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 219 } 220 221 @Test testLaunchToDocuments_convertsTreeUriToDocumentUri()222 public void testLaunchToDocuments_convertsTreeUriToDocumentUri() throws Exception { 223 if (!mEnv.features.isLaunchToDocumentEnabled()) { 224 return; 225 } 226 227 mEnv.docs.nextIsDocumentsUri = true; 228 mEnv.docs.nextPath = new Path( 229 TestProvidersAccess.HOME.rootId, 230 Arrays.asList( 231 TestEnv.FOLDER_0.documentId, 232 TestEnv.FOLDER_1.documentId, 233 TestEnv.FILE_GIF.documentId)); 234 mEnv.docs.nextDocuments = 235 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1, TestEnv.FILE_GIF); 236 237 final Uri treeBaseUri = DocumentsContract.buildTreeDocumentUri( 238 TestProvidersAccess.HOME.authority, TestEnv.FOLDER_0.documentId); 239 final Uri treeDocUri = DocumentsContract.buildDocumentUriUsingTree( 240 treeBaseUri, TestEnv.FILE_GIF.documentId); 241 assertTrue(mHandler.launchToDocument(treeDocUri)); 242 243 mEnv.beforeAsserts(); 244 245 DocumentStackAsserts.assertEqualsTo(mEnv.state.stack, TestProvidersAccess.HOME, 246 Arrays.asList(TestEnv.FOLDER_0, TestEnv.FOLDER_1)); 247 mEnv.docs.lastUri.assertLastArgument(TestEnv.FILE_GIF.derivedUri); 248 mActivity.refreshCurrentRootAndDirectory.assertCalled(); 249 } 250 251 @Test testLoadChildrenDocuments()252 public void testLoadChildrenDocuments() throws Exception { 253 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 254 mEnv.state.stack.push(TestEnv.FOLDER_0); 255 256 mEnv.state.sortModel.sortByUser( 257 SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); 258 259 mEnv.mockProviders.get(TestProvidersAccess.HOME.authority) 260 .setNextChildDocumentsReturns(TestEnv.FILE_APK, TestEnv.FILE_GIF); 261 262 mHandler.loadDocumentsForCurrentStack(); 263 CountDownLatch latch = new CountDownLatch(1); 264 mEnv.model.addUpdateListener(event -> latch.countDown()); 265 mActivity.supportLoaderManager.runAsyncTaskLoader(AbstractActionHandler.LOADER_ID); 266 267 latch.await(1, TimeUnit.SECONDS); 268 assertEquals(2, mEnv.model.getItemCount()); 269 String[] modelIds = mEnv.model.getModelIds(); 270 assertEquals(TestEnv.FILE_APK, mEnv.model.getDocument(modelIds[0])); 271 assertEquals(TestEnv.FILE_GIF, mEnv.model.getDocument(modelIds[1])); 272 } 273 274 @Test testLoadChildrenDocuments_failsWithNonRecentsAndEmptyStack()275 public void testLoadChildrenDocuments_failsWithNonRecentsAndEmptyStack() throws Exception { 276 mEnv.state.stack.changeRoot(TestProvidersAccess.HOME); 277 278 mEnv.mockProviders.get(TestProvidersAccess.HOME.authority) 279 .setNextChildDocumentsReturns(TestEnv.FILE_APK, TestEnv.FILE_GIF); 280 281 TestEventHandler<Model.Update> listener = new TestEventHandler<>(); 282 mEnv.model.addUpdateListener(listener::accept); 283 284 mHandler.loadDocumentsForCurrentStack(); 285 286 assertTrue(listener.getLastValue().hasException()); 287 } 288 289 @Test testPreviewItem_throwException()290 public void testPreviewItem_throwException() throws Exception { 291 try { 292 mHandler.previewItem(null); 293 fail("Should have thrown UnsupportedOperationException."); 294 } catch (UnsupportedOperationException expected) { 295 } 296 } 297 } 298