mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] Sort history metadata on home and allow limiting results
This commit is contained in:
parent
ae40da34f8
commit
d4a454442b
@ -17,6 +17,8 @@ import org.mozilla.fenix.home.HomeFragmentAction
|
||||
import org.mozilla.fenix.home.HomeFragmentStore
|
||||
import kotlin.math.max
|
||||
|
||||
private const val DEFAULT_MAX_RESULTS = 9
|
||||
|
||||
/**
|
||||
* View-bound feature that retrieves a list of history metadata and dispatches updates to the
|
||||
* [HomeFragmentStore].
|
||||
@ -25,12 +27,15 @@ import kotlin.math.max
|
||||
* @param historyMetadataStorage The storage manages [HistoryMetadata].
|
||||
* @param scope The [CoroutineScope] used to retrieve a list of history metadata.
|
||||
* @param ioDispatcher The [CoroutineDispatcher] for performing read/write operations.
|
||||
* @param maxResults The maximum number of metadata groups that should be added to
|
||||
* the store and displayed on the [HomeFragment].
|
||||
*/
|
||||
class HistoryMetadataFeature(
|
||||
private val homeStore: HomeFragmentStore,
|
||||
private val historyMetadataStorage: HistoryMetadataStorage,
|
||||
private val scope: CoroutineScope,
|
||||
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
|
||||
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
|
||||
private val maxResults: Int = DEFAULT_MAX_RESULTS
|
||||
) : LifecycleAwareFeature {
|
||||
|
||||
private var job: Job? = null
|
||||
@ -38,7 +43,7 @@ class HistoryMetadataFeature(
|
||||
override fun start() {
|
||||
job = scope.launch(ioDispatcher) {
|
||||
// For now, group the queried list of [HistoryMetadata] according to their search term.
|
||||
// This feature will later be used to generate more groups.
|
||||
// This feature will later be used to generate different groups and highlights.
|
||||
val historyMetadata = historyMetadataStorage.getHistoryMetadataSince(Long.MIN_VALUE)
|
||||
.filter { it.totalViewTime > 0 && it.key.searchTerm != null }
|
||||
.groupBy { it.key.searchTerm!! }
|
||||
@ -63,6 +68,8 @@ class HistoryMetadataFeature(
|
||||
historyMetadata = data
|
||||
)
|
||||
}
|
||||
.sortedByDescending { it.lastUpdated() }
|
||||
.take(maxResults)
|
||||
|
||||
homeStore.dispatch(HomeFragmentAction.HistoryMetadataChange(historyMetadata))
|
||||
}
|
||||
|
@ -18,3 +18,6 @@ data class HistoryMetadataGroup(
|
||||
val historyMetadata: List<HistoryMetadata>,
|
||||
val expanded: Boolean = false
|
||||
)
|
||||
|
||||
// The last updated time of the group is based on the most recently updated item in the group
|
||||
fun HistoryMetadataGroup.lastUpdated(): Long = historyMetadata.maxOf { it.updatedAt }
|
||||
|
@ -134,11 +134,12 @@ class HistoryMetadataFeatureTest {
|
||||
@Test
|
||||
fun `GIVEN history metadata WHEN different groups contain entries with same url THEN entries are not deduped`() =
|
||||
testDispatcher.runBlockingTest {
|
||||
val now = System.currentTimeMillis()
|
||||
val historyEntry1 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://www.mozilla.com", "mozilla", null),
|
||||
title = "mozilla",
|
||||
createdAt = System.currentTimeMillis(),
|
||||
updatedAt = System.currentTimeMillis(),
|
||||
createdAt = now,
|
||||
updatedAt = now + 3,
|
||||
totalViewTime = 10,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
@ -147,8 +148,8 @@ class HistoryMetadataFeatureTest {
|
||||
val historyEntry2 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://firefox.com", "mozilla", null),
|
||||
title = "firefox",
|
||||
createdAt = System.currentTimeMillis(),
|
||||
updatedAt = System.currentTimeMillis(),
|
||||
createdAt = now,
|
||||
updatedAt = now + 2,
|
||||
totalViewTime = 20,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
@ -157,8 +158,8 @@ class HistoryMetadataFeatureTest {
|
||||
val historyEntry3 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://www.mozilla.com", "firefox", null),
|
||||
title = "mozilla",
|
||||
createdAt = System.currentTimeMillis(),
|
||||
updatedAt = System.currentTimeMillis(),
|
||||
createdAt = now,
|
||||
updatedAt = now + 1,
|
||||
totalViewTime = 30,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
@ -187,12 +188,128 @@ class HistoryMetadataFeatureTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun startHistoryMetadataFeature() {
|
||||
@Test
|
||||
fun `GIVEN history metadata WHEN multiple groups exist THEN groups are sorted descending by last updated timestamp`() =
|
||||
testDispatcher.runBlockingTest {
|
||||
val now = System.currentTimeMillis()
|
||||
val historyEntry1 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://www.mozilla.com", "mozilla", null),
|
||||
title = "mozilla",
|
||||
createdAt = now,
|
||||
updatedAt = now + 1,
|
||||
totalViewTime = 10,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
)
|
||||
|
||||
val historyEntry2 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://firefox.com", "mozilla", null),
|
||||
title = "firefox",
|
||||
createdAt = now,
|
||||
updatedAt = now + 2,
|
||||
totalViewTime = 20,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
)
|
||||
|
||||
val historyEntry3 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://www.mozilla.com", "firefox", null),
|
||||
title = "mozilla",
|
||||
createdAt = now,
|
||||
updatedAt = now + 3,
|
||||
totalViewTime = 30,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
)
|
||||
|
||||
val expectedHistoryGroup1 = HistoryMetadataGroup(
|
||||
title = "mozilla",
|
||||
historyMetadata = listOf(historyEntry1, historyEntry2)
|
||||
)
|
||||
|
||||
val expectedHistoryGroup2 = HistoryMetadataGroup(
|
||||
title = "firefox",
|
||||
historyMetadata = listOf(historyEntry3)
|
||||
)
|
||||
|
||||
coEvery { historyMetadataStorage.getHistoryMetadataSince(any()) }.coAnswers {
|
||||
listOf(
|
||||
historyEntry1, historyEntry2, historyEntry3
|
||||
)
|
||||
}
|
||||
|
||||
startHistoryMetadataFeature()
|
||||
|
||||
middleware.assertLastAction(HomeFragmentAction.HistoryMetadataChange::class) {
|
||||
assertEquals(listOf(expectedHistoryGroup2, expectedHistoryGroup1), it.historyMetadata)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN history metadata WHEN multiple groups exist THEN no more than the configured maximum number of results are added to the store`() =
|
||||
testDispatcher.runBlockingTest {
|
||||
val now = System.currentTimeMillis()
|
||||
val historyEntry1 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://www.mozilla.com", "mozilla", null),
|
||||
title = "mozilla",
|
||||
createdAt = now,
|
||||
updatedAt = now + 1,
|
||||
totalViewTime = 10,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
)
|
||||
|
||||
val historyEntry2 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://firefox.com", "firefox", null),
|
||||
title = "firefox",
|
||||
createdAt = now,
|
||||
updatedAt = now + 2,
|
||||
totalViewTime = 20,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
)
|
||||
|
||||
val historyEntry3 = HistoryMetadata(
|
||||
key = HistoryMetadataKey("http://getpocket.com", "pocket", null),
|
||||
title = "pocket",
|
||||
createdAt = now,
|
||||
updatedAt = now + 3,
|
||||
totalViewTime = 30,
|
||||
documentType = DocumentType.Regular,
|
||||
previewImageUrl = null
|
||||
)
|
||||
|
||||
val expectedHistoryGroup1 = HistoryMetadataGroup(
|
||||
title = "firefox",
|
||||
historyMetadata = listOf(historyEntry2)
|
||||
)
|
||||
|
||||
val expectedHistoryGroup2 = HistoryMetadataGroup(
|
||||
title = "pocket",
|
||||
historyMetadata = listOf(historyEntry3)
|
||||
)
|
||||
|
||||
coEvery { historyMetadataStorage.getHistoryMetadataSince(any()) }.coAnswers {
|
||||
listOf(
|
||||
historyEntry1, historyEntry2, historyEntry3
|
||||
)
|
||||
}
|
||||
|
||||
startHistoryMetadataFeature(maxResults = 2)
|
||||
|
||||
// Should not get more than maxResults number of groups back
|
||||
middleware.assertLastAction(HomeFragmentAction.HistoryMetadataChange::class) {
|
||||
assertEquals(listOf(expectedHistoryGroup2, expectedHistoryGroup1), it.historyMetadata)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startHistoryMetadataFeature(maxResults: Int = 10) {
|
||||
val feature = HistoryMetadataFeature(
|
||||
homeStore,
|
||||
historyMetadataStorage,
|
||||
CoroutineScope(testDispatcher),
|
||||
testDispatcher
|
||||
testDispatcher,
|
||||
maxResults
|
||||
)
|
||||
|
||||
assertEquals(emptyList<HistoryMetadataGroup>(), homeStore.state.historyMetadata)
|
||||
|
Loading…
Reference in New Issue
Block a user