Timeline : continue to fix more tests...

This commit is contained in:
ganfra 2024-04-25 12:41:34 +02:00
parent bf87b975fc
commit bffa2d717f
9 changed files with 198 additions and 63 deletions

View file

@ -65,6 +65,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.featureflag.test.InMemoryAppPreferencesStore
import io.element.android.libraries.featureflag.test.InMemorySessionPreferencesStore
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
@ -83,6 +84,7 @@ 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.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediapickers.test.FakePickerProvider
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.libraries.mediaupload.api.MediaSender
@ -97,6 +99,9 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.consumeItemsUntilPredicate
import io.element.android.tests.testutils.consumeItemsUntilTimeout
import io.element.android.tests.testutils.lambda.assert
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.lambda.value
import io.element.android.tests.testutils.testCoroutineDispatchers
import io.mockk.mockk
import kotlinx.collections.immutable.persistentListOf
@ -169,7 +174,13 @@ class MessagesPresenterTest {
@Test
fun `present - handle toggling a reaction`() = runTest {
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
val room = FakeMatrixRoom()
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventId -> Result.success(Unit) }
val toggleReactionFailure = lambdaRecorder { _: String, _: EventId -> Result.failure<Unit>(IllegalStateException("Failed to send reaction")) }
val timeline = FakeTimeline().apply {
this.toggleReactionLambda = toggleReactionSuccess
}
val room = FakeMatrixRoom(liveTimeline = timeline)
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -177,29 +188,42 @@ class MessagesPresenterTest {
skipItems(1)
val initialState = awaitItem()
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID))
assertThat(room.myReactions.count()).isEqualTo(1)
// No crashes when sending a reaction failed
room.givenToggleReactionResult(Result.failure(IllegalStateException("Failed to send reaction")))
timeline.apply { toggleReactionLambda = toggleReactionFailure }
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID))
assertThat(room.myReactions.count()).isEqualTo(1)
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
assert(toggleReactionSuccess)
.isCalledOnce()
.with(value("👍"), value(AN_EVENT_ID))
assert(toggleReactionFailure)
.isCalledOnce()
.with(value("👍"), value(AN_EVENT_ID))
}
}
@Test
fun `present - handle toggling a reaction twice`() = runTest {
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
val room = FakeMatrixRoom()
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventId -> Result.success(Unit) }
val timeline = FakeTimeline().apply {
this.toggleReactionLambda = toggleReactionSuccess
}
val room = FakeMatrixRoom(liveTimeline = timeline)
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitFirstItem()
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID))
assertThat(room.myReactions.count()).isEqualTo(1)
initialState.eventSink.invoke(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID))
assertThat(room.myReactions.count()).isEqualTo(0)
assert(toggleReactionSuccess)
.isCalledExactly(2)
.withSequence(
listOf(value("👍"), value(AN_EVENT_ID)),
listOf(value("👍"), value(AN_EVENT_ID)),
)
}
}
@ -274,7 +298,7 @@ class MessagesPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(3)
skipItems(2)
val initialState = awaitItem()
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent(eventId = null)))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
@ -430,7 +454,6 @@ class MessagesPresenterTest {
initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Redact, aMessageEvent()))
assertThat(matrixRoom.redactEventEventIdParam).isEqualTo(AN_EVENT_ID)
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
skipItems(1) // back paginating
}
}

View file

