[fenix] Sort history metadata on home and allow limiting results

pull/600/head
Christian Sadilek 3 years ago committed by mergify[bot]
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…
Cancel
Save