Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 618f7c68 authored by Bo Majewski's avatar Bo Majewski Committed by Android (Google) Code Review
Browse files

Merge "[DocsUI, Search]: Fix and expand search tests." into main

parents 07bbaa7b 44f52ee0
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -52,7 +52,19 @@ data class LoaderTestParams(
    val otherArgs: Bundle,
    // The number of files that are expected, for the above parameters, to be found by a loader.
    val expectedCount: Int,
)
) {
    override fun toString(): String {
        var base = "query '$query'"
        if (lastModifiedDelta != null) {
            val durationInMs = lastModifiedDelta.toSeconds()
            base = "$base, modified in the last ${durationInMs}s"
        }
        if (!otherArgs.isEmpty) {
            base = "$base, and $otherArgs"
        }
        return "$base, expecting $expectedCount matches"
    }
}

/**
 * Common base class for search and folder loaders.
@@ -63,7 +75,7 @@ open class BaseLoaderTest {
    lateinit var mTestConfigStore: TestConfigStore

    @Before
    open fun setUp() {
    fun setUp() {
        mEnv = TestEnv.create()
        mTestConfigStore = TestConfigStore()
        mEnv.state.configStore = mTestConfigStore
+1 −2
Original line number Diff line number Diff line
@@ -62,8 +62,7 @@ class FolderLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes
    lateinit var queryOptions: QueryOptions

    @Before
    override fun setUp() {
        super.setUp()
    fun setUpTest() {
        queryOptions =
            QueryOptions(
                TOTAL_FILE_COUNT,
+145 −88
Original line number Diff line number Diff line
@@ -21,20 +21,24 @@ import android.provider.DocumentsContract
import androidx.test.filters.SmallTest
import com.android.documentsui.ContentLock
import com.android.documentsui.LockingContentObserver
import com.android.documentsui.Model
import com.android.documentsui.base.DocumentInfo
import com.android.documentsui.base.FolderInfo
import com.android.documentsui.flags.Flags.FLAG_USE_SEARCH_V2_READ_ONLY
import com.android.documentsui.rules.CheckAndForceMaterial3Flag
import com.android.documentsui.sorting.SortModel
import com.android.documentsui.testing.TestFeatures
import com.android.documentsui.testing.TestFileTypeLookup
import com.android.documentsui.testing.TestProvidersAccess
import com.google.common.truth.Expect
import java.time.Duration
import java.util.Locale
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import junit.framework.Assert.assertEquals
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.experimental.runners.Enclosed
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters
@@ -47,9 +51,13 @@ fun createQueryArgs(vararg mimeTypes: String): Bundle {
    return args
}

@RunWith(Parameterized::class)
@RunWith(Enclosed::class)
@SmallTest
class SearchLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTest() {
class SearchLoaderTest {

    // Collection of tests that are parametrized by query, duration, and MIME type.
    @RunWith(Parameterized::class)
    class ParametrizedTests(private val testParams: LoaderTestParams) : BaseLoaderTest() {
        lateinit var mExecutor: ExecutorService
        val mContentLock = ContentLock()
        val mContentObserver = LockingContentObserver(mContentLock) {}
@@ -72,9 +80,11 @@ class SearchLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes
        @get:Rule
        val checkFlags = CheckAndForceMaterial3Flag()

        @get:Rule
        val expect: Expect = Expect.create()

        @Before
    override fun setUp() {
        super.setUp()
        fun setUpTest() {
            mExecutor = Executors.newSingleThreadExecutor()
        }

@@ -94,8 +104,7 @@ class SearchLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes
                testParams.otherArgs,
            )

        val folderInfo =
            listOf(
            val folderInfo = listOf(
                FolderInfo(
                    TestProvidersAccess.DOWNLOADS.rootId,
                    TestProvidersAccess.DOWNLOADS.authority
@@ -114,52 +123,100 @@ class SearchLoaderTest(private val testParams: LoaderTestParams) : BaseLoaderTes
                mExecutor,
            )
            val directoryResult = loader.loadInBackground()
        assertEquals(testParams.expectedCount, getFileCount(directoryResult))
            expect.that(getFileCount(directoryResult)).isEqualTo(testParams.expectedCount)
        }
    }

    // Collection of plain tests that do not use parameters.
    class PlainTests : BaseLoaderTest() {
        @get:Rule
        val checkFlags = CheckAndForceMaterial3Flag()

        @get:Rule
        val expect: Expect = Expect.create()

        lateinit var mExecutor: ExecutorService
        val mContentLock = ContentLock()
        val mContentObserver = LockingContentObserver(mContentLock) {}

        @Before
        fun setUpTest() {
            mExecutor = Executors.newSingleThreadExecutor()
        }

        fun generateDocuments(
            count: Int,
            suffixOffset: Int,
            extensions: Array<String>
        ): Array<DocumentInfo> {
            return Array(count) { i ->
                val suffix = String.format(Locale.US, "%05d", 2 * i + suffixOffset)
                val ext = extensions[i % extensions.size]
                mEnv.model.createFile("document-$suffix.$ext")
            }
        }

        /**
         * Checks that the merging, filtering and sorting of results works correctly. We set up
         * two providers: home and pickles storage. They get files with names that have a zipper
         * like pattern, when sorted. Here we are checking if merging two cursors, with filtering
         * produces the expected result.
         */
        @Test
    @RequiresFlagsEnabled(FLAG_USE_SEARCH_V2_READ_ONLY)
    @Ignore("b/397095797")
    fun testBlankQueryAndRecency() {
        val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId)
        val folderInfo =
            listOf(
                FolderInfo(
                    TestProvidersAccess.DOWNLOADS.rootId,
                    TestProvidersAccess.DOWNLOADS.authority
                )
        fun testValidateMergeFilterSort() {
            val fileCount = 200
            val maxCount = fileCount / 2
            mEnv.mockProviders.apply {
                // Pickles documents have IDs 0, 2, 4, .., 398. Half of the documents are images,
                // the other half are documents (PDFs).
                get(TestProvidersAccess.PICKLES.authority)!!.setNextChildDocumentsReturns(
                    *generateDocuments(fileCount, 0, arrayOf("png", "pdf"))
                )
        val noLastModifiedQueryOptions =
            QueryOptions(10, null, null, true, arrayOf("*/*"), Bundle())

        // Blank query and no last modified duration is invalid.
        assertThrows(IllegalArgumentException::class.java) {
            SearchLoader(
                mActivity,
                userIds,
                TestFileTypeLookup(),
                mContentObserver,
                folderInfo,
                "",
                noLastModifiedQueryOptions,
                mEnv.state.sortModel,
                mExecutor,
                // Home documents have IDs 1, 3, 5, ... 399. Half of the documents are images,
                // the other half are videos.
                get(TestProvidersAccess.HOME.authority)!!.setNextChildDocumentsReturns(
                    *generateDocuments(fileCount, 1, arrayOf("png", "avi"))
                )
            }

        // Null query and no last modified duration is invalid.
        assertThrows(IllegalArgumentException::class.java) {
            SearchLoader(
            // Setup the sort model so that results are sorted by their name.
            val sortModel = SortModel.createModel()
            sortModel.setDefaultDimension(SortModel.SORT_DIMENSION_ID_TITLE)
            val folderInfo = listOf(
                FolderInfo(
                    TestProvidersAccess.PICKLES.rootId,
                    TestProvidersAccess.PICKLES.authority
                ),
                FolderInfo(
                    TestProvidersAccess.HOME.rootId,
                    TestProvidersAccess.HOME.authority
                ),
            )
            val loader = SearchLoader(
                mActivity,
                userIds,
                listOf(TestProvidersAccess.PICKLES.userId, TestProvidersAccess.HOME.userId),
                TestFileTypeLookup(),
                mContentObserver,
                folderInfo,
                null,
                noLastModifiedQueryOptions,
                mEnv.state.sortModel,
                "document-",
                QueryOptions(maxCount, null, null, false, arrayOf("image/png"), Bundle()),
                sortModel,
                mExecutor,
            )
            val result = loader.loadInBackground()
            expect.that(result?.cursor?.getCount()).isEqualTo(maxCount)
            // We expect a perfect mix of documents from PICKLES and HOME. Pickles has odd indices
            // Home has even indices. However, the filtering cursor should take out all non-images
            // leaving us with 0, 4, 8, ..., from PICKLES and 1, 5, 9, ... from HOME.
            val model = Model(TestFeatures())
            model.update(result)
            val names = model.modelIds.map {
                model.getDocument(it)!!.displayName
            }
            expect.that(names).isEqualTo((0..maxCount - 1).map {
                val index = String.format(Locale.US, "%05d", 4 * (it / 2) + (it % 2))
                "document-$index.png"
            })
        }
    }
}