From 3139337d7fad52499bc7bc1a56a8c09185a3bc43 Mon Sep 17 00:00:00 2001 From: Jocelyne Abi Haidar <38375996+joc-a@users.noreply.github.com> Date: Mon, 2 Nov 2020 18:06:30 +0200 Subject: [PATCH] [fenix] For https://github.com/mozilla-mobile/fenix/issues/15931: Sort Downloads from newest to oldest (https://github.com/mozilla-mobile/fenix/pull/15939) --- .../library/downloads/DownloadFragment.kt | 33 ++++-- .../library/downloads/DownloadFragmentTest.kt | 107 ++++++++++++++++++ 2 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/library/downloads/DownloadFragmentTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt b/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt index 95effa563..89b64c88d 100644 --- a/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt @@ -8,8 +8,10 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.annotation.VisibleForTesting import kotlinx.android.synthetic.main.fragment_downloads.view.* import kotlinx.coroutines.ExperimentalCoroutinesApi +import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.content.DownloadState import mozilla.components.feature.downloads.AbstractFetchDownloadService import mozilla.components.lib.state.ext.consumeFrom @@ -37,18 +39,7 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan ): View? { val view = inflater.inflate(R.layout.fragment_downloads, container, false) - val items = requireComponents.core.store.state.downloads.map { - DownloadItem( - it.value.id.toString(), - it.value.fileName, - it.value.filePath, - it.value.contentLength.toString(), - it.value.contentType, - it.value.status - ) - }.filter { - it.status == DownloadState.Status.COMPLETED - }.filterNotExistsOnDisk() + val items = provideDownloads(requireComponents.core.store.state) downloadStore = StoreProvider.get(this) { DownloadFragmentStore( @@ -71,6 +62,24 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan return view } + @VisibleForTesting + internal fun provideDownloads(state: BrowserState): List { + return state.downloads.values + .sortedByDescending { it.createdTime } // sort from newest to oldest + .map { + DownloadItem( + it.id, + it.fileName, + it.filePath, + it.contentLength.toString(), + it.contentType, + it.status + ) + }.filter { + it.status == DownloadState.Status.COMPLETED + }.filterNotExistsOnDisk() + } + override val selectedItems get() = downloadStore.state.mode.selectedItems override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadFragmentTest.kt new file mode 100644 index 000000000..ecb19e78c --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadFragmentTest.kt @@ -0,0 +1,107 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.library.downloads + +import android.os.Environment +import io.mockk.every +import io.mockk.mockk +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.content.DownloadState +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import java.io.File + +@Suppress("DEPRECATION") +@RunWith(FenixRobolectricTestRunner::class) +class DownloadFragmentTest { + + @Test + fun `downloads are sorted from newest to oldest`() { + + val downloadedFile1 = File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), + "1.pdf" + ) + + val downloadedFile2 = File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), + "2.pdf" + ) + + val downloadedFile3 = File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), + "3.pdf" + ) + + downloadedFile1.createNewFile() + downloadedFile2.createNewFile() + downloadedFile3.createNewFile() + + val fragment = DownloadFragment() + + val expectedList = listOf( + DownloadItem( + "3", + "3.pdf", + downloadedFile3.path, + "null", + null, + DownloadState.Status.COMPLETED + ), + DownloadItem( + "2", + "2.pdf", + downloadedFile2.path, + "null", + null, + DownloadState.Status.COMPLETED + ), + DownloadItem( + "1", + "1.pdf", + downloadedFile1.path, + "null", + null, + DownloadState.Status.COMPLETED + ) + ) + + val state: BrowserState = mockk(relaxed = true) + + every { state.downloads } returns mapOf( + "1" to DownloadState( + id = "1", + createdTime = 1, + url = "url", + fileName = "1.pdf", + status = DownloadState.Status.COMPLETED + ), + "2" to DownloadState( + id = "2", + createdTime = 2, + url = "url", + fileName = "2.pdf", + status = DownloadState.Status.COMPLETED + ), + "3" to DownloadState( + id = "3", + createdTime = 3, + url = "url", + fileName = "3.pdf", + status = DownloadState.Status.COMPLETED + ) + ) + + val list = fragment.provideDownloads(state) + + assertEquals(expectedList, list) + + downloadedFile1.delete() + downloadedFile2.delete() + downloadedFile3.delete() + } +}