Add test on MessagesViewTest: clicking on a read receipt list emits the expected Event.

This commit is contained in:
Benoit Marty 2024-02-09 22:35:46 +01:00 committed by Benoit Marty
parent 446ba571a3
commit 240e2cd09f
5 changed files with 65 additions and 10 deletions

View file

@ -22,15 +22,18 @@ import io.element.android.features.messages.impl.actionlist.anActionListState
import io.element.android.features.messages.impl.messagecomposer.AttachmentsState import io.element.android.features.messages.impl.messagecomposer.AttachmentsState
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState
import io.element.android.features.messages.impl.timeline.TimelineState
import io.element.android.features.messages.impl.timeline.aTimelineItemList import io.element.android.features.messages.impl.timeline.aTimelineItemList
import io.element.android.features.messages.impl.timeline.aTimelineState import io.element.android.features.messages.impl.timeline.aTimelineState
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
import io.element.android.features.messages.impl.typing.aTypingNotificationState import io.element.android.features.messages.impl.typing.aTypingNotificationState
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
@ -101,7 +104,11 @@ fun aMessagesState(
mode = MessageComposerMode.Normal, mode = MessageComposerMode.Normal,
), ),
voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(), voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(),
timelineState: TimelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
),
retrySendMenuState: RetrySendMenuState = aRetrySendMenuState(), retrySendMenuState: RetrySendMenuState = aRetrySendMenuState(),
readReceiptBottomSheetState: ReadReceiptBottomSheetState = aReadReceiptBottomSheetState(),
actionListState: ActionListState = anActionListState(), actionListState: ActionListState = anActionListState(),
customReactionState: CustomReactionState = aCustomReactionState(), customReactionState: CustomReactionState = aCustomReactionState(),
reactionSummaryState: ReactionSummaryState = aReactionSummaryState(), reactionSummaryState: ReactionSummaryState = aReactionSummaryState(),
@ -120,15 +127,10 @@ fun aMessagesState(
userHasPermissionToSendReaction = userHasPermissionToSendReaction, userHasPermissionToSendReaction = userHasPermissionToSendReaction,
composerState = composerState, composerState = composerState,
voiceMessageComposerState = voiceMessageComposerState, voiceMessageComposerState = voiceMessageComposerState,
timelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
),
typingNotificationState = aTypingNotificationState(), typingNotificationState = aTypingNotificationState(),
timelineState = timelineState,
retrySendMenuState = retrySendMenuState, retrySendMenuState = retrySendMenuState,
readReceiptBottomSheetState = ReadReceiptBottomSheetState( readReceiptBottomSheetState = readReceiptBottomSheetState,
selectedEvent = null,
eventSink = {},
),
actionListState = actionListState, actionListState = actionListState,
customReactionState = customReactionState, customReactionState = customReactionState,
reactionSummaryState = reactionSummaryState, reactionSummaryState = reactionSummaryState,
@ -158,3 +160,11 @@ fun aCustomReactionState(
selectedEmoji = persistentSetOf(), selectedEmoji = persistentSetOf(),
eventSink = eventSink, eventSink = eventSink,
) )
fun aReadReceiptBottomSheetState(
selectedEvent: TimelineItem.Event? = null,
eventSink: (ReadReceiptBottomSheetEvents) -> Unit = {},
) = ReadReceiptBottomSheetState(
selectedEvent = selectedEvent,
eventSink = eventSink,
)

View file

@ -48,12 +48,13 @@ import kotlin.random.Random
fun aTimelineState( fun aTimelineState(
timelineItems: ImmutableList<TimelineItem> = persistentListOf(), timelineItems: ImmutableList<TimelineItem> = persistentListOf(),
paginationState: MatrixTimeline.PaginationState = aPaginationState(), paginationState: MatrixTimeline.PaginationState = aPaginationState(),
renderReadReceipts: Boolean = false,
eventSink: (TimelineEvents) -> Unit = {}, eventSink: (TimelineEvents) -> Unit = {},
) = TimelineState( ) = TimelineState(
timelineItems = timelineItems, timelineItems = timelineItems,
timelineRoomInfo = aTimelineRoomInfo(), timelineRoomInfo = aTimelineRoomInfo(),
paginationState = paginationState, paginationState = paginationState,
renderReadReceipts = false, renderReadReceipts = renderReadReceipts,
highlightedEventId = null, highlightedEventId = null,
newEventState = NewEventState.None, newEventState = NewEventState.None,
sessionState = aSessionState( sessionState = aSessionState(
@ -196,9 +197,11 @@ internal fun aTimelineItemDebugInfo(
latestEditedJson latestEditedJson
) )
internal fun aTimelineItemReadReceipts(): TimelineItemReadReceipts { internal fun aTimelineItemReadReceipts(
receipts: List<ReadReceiptData> = emptyList(),
): TimelineItemReadReceipts {
return TimelineItemReadReceipts( return TimelineItemReadReceipts(
receipts = emptyList<ReadReceiptData>().toImmutableList(), receipts = receipts.toImmutableList(),
) )
} }

View file

@ -51,6 +51,8 @@ import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.testtags.testTag
import io.element.android.libraries.ui.strings.CommonPlurals import io.element.android.libraries.ui.strings.CommonPlurals
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@ -68,6 +70,7 @@ fun TimelineItemReadReceiptView(
ReadReceiptsAvatars( ReadReceiptsAvatars(
receipts = state.receipts, receipts = state.receipts,
modifier = Modifier modifier = Modifier
.testTag(TestTags.messageReadReceipts)
.clip(RoundedCornerShape(4.dp)) .clip(RoundedCornerShape(4.dp))
.clickable { .clickable {
onReadReceiptsClicked() onReadReceiptsClicked()

View file

@ -27,6 +27,7 @@ import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.test.performTouchInput
@ -37,8 +38,13 @@ import io.element.android.features.messages.impl.actionlist.anActionListState
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.attachments.Attachment
import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.aTimelineItemReadReceipts
import io.element.android.features.messages.impl.timeline.aTimelineState
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuEvents import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuEvents
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState
import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.TimelineItem
@ -200,6 +206,34 @@ class MessagesViewTest {
) )
} }
@Test
fun `clicking on a read receipt list emits the expected Event`() {
val eventsRecorder = EventsRecorder<ReadReceiptBottomSheetEvents>()
val state = aMessagesState(
timelineState = aTimelineState(
renderReadReceipts = true,
timelineItems = persistentListOf(
aTimelineItemEvent(
readReceiptState = aTimelineItemReadReceipts(
receipts = listOf(
aReadReceiptData(0),
),
),
),
),
),
readReceiptBottomSheetState = aReadReceiptBottomSheetState(
eventSink = eventsRecorder
),
)
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
rule.setMessagesView(
state = state,
)
rule.onNodeWithTag(TestTags.messageReadReceipts.value).performClick()
eventsRecorder.assertSingle(ReadReceiptBottomSheetEvents.EventSelected(timelineItem))
}
@Test @Test
fun `clicking on send location invoke expected callback`() { fun `clicking on send location invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false)

View file

@ -63,6 +63,11 @@ object TestTags {
*/ */
val messageBubble = TestTag("message_bubble") val messageBubble = TestTag("message_bubble")
/**
* Message Read Receipts.
*/
val messageReadReceipts = TestTag("message_read_receipts")
/** /**
* Dialogs. * Dialogs.
*/ */