@ -66,6 +66,7 @@ import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
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.aRoomMember
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.mediapickers.api.PickerProvider
import io.element.android.libraries.mediapickers.test.FakePickerProvider
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
@ -82,6 +83,10 @@ import io.element.android.libraries.textcomposer.model.Suggestion
import io.element.android.libraries.textcomposer.model.SuggestionType
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.any
import io.element.android.tests.testutils.lambda.assert
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.lambda.value
import io.element.android.tests.testutils.waitForPredicate
import io.mockk.mockk
import kotlinx.collections.immutable.persistentListOf
@ -260,7 +265,13 @@ class MessageComposerPresenterTest {
@Test
fun `present - edit sent message`() = runTest {
val fakeMatrixRoom = FakeMatrixRoom()
val editMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<Mention> ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.editMessageLambda = editMessageLambda
}
val fakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline)
val presenter = createPresenter(
this,
fakeMatrixRoom,
@ -284,7 +295,13 @@ class MessageComposerPresenterTest {
skipItems(1)
val messageSentState = awaitItem()
assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("")
assertThat(fakeMatrixRoom.editMessageCalls.first()).isEqualTo(ANOTHER_MESSAGE to ANOTHER_MESSAGE)
advanceUntilIdle()
assert(editMessageLambda)
.isCalledOnce()
.with(any(), any(), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
assertThat(analyticsService.capturedEvents).containsExactly(
Composer(
inThread = false,
@ -298,7 +315,13 @@ class MessageComposerPresenterTest {
@Test
fun `present - edit not sent message`() = runTest {
val fakeMatrixRoom = FakeMatrixRoom()
val editMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<Mention> ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.editMessageLambda = editMessageLambda
}
val fakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline)
val presenter = createPresenter(
this,
fakeMatrixRoom,
@ -322,7 +345,13 @@ class MessageComposerPresenterTest {
skipItems(1)
val messageSentState = awaitItem()
assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("")
assertThat(fakeMatrixRoom.editMessageCalls.first()).isEqualTo(ANOTHER_MESSAGE to ANOTHER_MESSAGE)
advanceUntilIdle()
assert(editMessageLambda)
.isCalledOnce()
.with(any(), any(), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
assertThat(analyticsService.capturedEvents).containsExactly(
Composer(
inThread = false,
@ -336,7 +365,13 @@ class MessageComposerPresenterTest {
@Test
fun `present - reply message`() = runTest {
val fakeMatrixRoom = FakeMatrixRoom()
val replyMessageLambda = lambdaRecorder {_: EventId, _: String, _: String?, _:List<Mention> ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.replyMessageLambda = replyMessageLambda
}
val fakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline)
val presenter = createPresenter(
this,
fakeMatrixRoom,
@ -356,7 +391,13 @@ class MessageComposerPresenterTest {
state.eventSink.invoke(MessageComposerEvents.SendMessage(A_REPLY.toMessage()))
val messageSentState = awaitItem()
assertThat(messageSentState.richTextEditorState.messageHtml).isEqualTo("")
assertThat(fakeMatrixRoom.replyMessageParameter).isEqualTo(A_REPLY to A_REPLY)
advanceUntilIdle()
assert(replyMessageLambda)
.isCalledOnce()
.with(any(),value(A_REPLY),value(A_REPLY),any())
assertThat(analyticsService.capturedEvents).containsExactly(
Composer(
inThread = false,
@ -832,7 +873,17 @@ class MessageComposerPresenterTest {
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `present - send messages with intentional mentions`() = runTest {
val room = FakeMatrixRoom()
val replyMessageLambda = lambdaRecorder {_: EventId, _: String, _: String?, _:List<Mention> ->
Result.success(Unit)
}
val editMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<Mention> ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.replyMessageLambda = replyMessageLambda
this.editMessageLambda = editMessageLambda
}
val room = FakeMatrixRoom(liveTimeline = timeline)
val presenter = createPresenter(room = room, coroutineScope = this)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -867,7 +918,9 @@ class MessageComposerPresenterTest {
initialState.eventSink(MessageComposerEvents.SendMessage(A_MESSAGE.toMessage()))
advanceUntilIdle()
assertThat(room.sendMessageMentions).isEqualTo(listOf(Mention.User(A_USER_ID_2)))
assert(replyMessageLambda)
.isCalledOnce()
.with(any(), any(), any(), value(listOf(Mention.User(A_USER_ID_2))))
// Check intentional mentions on edit message
skipItems(1)
@ -883,7 +936,10 @@ class MessageComposerPresenterTest {
initialState.eventSink(MessageComposerEvents.SendMessage(A_MESSAGE.toMessage()))
advanceUntilIdle()
assertThat(room.sendMessageMentions).isEqualTo(listOf(Mention.User(A_USER_ID_3)))
assert(editMessageLambda)
.isCalledOnce()
.with(any(), any(), any(), any(), value(listOf(Mention.User(A_USER_ID_3))))
skipItems(1)
}