Add test for TimelineItemGrouper and fix a bug: the last group if any was not added to the list.
This commit is contained in:
parent
02842d978f
commit
d899a8e881
2 changed files with 194 additions and 11 deletions
|
|
@ -46,22 +46,15 @@ class TimelineItemGrouper @Inject constructor() {
|
||||||
// timelineItem cannot be grouped
|
// timelineItem cannot be grouped
|
||||||
if (currentGroup.isNotEmpty()) {
|
if (currentGroup.isNotEmpty()) {
|
||||||
// There is a pending group, create a TimelineItem.GroupedEvents if there is more than 1 Event in the pending group.
|
// There is a pending group, create a TimelineItem.GroupedEvents if there is more than 1 Event in the pending group.
|
||||||
if (currentGroup.size == 1) {
|
result.addGroup(currentGroup, expandedGroups)
|
||||||
// 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()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
currentGroup.clear()
|
currentGroup.clear()
|
||||||
}
|
}
|
||||||
result.add(timelineItem)
|
result.add(timelineItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (currentGroup.isNotEmpty()) {
|
||||||
|
result.addGroup(currentGroup, expandedGroups)
|
||||||
|
}
|
||||||
return result
|
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()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue