Improve FakeMessagesNavigator using lambda as per the new test system.

This commit is contained in:
Benoit Marty 2024-11-21 17:17:21 +01:00
parent 1c1126ba39
commit 682abb3eff
4 changed files with 78 additions and 45 deletions

View file

@ -11,41 +11,33 @@ import io.element.android.features.messages.impl.attachments.Attachment
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.tests.testutils.lambda.lambdaError
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
class FakeMessagesNavigator : MessagesNavigator { class FakeMessagesNavigator(
var onShowEventDebugInfoClickedCount = 0 private val onShowEventDebugInfoClickLambda: (eventId: EventId?, debugInfo: TimelineItemDebugInfo) -> Unit = { _, _ -> lambdaError() },
private set private val onForwardEventClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() },
private val onReportContentClickLambda: (eventId: EventId, senderId: UserId) -> Unit = { _, _ -> lambdaError() },
var onForwardEventClickedCount = 0 private val onEditPollClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() },
private set private val onPreviewAttachmentLambda: (attachments: ImmutableList<Attachment>) -> Unit = { _ -> lambdaError() },
) : MessagesNavigator {
var onReportContentClickedCount = 0
private set
var onEditPollClickedCount = 0
private set
var onPreviewAttachmentCount = 0
private set
override fun onShowEventDebugInfoClick(eventId: EventId?, debugInfo: TimelineItemDebugInfo) { override fun onShowEventDebugInfoClick(eventId: EventId?, debugInfo: TimelineItemDebugInfo) {
onShowEventDebugInfoClickedCount++ onShowEventDebugInfoClickLambda(eventId, debugInfo)
} }
override fun onForwardEventClick(eventId: EventId) { override fun onForwardEventClick(eventId: EventId) {
onForwardEventClickedCount++ onForwardEventClickLambda(eventId)
} }
override fun onReportContentClick(eventId: EventId, senderId: UserId) { override fun onReportContentClick(eventId: EventId, senderId: UserId) {
onReportContentClickedCount++ onReportContentClickLambda(eventId, senderId)
} }
override fun onEditPollClick(eventId: EventId) { override fun onEditPollClick(eventId: EventId) {
onEditPollClickedCount++ onEditPollClickLambda(eventId)
} }
override fun onPreviewAttachment(attachments: ImmutableList<Attachment>) { override fun onPreviewAttachment(attachments: ImmutableList<Attachment>) {
onPreviewAttachmentCount++ onPreviewAttachmentLambda(attachments)
} }
} }

View file

@ -56,6 +56,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_AVATAR_URL
@ -65,12 +66,14 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID_2 import io.element.android.libraries.matrix.test.A_SESSION_ID_2
import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.matrix.test.timeline.aTimelineItemDebugInfo
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.libraries.textcomposer.model.TextEditorState import io.element.android.libraries.textcomposer.model.TextEditorState
@ -217,7 +220,10 @@ class MessagesPresenterTest {
@Test @Test
fun `present - handle action forward`() = runTest { fun `present - handle action forward`() = runTest {
val navigator = FakeMessagesNavigator() val onForwardEventClickLambda = lambdaRecorder<EventId, Unit> { }
val navigator = FakeMessagesNavigator(
onForwardEventClickLambda = onForwardEventClickLambda,
)
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
@ -225,7 +231,7 @@ class MessagesPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Forward, aMessageEvent())) initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Forward, aMessageEvent()))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
assertThat(navigator.onForwardEventClickedCount).isEqualTo(1) onForwardEventClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
} }
} }
@ -452,7 +458,10 @@ class MessagesPresenterTest {
@Test @Test
fun `present - handle action edit poll`() = runTest { fun `present - handle action edit poll`() = runTest {
val navigator = FakeMessagesNavigator() val onEditPollClickLambda = lambdaRecorder<EventId, Unit> { }
val navigator = FakeMessagesNavigator(
onEditPollClickLambda = onEditPollClickLambda
)
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
@ -460,7 +469,7 @@ class MessagesPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent(content = aTimelineItemPollContent()))) initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent(content = aTimelineItemPollContent())))
awaitItem() awaitItem()
assertThat(navigator.onEditPollClickedCount).isEqualTo(1) onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
} }
} }
@ -516,7 +525,10 @@ class MessagesPresenterTest {
@Test @Test
fun `present - handle action report content`() = runTest { fun `present - handle action report content`() = runTest {
val navigator = FakeMessagesNavigator() val onReportContentClickLambda = lambdaRecorder { _: EventId, _: UserId -> }
val navigator = FakeMessagesNavigator(
onReportContentClickLambda = onReportContentClickLambda
)
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
@ -524,7 +536,7 @@ class MessagesPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ReportContent, aMessageEvent())) initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ReportContent, aMessageEvent()))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
assertThat(navigator.onReportContentClickedCount).isEqualTo(1) onReportContentClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(A_USER_ID))
} }
} }
@ -542,7 +554,10 @@ class MessagesPresenterTest {
@Test @Test
fun `present - handle action show developer info`() = runTest { fun `present - handle action show developer info`() = runTest {
val navigator = FakeMessagesNavigator() val onShowEventDebugInfoClickLambda = lambdaRecorder { _: EventId?, _: TimelineItemDebugInfo -> }
val navigator = FakeMessagesNavigator(
onShowEventDebugInfoClickLambda = onShowEventDebugInfoClickLambda
)
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
@ -550,7 +565,7 @@ class MessagesPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ViewSource, aMessageEvent())) initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ViewSource, aMessageEvent()))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
assertThat(navigator.onShowEventDebugInfoClickedCount).isEqualTo(1) onShowEventDebugInfoClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(aTimelineItemDebugInfo()))
} }
} }

