blob: c52dbd3dec409e9fff92bdd743d66d48a730f1a9 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.documentsui;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.sorting.SortDimension;
import com.android.documentsui.sorting.SortModel;
import com.android.documentsui.testing.ActivityManagers;
import com.android.documentsui.testing.TestEnv;
import com.android.documentsui.testing.TestFileTypeLookup;
import com.android.documentsui.testing.TestImmediateExecutor;
import com.android.documentsui.testing.TestProvidersAccess;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class GlobalSearchLoaderTest {
private static final String SEARCH_STRING = "freddy";
private static int FILE_FLAG = Document.FLAG_SUPPORTS_MOVE | Document.FLAG_SUPPORTS_DELETE
| Document.FLAG_SUPPORTS_REMOVE;
private TestEnv mEnv;
private TestActivity mActivity;
private GlobalSearchLoader mLoader;
private Bundle mQueryArgs = new Bundle();
@Before
public void setUp() {
mEnv = TestEnv.create();
mActivity = TestActivity.create(mEnv);
mActivity.activityManager = ActivityManagers.create(false);
mEnv.state.action = State.ACTION_BROWSE;
mEnv.state.acceptMimes = new String[]{"*/*"};
mQueryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, SEARCH_STRING);
mLoader = new GlobalSearchLoader(mActivity, mEnv.providers, mEnv.state,
TestImmediateExecutor.createLookup(), new TestFileTypeLookup(), mQueryArgs,
TestProvidersAccess.USER_ID);
final DocumentInfo doc = mEnv.model.createFile(SEARCH_STRING + ".jpg", FILE_FLAG);
doc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.DOWNLOADS.authority)
.setNextChildDocumentsReturns(doc);
TestProvidersAccess.DOWNLOADS.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
}
@After
public void tearDown() {
TestProvidersAccess.DOWNLOADS.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
}
@Test
public void testNotSearchableRoot_beIgnored() {
TestProvidersAccess.PICKLES.flags |= DocumentsContract.Root.FLAG_LOCAL_ONLY;
assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.PICKLES));
TestProvidersAccess.PICKLES.flags &= ~DocumentsContract.Root.FLAG_LOCAL_ONLY;
}
@Test
public void testNotLocalOnlyRoot_beIgnored() {
TestProvidersAccess.PICKLES.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.PICKLES));
TestProvidersAccess.PICKLES.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
}
@Test
public void testShowAdvance_storageRoot_beIgnored() {
TestProvidersAccess.HOME.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.HOME));
TestProvidersAccess.HOME.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH);
}
@Test
public void testCrossProfileRoot_notInTextSearch_beIgnored() {
mEnv.state.supportsCrossProfile = true;
mQueryArgs.remove(DocumentsContract.QUERY_ARG_DISPLAY_NAME);
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.OtherUser.USER_ID;
assertThat(mLoader.shouldIgnoreRoot(TestProvidersAccess.DOWNLOADS)).isTrue();
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.USER_ID;
}
@Test
public void testCrossProfileRoot_inTextSearch_beIncluded() {
mEnv.state.supportsCrossProfile = true;
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.OtherUser.USER_ID;
assertThat(mLoader.shouldIgnoreRoot(TestProvidersAccess.DOWNLOADS)).isFalse();
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.USER_ID;
}
@Test
public void testSearchResult_includeDirectory() {
final DocumentInfo doc = mEnv.model.createFolder(SEARCH_STRING);
doc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.DOWNLOADS.authority)
.setNextChildDocumentsReturns(doc);
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertEquals(1, c.getCount());
c.moveToNext();
final String mimeType = c.getString(c.getColumnIndex(Document.COLUMN_MIME_TYPE));
assertEquals(Document.MIME_TYPE_DIR, mimeType);
}
@Test
public void testShowOrHideHiddenFiles() {
final DocumentInfo doc1 = mEnv.model.createFile(".test" + SEARCH_STRING);
final DocumentInfo doc2 = mEnv.model.createFile("test" + SEARCH_STRING);
doc1.documentId = ".test";
doc2.documentId = "parent_folder/.hidden_folder/test";
mEnv.mockProviders.get(TestProvidersAccess.DOWNLOADS.authority)
.setNextChildDocumentsReturns(doc1, doc2);
assertEquals(false, mLoader.mState.showHiddenFiles);
DirectoryResult result = mLoader.loadInBackground();
assertEquals(0, result.getCursor().getCount());
mLoader.mState.showHiddenFiles = true;
result = mLoader.loadInBackground();
assertEquals(2, result.getCursor().getCount());
}
@Test
public void testSearchResult_isNotMovable() {
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertEquals(1, c.getCount());
c.moveToNext();
final int flags = c.getInt(c.getColumnIndex(Document.COLUMN_FLAGS));
assertEquals(0, flags & Document.FLAG_SUPPORTS_DELETE);
assertEquals(0, flags & Document.FLAG_SUPPORTS_REMOVE);
assertEquals(0, flags & Document.FLAG_SUPPORTS_MOVE);
}
@Test
public void testSearchResult_includeDirectory_excludedOtherUsers() {
mEnv.state.canShareAcrossProfile = false;
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.OtherUser.USER_ID;
TestProvidersAccess.PICKLES.flags |= (DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
final DocumentInfo currentUserDoc = mEnv.model.createFile(
SEARCH_STRING + "_currentUser.pdf");
currentUserDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.DOWNLOADS.authority)
.setNextChildDocumentsReturns(currentUserDoc);
final DocumentInfo otherUserDoc = mEnv.model.createFile(SEARCH_STRING + "_otherUser.png");
otherUserDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.PICKLES.authority)
.setNextChildDocumentsReturns(otherUserDoc);
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertThat(c.getCount()).isEqualTo(1);
c.moveToNext();
final String docName = c.getString(c.getColumnIndex(Document.COLUMN_DISPLAY_NAME));
assertThat(docName).contains("currentUser");
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
}
@Test
public void testSearchResult_includeSearchString() {
final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
pdfDoc.lastModified = System.currentTimeMillis();
final DocumentInfo apkDoc = mEnv.model.createFile(SEARCH_STRING + ".apk");
apkDoc.lastModified = System.currentTimeMillis();
final DocumentInfo testApkDoc = mEnv.model.createFile("test.apk");
testApkDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.DOWNLOADS.authority)
.setNextChildDocumentsReturns(pdfDoc, apkDoc, testApkDoc);
mEnv.state.sortModel.sortByUser(
SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertEquals(2, c.getCount());
c.moveToNext();
String displayName = c.getString(c.getColumnIndex(Document.COLUMN_DISPLAY_NAME));
assertTrue(displayName.contains(SEARCH_STRING));
c.moveToNext();
displayName = c.getString(c.getColumnIndex(Document.COLUMN_DISPLAY_NAME));
assertTrue(displayName.contains(SEARCH_STRING));
}
@Test
public void testSearchResult_includeDifferentRoot() {
final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
pdfDoc.lastModified = System.currentTimeMillis();
final DocumentInfo apkDoc = mEnv.model.createFile(SEARCH_STRING + ".apk");
apkDoc.lastModified = System.currentTimeMillis();
final DocumentInfo testApkDoc = mEnv.model.createFile("test.apk");
testApkDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.PICKLES.authority)
.setNextChildDocumentsReturns(pdfDoc, apkDoc, testApkDoc);
TestProvidersAccess.PICKLES.flags |= (DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
mEnv.state.sortModel.sortByUser(
SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertEquals(3, c.getCount());
TestProvidersAccess.PICKLES.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
}
@Test
public void testSearchResult_includeCurrentUserRootOnly() {
mEnv.state.canShareAcrossProfile = false;
mEnv.state.supportsCrossProfile = true;
final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
pdfDoc.lastModified = System.currentTimeMillis();
final DocumentInfo apkDoc = mEnv.model.createFile(SEARCH_STRING + ".apk");
apkDoc.lastModified = System.currentTimeMillis();
final DocumentInfo testApkDoc = mEnv.model.createFile("test.apk");
testApkDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.PICKLES.authority)
.setNextChildDocumentsReturns(pdfDoc, apkDoc, testApkDoc);
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.OtherUser.USER_ID;
TestProvidersAccess.PICKLES.flags |= (DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
mEnv.state.sortModel.sortByUser(
SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertEquals(1, c.getCount());
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
}
@Test
public void testSearchResult_includeBothUsersRoots() {
mEnv.state.canShareAcrossProfile = true;
mEnv.state.supportsCrossProfile = true;
final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
pdfDoc.lastModified = System.currentTimeMillis();
final DocumentInfo apkDoc = mEnv.model.createFile(SEARCH_STRING + ".apk");
apkDoc.lastModified = System.currentTimeMillis();
final DocumentInfo testApkDoc = mEnv.model.createFile("test.apk");
testApkDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.PICKLES.authority)
.setNextChildDocumentsReturns(pdfDoc, apkDoc, testApkDoc);
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.OtherUser.USER_ID;
TestProvidersAccess.PICKLES.flags |= (DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
mEnv.state.sortModel.sortByUser(
SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
final DirectoryResult result = mLoader.loadInBackground();
final Cursor c = result.getCursor();
assertEquals(3, c.getCount());
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
}
@Test
public void testSearchResult_emptyCurrentUsersRoot() {
mEnv.state.canShareAcrossProfile = false;
mEnv.state.supportsCrossProfile = true;
final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
pdfDoc.lastModified = System.currentTimeMillis();
mEnv.mockProviders.get(TestProvidersAccess.PICKLES.authority)
.setNextChildDocumentsReturns(pdfDoc);
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.OtherUser.USER_ID;
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.OtherUser.USER_ID;
TestProvidersAccess.PICKLES.flags |= (DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
mEnv.state.sortModel.sortByUser(
SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
final DirectoryResult result = mLoader.loadInBackground();
assertThat(result.getCursor().getCount()).isEqualTo(0);
// We don't expect exception even if all roots are from other users.
assertThat(result.exception).isNull();
TestProvidersAccess.DOWNLOADS.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.userId = TestProvidersAccess.USER_ID;
TestProvidersAccess.PICKLES.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
| DocumentsContract.Root.FLAG_LOCAL_ONLY);
}
}