Commit c59ff6f1 authored by Christian Sadilek's avatar Christian Sadilek
Browse files

Closes #7103 #5217: Move queued download state to browser store

parent ff020476
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -558,3 +558,23 @@ sealed class MediaAction : BrowserAction() {
        val aggregate: MediaState.Aggregate
    ) : MediaAction()
}

/**
 * [BrowserAction] implementations related to updating the global download state.
 */
sealed class DownloadAction : BrowserAction() {
    /**
     * Updates the [BrowserState] to track the provided [download] as queued.
     */
    data class QueueDownloadAction(val download: DownloadState) : DownloadAction()

    /**
     * Updates the [BrowserState] to remove the queued download with the provided [downloadId].
     */
    data class RemoveQueuedDownloadAction(val downloadId: Long) : DownloadAction()

    /**
     * Updates the [BrowserState] to remove all queued downloads.
     */
    object RemoveAllQueuedDownloadsAction : DownloadAction()
}
+2 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ package mozilla.components.browser.state.reducer
import mozilla.components.browser.state.action.BrowserAction
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.action.CustomTabListAction
import mozilla.components.browser.state.action.DownloadAction
import mozilla.components.browser.state.action.EngineAction
import mozilla.components.browser.state.action.MediaAction
import mozilla.components.browser.state.action.ReaderAction
@@ -39,6 +40,7 @@ internal object BrowserStateReducer {
            is TrackingProtectionAction -> TrackingProtectionStateReducer.reduce(state, action)
            is WebExtensionAction -> WebExtensionReducer.reduce(state, action)
            is MediaAction -> MediaReducer.reduce(state, action)
            is DownloadAction -> DownloadStateReducer.reduce(state, action)
        }
    }
}
+28 −0
Original line number Diff line number Diff line
/* 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 mozilla.components.browser.state.reducer

import mozilla.components.browser.state.action.DownloadAction
import mozilla.components.browser.state.state.BrowserState

internal object DownloadStateReducer {

    /**
     * [DownloadAction] Reducer function for modifying [BrowserState.queuedDownloads].
     */
    fun reduce(state: BrowserState, action: DownloadAction): BrowserState {
        return when (action) {
            is DownloadAction.QueueDownloadAction -> {
                state.copy(queuedDownloads = state.queuedDownloads + (action.download.id to action.download))
            }
            is DownloadAction.RemoveQueuedDownloadAction -> {
                state.copy(queuedDownloads = state.queuedDownloads - action.downloadId)
            }
            is DownloadAction.RemoveAllQueuedDownloadsAction -> {
                state.copy(queuedDownloads = emptyMap())
            }
        }
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

package mozilla.components.browser.state.state

import mozilla.components.browser.state.state.content.DownloadState
import mozilla.components.lib.state.State

/**
@@ -16,11 +17,13 @@ import mozilla.components.lib.state.State
 * The extensions here represent the default values for all [BrowserState.extensions] and can
 * be overridden per [SessionState].
 * @property media The state of all media elements and playback states for all tabs.
 * @property queuedDownloads queued downloads ([DownloadState]s) mapped to their IDs.
 */
data class BrowserState(
    val tabs: List<TabSessionState> = emptyList(),
    val selectedTabId: String? = null,
    val customTabs: List<CustomTabSessionState> = emptyList(),
    val extensions: Map<String, WebExtensionState> = emptyMap(),
    val media: MediaState = MediaState()
    val media: MediaState = MediaState(),
    val queuedDownloads: Map<Long, DownloadState> = emptyMap()
) : State
+61 −0
Original line number Diff line number Diff line
/* 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 mozilla.components.browser.state.action

import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.content.DownloadState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.support.test.ext.joinBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class DownloadActionTest {

    @Test
    fun `QueueDownloadAction adds download`() {
        val store = BrowserStore(BrowserState())

        val download1 = DownloadState("https://mozilla.org/download1", destinationDirectory = "")
        store.dispatch(DownloadAction.QueueDownloadAction(download1)).joinBlocking()
        assertEquals(download1, store.state.queuedDownloads[download1.id])
        assertEquals(1, store.state.queuedDownloads.size)

        val download2 = DownloadState("https://mozilla.org/download2", destinationDirectory = "")
        store.dispatch(DownloadAction.QueueDownloadAction(download2)).joinBlocking()
        assertEquals(download2, store.state.queuedDownloads[download2.id])
        assertEquals(2, store.state.queuedDownloads.size)
    }

    @Test
    fun `RemoveQueuedDownloadAction removes download`() {
        val store = BrowserStore(BrowserState())

        val download = DownloadState("https://mozilla.org/download1", destinationDirectory = "")
        store.dispatch(DownloadAction.QueueDownloadAction(download)).joinBlocking()
        assertEquals(download, store.state.queuedDownloads[download.id])
        assertFalse(store.state.queuedDownloads.isEmpty())

        store.dispatch(DownloadAction.RemoveQueuedDownloadAction(download.id)).joinBlocking()
        assertTrue(store.state.queuedDownloads.isEmpty())
    }

    @Test
    fun `RemoveAllQueuedDownloadsAction removes all downloads`() {
        val store = BrowserStore(BrowserState())

        val download = DownloadState("https://mozilla.org/download1", destinationDirectory = "")
        val download2 = DownloadState("https://mozilla.org/download2", destinationDirectory = "")
        store.dispatch(DownloadAction.QueueDownloadAction(download)).joinBlocking()
        store.dispatch(DownloadAction.QueueDownloadAction(download2)).joinBlocking()

        assertFalse(store.state.queuedDownloads.isEmpty())
        assertEquals(2, store.state.queuedDownloads.size)

        store.dispatch(DownloadAction.RemoveAllQueuedDownloadsAction).joinBlocking()
        assertTrue(store.state.queuedDownloads.isEmpty())
    }
}
Loading