Skip to content

Commit

Permalink
Add tests for initial collection creation state
Browse files Browse the repository at this point in the history
  • Loading branch information
NotWoods authored and ekager committed Sep 29, 2020
1 parent 01fdb4a commit f2a6aa4
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.navArgs
Expand All @@ -22,10 +21,7 @@ import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.ext.getMediaStateForSession
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.home.Tab

@ExperimentalCoroutinesApi
class CollectionCreationFragment : DialogFragment() {
Expand All @@ -47,27 +43,16 @@ class CollectionCreationFragment : DialogFragment() {
val view = inflater.inflate(R.layout.fragment_create_collection, container, false)
val args: CollectionCreationFragmentArgs by navArgs()

val store = requireComponents.core.store
val publicSuffixList = requireComponents.publicSuffixList
val tabs = store.state.getTabs(args.tabIds, publicSuffixList)
val selectedTabs = if (args.selectedTabIds != null) {
store.state.getTabs(args.selectedTabIds, publicSuffixList).toSet()
} else {
if (tabs.size == 1) setOf(tabs.first()) else emptySet()
}

val tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections
val selectedTabCollection = args.selectedTabCollectionId
.let { id -> tabCollections.firstOrNull { it.id == id } }

collectionCreationStore = StoreProvider.get(this) {
CollectionCreationStore(
CollectionCreationState(
tabs = tabs,
selectedTabs = selectedTabs,
createInitialCollectionCreationState(
browserState = requireComponents.core.store.state,
tabCollectionStorage = requireComponents.core.tabCollectionStorage,
publicSuffixList = requireComponents.publicSuffixList,
saveCollectionStep = args.saveCollectionStep,
tabCollections = tabCollections,
selectedTabCollection = selectedTabCollection
tabIds = args.tabIds,
selectedTabIds = args.selectedTabIds,
selectedTabCollectionId = args.selectedTabCollectionId
)
)
}
Expand Down Expand Up @@ -110,31 +95,3 @@ class CollectionCreationFragment : DialogFragment() {
return dialog
}
}

@VisibleForTesting
internal fun BrowserState.getTabs(
tabIds: Array<String>?,
publicSuffixList: PublicSuffixList
): List<Tab> {
return tabIds
?.mapNotNull { id -> findTab(id) }
?.map { it.toTab(this, publicSuffixList) }
.orEmpty()
}

private fun TabSessionState.toTab(
state: BrowserState,
publicSuffixList: PublicSuffixList,
selected: Boolean? = null
): Tab {
val url = readerState.activeUrl ?: content.url
return Tab(
sessionId = this.id,
url = url,
hostname = url.toShortUrl(publicSuffixList),
title = content.title,
selected = selected,
icon = content.icon,
mediaState = state.getMediaStateForSession(this.id)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@

package org.mozilla.fenix.collections

import androidx.annotation.VisibleForTesting
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.lib.state.Action
import mozilla.components.lib.state.State
import mozilla.components.lib.state.Store
import org.mozilla.fenix.collections.CollectionCreationAction.StepChanged
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.ext.getMediaStateForSession
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.home.Tab

class CollectionCreationStore(
Expand Down Expand Up @@ -43,6 +51,61 @@ data class CollectionCreationState(
val defaultCollectionNumber: Int = 1
) : State

fun createInitialCollectionCreationState(
browserState: BrowserState,
tabCollectionStorage: TabCollectionStorage,
publicSuffixList: PublicSuffixList,
saveCollectionStep: SaveCollectionStep,
tabIds: Array<String>?,
selectedTabIds: Array<String>?,
selectedTabCollectionId: Long
) : CollectionCreationState {
val tabs = browserState.getTabs(tabIds, publicSuffixList)
val selectedTabs = if (selectedTabIds != null) {
browserState.getTabs(selectedTabIds, publicSuffixList).toSet()
} else {
if (tabs.size == 1) setOf(tabs.first()) else emptySet()
}

val tabCollections = tabCollectionStorage.cachedTabCollections
val selectedTabCollection = tabCollections.firstOrNull { it.id == selectedTabCollectionId }

return CollectionCreationState(
tabs = tabs,
selectedTabs = selectedTabs,
saveCollectionStep = saveCollectionStep,
tabCollections = tabCollections,
selectedTabCollection = selectedTabCollection
)
}

@VisibleForTesting
internal fun BrowserState.getTabs(
tabIds: Array<String>?,
publicSuffixList: PublicSuffixList
): List<Tab> {
return tabIds
?.mapNotNull { id -> findTab(id) }
?.map { it.toTab(this, publicSuffixList) }
.orEmpty()
}

private fun TabSessionState.toTab(
state: BrowserState,
publicSuffixList: PublicSuffixList
): Tab {
val url = readerState.activeUrl ?: content.url
return Tab(
sessionId = this.id,
url = url,
hostname = url.toShortUrl(publicSuffixList),
title = content.title,
selected = null,
icon = content.icon,
mediaState = state.getMediaStateForSession(this.id)
)
}

sealed class CollectionCreationAction : Action {
object AddAllTabs : CollectionCreationAction()
object RemoveAllTabs : CollectionCreationAction()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ import io.mockk.impl.annotations.MockK
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.ReaderState
import mozilla.components.browser.state.state.createTab
import mozilla.components.feature.tab.collections.Tab
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.support.test.robolectric.createAddedTestFragment
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
Expand All @@ -31,9 +28,6 @@ private const val SESSION_ID_MOZILLA = "0"
private const val URL_BCC = "www.bcc.co.uk"
private const val SESSION_ID_BCC = "1"

private const val SESSION_ID_BAD_1 = "not a real session id"
private const val SESSION_ID_BAD_2 = "definitely not a real session id"

@ExperimentalCoroutinesApi
@RunWith(FenixRobolectricTestRunner::class)
class CollectionCreationFragmentTest {
Expand Down Expand Up @@ -71,63 +65,4 @@ class CollectionCreationFragmentTest {
fragment.dismiss()
assertNull(fragment.dialog)
}

@Test
fun `GIVEN tabs are present in state WHEN getTabs is called THEN tabs will be returned`() {
val tabs = state.getTabs(arrayOf(SESSION_ID_MOZILLA, SESSION_ID_BCC), publicSuffixList)

val hosts = tabs.map { it.hostname }

assertEquals(URL_MOZILLA, hosts[0])
assertEquals(URL_BCC, hosts[1])
}

@Test
fun `GIVEN some tabs are present in state WHEN getTabs is called THEN only valid tabs will be returned`() {
val tabs = state.getTabs(arrayOf(SESSION_ID_MOZILLA, SESSION_ID_BAD_1), publicSuffixList)

val hosts = tabs.map { it.hostname }

assertEquals(URL_MOZILLA, hosts[0])
assertEquals(1, hosts.size)
}

@Test
fun `GIVEN tabs are not present in state WHEN getTabs is called THEN an empty list will be returned`() {
val tabs = state.getTabs(arrayOf(SESSION_ID_BAD_1, SESSION_ID_BAD_2), publicSuffixList)

assertEquals(emptyList<Tab>(), tabs)
}

@Test
fun `WHEN getTabs is called will null tabIds THEN an empty list will be returned`() {
val tabs = state.getTabs(null, publicSuffixList)

assertEquals(emptyList<Tab>(), tabs)
}

@Test
fun `toTab uses active reader URL`() {
val tabWithoutReaderState = createTab(url = "https://example.com", id = "1")

val tabWithInactiveReaderState = createTab(url = "https://blog.mozilla.org", id = "2",
readerState = ReaderState(active = false, activeUrl = null)
)

val tabWithActiveReaderState = createTab(url = "moz-extension://123", id = "3",
readerState = ReaderState(active = true, activeUrl = "https://blog.mozilla.org/123")
)

val state = BrowserState(
tabs = listOf(tabWithoutReaderState, tabWithInactiveReaderState, tabWithActiveReaderState)
)
val tabs = state.getTabs(
arrayOf(tabWithoutReaderState.id, tabWithInactiveReaderState.id, tabWithActiveReaderState.id),
publicSuffixList
)

assertEquals(tabWithoutReaderState.content.url, tabs[0].url)
assertEquals(tabWithInactiveReaderState.content.url, tabs[1].url)
assertEquals("https://blog.mozilla.org/123", tabs[2].url)
}
}

0 comments on commit f2a6aa4

Please sign in to comment.