View file

@ -20,6 +20,7 @@ import im.vector.app.features.analytics.plan.Composer
import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.analytics.plan.Interaction
import io.element.android.features.messages.impl.FakeMessagesNavigator import io.element.android.features.messages.impl.FakeMessagesNavigator
import io.element.android.features.messages.impl.MessagesNavigator import io.element.android.features.messages.impl.MessagesNavigator
import io.element.android.features.messages.impl.attachments.Attachment
import io.element.android.features.messages.impl.draft.ComposerDraftService import io.element.android.features.messages.impl.draft.ComposerDraftService
import io.element.android.features.messages.impl.draft.FakeComposerDraftService import io.element.android.features.messages.impl.draft.FakeComposerDraftService
import io.element.android.features.messages.impl.messagecomposer.suggestions.SuggestionsProcessor import io.element.android.features.messages.impl.messagecomposer.suggestions.SuggestionsProcessor
@ -93,6 +94,7 @@ import io.element.android.tests.testutils.lambda.value
import io.element.android.tests.testutils.test import io.element.android.tests.testutils.test
import io.element.android.tests.testutils.waitForPredicate import io.element.android.tests.testutils.waitForPredicate
import io.mockk.mockk import io.mockk.mockk
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -686,7 +688,10 @@ class MessageComposerPresenterTest {
val room = FakeMatrixRoom( val room = FakeMatrixRoom(
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -715,7 +720,7 @@ class MessageComposerPresenterTest {
}.test { }.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery)
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
} }
} }
@ -724,7 +729,10 @@ class MessageComposerPresenterTest {
val room = FakeMatrixRoom( val room = FakeMatrixRoom(
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -754,7 +762,7 @@ class MessageComposerPresenterTest {
}.test { }.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery)
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
} }
} }
@ -779,7 +787,10 @@ class MessageComposerPresenterTest {
val room = FakeMatrixRoom( val room = FakeMatrixRoom(
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -790,7 +801,7 @@ class MessageComposerPresenterTest {
}.test { }.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles)
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
} }
} }
@ -838,7 +849,10 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -850,7 +864,7 @@ class MessageComposerPresenterTest {
}.test { }.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera)
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
} }
} }
@ -860,7 +874,10 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val permissionPresenter = FakePermissionsPresenter() val permissionPresenter = FakePermissionsPresenter()
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -873,7 +890,7 @@ class MessageComposerPresenterTest {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera)
permissionPresenter.setPermissionGranted() permissionPresenter.setPermissionGranted()
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
} }
} }
@ -884,7 +901,10 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -896,7 +916,7 @@ class MessageComposerPresenterTest {
}.test { }.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera) initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera)
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
} }
} }
@ -906,7 +926,10 @@ class MessageComposerPresenterTest {
typingNoticeResult = { Result.success(Unit) } typingNoticeResult = { Result.success(Unit) }
) )
val permissionPresenter = FakePermissionsPresenter() val permissionPresenter = FakePermissionsPresenter()
val navigator = FakeMessagesNavigator() val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList<Attachment> -> }
val navigator = FakeMessagesNavigator(
onPreviewAttachmentLambda = onPreviewAttachmentLambda
)
val presenter = createPresenter( val presenter = createPresenter(
coroutineScope = this, coroutineScope = this,
room = room, room = room,
@ -922,7 +945,7 @@ class MessageComposerPresenterTest {
assertThat(permissionState.showAttachmentSourcePicker).isFalse() assertThat(permissionState.showAttachmentSourcePicker).isFalse()
permissionPresenter.setPermissionGranted() permissionPresenter.setPermissionGranted()
skipItems(1) skipItems(1)
assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) onPreviewAttachmentLambda.assertions().isCalledOnce()
} }
} }

View file

@ -431,7 +431,10 @@ import kotlin.time.Duration.Companion.seconds
@Test @Test
fun `present - PollEditClicked event navigates`() = runTest { fun `present - PollEditClicked event navigates`() = runTest {
val navigator = FakeMessagesNavigator() val onEditPollClickLambda = lambdaRecorder { _: EventId -> }
val navigator = FakeMessagesNavigator(
onEditPollClickLambda = onEditPollClickLambda
)
val presenter = createTimelinePresenter( val presenter = createTimelinePresenter(
messagesNavigator = navigator, messagesNavigator = navigator,
) )
@ -439,7 +442,7 @@ import kotlin.time.Duration.Companion.seconds
presenter.present() presenter.present()
}.test { }.test {
awaitFirstItem().eventSink(TimelineEvents.EditPoll(AN_EVENT_ID)) awaitFirstItem().eventSink(TimelineEvents.EditPoll(AN_EVENT_ID))
assertThat(navigator.onEditPollClickedCount).isEqualTo(1) onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
} }
} }