Add test for TimelineItemGrouper and fix a bug: the last group if any was not added to the list.
This commit is contained in:
@@ -46,22 +46,15 @@ class TimelineItemGrouper @Inject constructor() {
|
||||
// timelineItem cannot be grouped
|
||||
if (currentGroup.isNotEmpty()) {
|
||||
// There is a pending group, create a TimelineItem.GroupedEvents if there is more than 1 Event in the pending group.
|
||||
if (currentGroup.size == 1) {
|
||||
// Do not create a group with just 1 item, just add the item to the result
|
||||
result.add(currentGroup.first())
|
||||
} else {
|
||||
result.add(
|
||||
TimelineItem.GroupedEvents(
|
||||
expanded = expandedGroups[currentGroup.first().id + "_group"].orFalse(),
|
||||
events = currentGroup.toImmutableList()
|
||||
)
|
||||
)
|
||||
}
|
||||
result.addGroup(currentGroup, expandedGroups)
|
||||
currentGroup.clear()
|
||||
}
|
||||
result.add(timelineItem)
|
||||
}
|
||||
}
|
||||
if (currentGroup.isNotEmpty()) {
|
||||
result.addGroup(currentGroup, expandedGroups)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -80,3 +73,23 @@ class TimelineItemGrouper @Inject constructor() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will add a group if there is more than 1 item, else add the item to the list.
|
||||
*/
|
||||
private fun MutableList<TimelineItem>.addGroup(
|
||||
group: MutableList<TimelineItem.Event>,
|
||||
expandedGroups: Map<String, Boolean>,
|
||||
) {
|
||||
if (group.size == 1) {
|
||||
// Do not create a group with just 1 item, just add the item to the result
|
||||
add(group.first())
|
||||
} else {
|
||||
add(
|
||||
TimelineItem.GroupedEvents(
|
||||
expanded = expandedGroups[group.first().id + "_group"].orFalse(),
|
||||
events = group.toImmutableList()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.messages.timeline.groups
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.messages.fixtures.aMessageEvent
|
||||
import io.element.android.features.messages.impl.timeline.groups.TimelineItemGrouper
|
||||
import io.element.android.features.messages.impl.timeline.model.AggregatedReaction
|
||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||
import io.element.android.features.messages.impl.timeline.model.TimelineItemReactions
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.aTimelineItemDaySeparatorModel
|
||||
import io.element.android.libraries.designsystem.components.avatar.anAvatarData
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import org.junit.Test
|
||||
|
||||
class TimelineItemGrouperTest {
|
||||
private val sut = TimelineItemGrouper()
|
||||
|
||||
private val aGroupableItem = TimelineItem.Event(
|
||||
id = AN_EVENT_ID.value,
|
||||
senderId = A_USER_ID,
|
||||
senderAvatar = anAvatarData(),
|
||||
senderDisplayName = "",
|
||||
content = TimelineItemStateEventContent(body = "a state event"),
|
||||
reactionsState = TimelineItemReactions(emptyList<AggregatedReaction>().toImmutableList())
|
||||
)
|
||||
private val aNonGroupableItem = aMessageEvent()
|
||||
private val aNonGroupableItemNoEvent = TimelineItem.Virtual("virtual", aTimelineItemDaySeparatorModel("Today"))
|
||||
|
||||
@Test
|
||||
fun `test empty`() {
|
||||
val result = sut.group(emptyList(), emptyMap())
|
||||
assertThat(result).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test non groupables`() {
|
||||
val result = sut.group(
|
||||
listOf(
|
||||
aNonGroupableItem,
|
||||
aNonGroupableItem,
|
||||
),
|
||||
emptyMap()
|
||||
)
|
||||
assertThat(result).isEqualTo(
|
||||
listOf(
|
||||
aNonGroupableItem,
|
||||
aNonGroupableItem,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test groupables and ensure reordering`() {
|
||||
val result = sut.group(
|
||||
listOf(
|
||||
aGroupableItem.copy(id = AN_EVENT_ID_2.value),
|
||||
aGroupableItem,
|
||||
),
|
||||
emptyMap()
|
||||
)
|
||||
assertThat(result).isEqualTo(
|
||||
listOf(
|
||||
TimelineItem.GroupedEvents(
|
||||
expanded = false,
|
||||
events = listOf(
|
||||
aGroupableItem,
|
||||
aGroupableItem.copy(id = AN_EVENT_ID_2.value),
|
||||
).toImmutableList()
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test groupables expanded`() {
|
||||
val result = sut.group(
|
||||
listOf(
|
||||
aGroupableItem,
|
||||
aGroupableItem.copy(id = AN_EVENT_ID_2.value),
|
||||
),
|
||||
mapOf("${AN_EVENT_ID_2.value}_group" to true)
|
||||
)
|
||||
assertThat(result).isEqualTo(
|
||||
listOf(
|
||||
TimelineItem.GroupedEvents(
|
||||
expanded = true,
|
||||
events = listOf(
|
||||
aGroupableItem.copy(id = AN_EVENT_ID_2.value),
|
||||
aGroupableItem,
|
||||
).toImmutableList()
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test 1 groupable, not group must be created`() {
|
||||
val listsToTest = listOf(
|
||||
listOf(aGroupableItem),
|
||||
listOf(aGroupableItem, aNonGroupableItem),
|
||||
listOf(aGroupableItem, aNonGroupableItemNoEvent),
|
||||
listOf(aNonGroupableItem, aGroupableItem),
|
||||
listOf(aNonGroupableItemNoEvent, aGroupableItem),
|
||||
listOf(aNonGroupableItem, aGroupableItem, aNonGroupableItem),
|
||||
listOf(aNonGroupableItemNoEvent, aGroupableItem, aNonGroupableItemNoEvent),
|
||||
listOf(aGroupableItem, aNonGroupableItem, aGroupableItem),
|
||||
listOf(aGroupableItem, aNonGroupableItemNoEvent, aGroupableItem),
|
||||
listOf(aNonGroupableItem),
|
||||
listOf(aNonGroupableItemNoEvent),
|
||||
)
|
||||
listsToTest.forEach { listToTest ->
|
||||
val result = sut.group(listToTest, emptyMap())
|
||||
assertThat(result).isEqualTo(listToTest)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test 3 blocks`() {
|
||||
val result = sut.group(
|
||||
listOf(
|
||||
aGroupableItem,
|
||||
aGroupableItem,
|
||||
aNonGroupableItem,
|
||||
aGroupableItem,
|
||||
aGroupableItem,
|
||||
aGroupableItem,
|
||||
),
|
||||
emptyMap()
|
||||
)
|
||||
assertThat(result).isEqualTo(
|
||||
listOf(
|
||||
TimelineItem.GroupedEvents(
|
||||
expanded = false,
|
||||
events = listOf(
|
||||
aGroupableItem,
|
||||
aGroupableItem,
|
||||
).toImmutableList()
|
||||
),
|
||||
aNonGroupableItem,
|
||||
TimelineItem.GroupedEvents(
|
||||
expanded = false,
|
||||
events = listOf(
|
||||
aGroupableItem,
|
||||
aGroupableItem,
|
||||
aGroupableItem,
|
||||
).toImmutableList()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user