Browse Source

Fix test compilation

misc/jme/add-logging-to-state-machine
ganfra 2 years ago
parent
commit
4fc12f13d8
  1. 1
      features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelinePresenter.kt
  2. 2
      features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineState.kt
  3. 2
      features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineStateProvider.kt
  4. 2
      features/messages/src/main/kotlin/io/element/android/features/messages/timeline/factories/event/TimelineItemEventFactory.kt
  5. 34
      features/messages/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt
  6. 14
      features/messages/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt
  7. 43
      features/messages/src/test/kotlin/io/element/android/features/messages/fixtures/aMessageEvent.kt
  8. 28
      features/messages/src/test/kotlin/io/element/android/features/messages/fixtures/testCoroutineDispatchers.kt
  9. 52
      features/messages/src/test/kotlin/io/element/android/features/messages/fixtures/timelineItemsFactory.kt
  10. 50
      features/messages/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt
  11. 4
      libraries/matrixtest/src/main/kotlin/io/element/android/libraries/matrixtest/timeline/FakeMatrixTimeline.kt

1
features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelinePresenter.kt

@ -89,6 +89,7 @@ class TimelinePresenter @Inject constructor(
return TimelineState( return TimelineState(
highlightedEventId = highlightedEventId.value, highlightedEventId = highlightedEventId.value,
paginationState = paginationState.value,
timelineItems = timelineItems.value.toImmutableList(), timelineItems = timelineItems.value.toImmutableList(),
eventSink = ::handleEvents eventSink = ::handleEvents
) )

2
features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineState.kt

@ -19,11 +19,13 @@ package io.element.android.features.messages.timeline
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import io.element.android.features.messages.timeline.model.TimelineItem import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.libraries.matrix.core.EventId import io.element.android.libraries.matrix.core.EventId
import io.element.android.libraries.matrix.timeline.MatrixTimeline
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@Immutable @Immutable
data class TimelineState( data class TimelineState(
val timelineItems: ImmutableList<TimelineItem>, val timelineItems: ImmutableList<TimelineItem>,
val highlightedEventId: EventId?, val highlightedEventId: EventId?,
val paginationState: MatrixTimeline.PaginationState,
val eventSink: (TimelineEvents) -> Unit val eventSink: (TimelineEvents) -> Unit
) )

2
features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineStateProvider.kt

@ -24,11 +24,13 @@ import io.element.android.features.messages.timeline.model.event.TimelineItemEve
import io.element.android.features.messages.timeline.model.event.TimelineItemTextContent import io.element.android.features.messages.timeline.model.event.TimelineItemTextContent
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.core.EventId import io.element.android.libraries.matrix.core.EventId
import io.element.android.libraries.matrix.timeline.MatrixTimeline
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
fun aTimelineState() = TimelineState( fun aTimelineState() = TimelineState(
timelineItems = persistentListOf(), timelineItems = persistentListOf(),
paginationState = MatrixTimeline.PaginationState(isBackPaginating = false, canBackPaginate = true),
highlightedEventId = null, highlightedEventId = null,
eventSink = {} eventSink = {}
) )

2
features/messages/src/main/kotlin/io/element/android/features/messages/timeline/factories/event/TimelineItemEventFactory.kt

@ -22,14 +22,12 @@ import io.element.android.features.messages.timeline.model.TimelineItemGroupPosi
import io.element.android.features.messages.timeline.model.TimelineItemReactions import io.element.android.features.messages.timeline.model.TimelineItemReactions
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.room.MatrixRoom
import io.element.android.libraries.matrix.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.timeline.MatrixTimelineItem
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import org.matrix.rustcomponents.sdk.ProfileTimelineDetails import org.matrix.rustcomponents.sdk.ProfileTimelineDetails
import javax.inject.Inject import javax.inject.Inject
class TimelineItemEventFactory @Inject constructor( class TimelineItemEventFactory @Inject constructor(
private val room: MatrixRoom,
private val contentFactory: TimelineItemContentFactory, private val contentFactory: TimelineItemContentFactory,
) { ) {

34
features/messages/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt

@ -24,12 +24,14 @@ import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.actionlist.ActionListPresenter import io.element.android.features.messages.actionlist.ActionListPresenter
import io.element.android.features.messages.actionlist.model.TimelineItemAction import io.element.android.features.messages.actionlist.model.TimelineItemAction
import io.element.android.features.messages.fixtures.aMessageEvent
import io.element.android.features.messages.fixtures.aTimelineItemsFactory
import io.element.android.features.messages.textcomposer.MessageComposerPresenter import io.element.android.features.messages.textcomposer.MessageComposerPresenter
import io.element.android.features.messages.timeline.TimelinePresenter import io.element.android.features.messages.timeline.TimelinePresenter
import io.element.android.features.messages.timeline.model.TimelineItem import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.features.messages.timeline.model.TimelineItemReactions import io.element.android.features.messages.timeline.model.TimelineItemReactions
import io.element.android.features.messages.timeline.model.content.TimelineItemContent import io.element.android.features.messages.timeline.model.event.TimelineItemEventContent
import io.element.android.features.messages.timeline.model.content.TimelineItemTextContent import io.element.android.features.messages.timeline.model.event.TimelineItemTextContent
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.room.MatrixRoom import io.element.android.libraries.matrix.room.MatrixRoom
@ -38,7 +40,6 @@ import io.element.android.libraries.matrixtest.A_MESSAGE
import io.element.android.libraries.matrixtest.A_ROOM_ID import io.element.android.libraries.matrixtest.A_ROOM_ID
import io.element.android.libraries.matrixtest.A_USER_ID import io.element.android.libraries.matrixtest.A_USER_ID
import io.element.android.libraries.matrixtest.A_USER_NAME import io.element.android.libraries.matrixtest.A_USER_NAME
import io.element.android.libraries.matrixtest.FakeMatrixClient
import io.element.android.libraries.matrixtest.room.FakeMatrixRoom import io.element.android.libraries.matrixtest.room.FakeMatrixRoom
import io.element.android.libraries.textcomposer.MessageComposerMode import io.element.android.libraries.textcomposer.MessageComposerMode
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -134,14 +135,13 @@ class MessagesPresenterTest {
private fun TestScope.createMessagePresenter( private fun TestScope.createMessagePresenter(
matrixRoom: MatrixRoom = FakeMatrixRoom() matrixRoom: MatrixRoom = FakeMatrixRoom()
): MessagesPresenter { ): MessagesPresenter {
val matrixClient = FakeMatrixClient()
val messageComposerPresenter = MessageComposerPresenter( val messageComposerPresenter = MessageComposerPresenter(
appCoroutineScope = this, appCoroutineScope = this,
room = matrixRoom room = matrixRoom
) )
val timelinePresenter = TimelinePresenter( val timelinePresenter = TimelinePresenter(
coroutineDispatchers = testCoroutineDispatchers(), timelineItemsFactory = aTimelineItemsFactory(),
client = matrixClient,
room = matrixRoom, room = matrixRoom,
) )
val actionListPresenter = ActionListPresenter() val actionListPresenter = ActionListPresenter()
@ -154,25 +154,3 @@ class MessagesPresenterTest {
} }
} }
// TODO Move to common module to reuse
fun testCoroutineDispatchers() = CoroutineDispatchers(
io = UnconfinedTestDispatcher(),
computation = UnconfinedTestDispatcher(),
main = UnconfinedTestDispatcher(),
diffUpdateDispatcher = UnconfinedTestDispatcher(),
)
// TODO Move to common module to reuse and remove this duplication
private fun aMessageEvent(
isMine: Boolean = true,
content: TimelineItemContent = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null),
) = TimelineItem.MessageEvent(
id = AN_EVENT_ID,
senderId = A_USER_ID.value,
senderDisplayName = A_USER_NAME,
senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME),
content = content,
sentTime = "",
isMine = isMine,
reactionsState = TimelineItemReactions(persistentListOf())
)

14
features/messages/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt

@ -25,9 +25,9 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.actionlist.model.TimelineItemAction import io.element.android.features.messages.actionlist.model.TimelineItemAction
import io.element.android.features.messages.timeline.model.TimelineItem import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.features.messages.timeline.model.TimelineItemReactions import io.element.android.features.messages.timeline.model.TimelineItemReactions
import io.element.android.features.messages.timeline.model.content.TimelineItemContent import io.element.android.features.messages.timeline.model.event.TimelineItemEventContent
import io.element.android.features.messages.timeline.model.content.TimelineItemRedactedContent import io.element.android.features.messages.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.timeline.model.content.TimelineItemTextContent import io.element.android.features.messages.timeline.model.event.TimelineItemTextContent
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrixtest.AN_EVENT_ID import io.element.android.libraries.matrixtest.AN_EVENT_ID
import io.element.android.libraries.matrixtest.A_MESSAGE import io.element.android.libraries.matrixtest.A_MESSAGE
@ -37,6 +37,7 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
import org.matrix.rustcomponents.sdk.TimelineItemContent
class ActionListPresenterTest { class ActionListPresenterTest {
@Test @Test
@ -163,9 +164,10 @@ class ActionListPresenterTest {
private fun aMessageEvent( private fun aMessageEvent(
isMine: Boolean, isMine: Boolean,
content: TimelineItemContent, content: TimelineItemEventContent,
) = TimelineItem.MessageEvent( ) = TimelineItem.Event(
id = AN_EVENT_ID, id = AN_EVENT_ID.value,
eventId = AN_EVENT_ID,
senderId = A_USER_ID.value, senderId = A_USER_ID.value,
senderDisplayName = A_USER_NAME, senderDisplayName = A_USER_NAME,
senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME), senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME),

43
features/messages/src/test/kotlin/io/element/android/features/messages/fixtures/aMessageEvent.kt

@ -0,0 +1,43 @@
/*
* 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.fixtures
import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.features.messages.timeline.model.TimelineItemReactions
import io.element.android.features.messages.timeline.model.event.TimelineItemEventContent
import io.element.android.features.messages.timeline.model.event.TimelineItemTextContent
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrixtest.AN_EVENT_ID
import io.element.android.libraries.matrixtest.A_MESSAGE
import io.element.android.libraries.matrixtest.A_USER_ID
import io.element.android.libraries.matrixtest.A_USER_NAME
import kotlinx.collections.immutable.persistentListOf
internal fun aMessageEvent(
isMine: Boolean = true,
content: TimelineItemEventContent = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null),
) = TimelineItem.Event(
id = AN_EVENT_ID.value,
eventId = AN_EVENT_ID,
senderId = A_USER_ID.value,
senderDisplayName = A_USER_NAME,
senderAvatar = AvatarData(A_USER_ID.value, A_USER_NAME),
content = content,
sentTime = "",
isMine = isMine,
reactionsState = TimelineItemReactions(persistentListOf())
)

28
features/messages/src/test/kotlin/io/element/android/features/messages/fixtures/testCoroutineDispatchers.kt

@ -0,0 +1,28 @@
/*
* 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.fixtures
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import kotlinx.coroutines.test.UnconfinedTestDispatcher
// TODO Move to common module to reuse
internal fun testCoroutineDispatchers() = CoroutineDispatchers(
io = UnconfinedTestDispatcher(),
computation = UnconfinedTestDispatcher(),
main = UnconfinedTestDispatcher(),
diffUpdateDispatcher = UnconfinedTestDispatcher(),
)

52
features/messages/src/test/kotlin/io/element/android/features/messages/fixtures/timelineItemsFactory.kt

@ -0,0 +1,52 @@
/*
* 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.fixtures
import io.element.android.features.messages.timeline.factories.TimelineItemsFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentFailedToParseMessageFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentFailedToParseStateFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentMessageFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentProfileChangeFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentRedactedFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentRoomMembershipFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentStateFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentStickerFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemContentUTDFactory
import io.element.android.features.messages.timeline.factories.event.TimelineItemEventFactory
import io.element.android.features.messages.timeline.factories.virtual.TimelineItemDaySeparatorFactory
import io.element.android.features.messages.timeline.factories.virtual.TimelineItemVirtualFactory
internal fun aTimelineItemsFactory() = TimelineItemsFactory(
dispatchers = testCoroutineDispatchers(),
eventItemFactory = TimelineItemEventFactory(
TimelineItemContentFactory(
messageFactory = TimelineItemContentMessageFactory(),
redactedMessageFactory = TimelineItemContentRedactedFactory(),
stickerFactory = TimelineItemContentStickerFactory(),
utdFactory = TimelineItemContentUTDFactory(),
roomMembershipFactory = TimelineItemContentRoomMembershipFactory(),
profileChangeFactory = TimelineItemContentProfileChangeFactory(),
stateFactory = TimelineItemContentStateFactory(),
failedToParseMessageFactory = TimelineItemContentFailedToParseMessageFactory(),
failedToParseStateFactory = TimelineItemContentFailedToParseStateFactory()
)
),
virtualItemFactory = TimelineItemVirtualFactory(
daySeparatorFactory = TimelineItemDaySeparatorFactory(),
)
)

50
features/messages/src/test/kotlin/io/element/android/features/messages/timeline/TimelinePresenterTest.kt

@ -22,10 +22,8 @@ import app.cash.molecule.RecompositionClock
import app.cash.molecule.moleculeFlow import app.cash.molecule.moleculeFlow
import app.cash.turbine.test import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.timeline.model.TimelineItem import io.element.android.features.messages.fixtures.aTimelineItemsFactory
import io.element.android.libraries.matrix.timeline.MatrixTimelineItem
import io.element.android.libraries.matrixtest.AN_EVENT_ID import io.element.android.libraries.matrixtest.AN_EVENT_ID
import io.element.android.libraries.matrixtest.FakeMatrixClient
import io.element.android.libraries.matrixtest.room.FakeMatrixRoom import io.element.android.libraries.matrixtest.room.FakeMatrixRoom
import io.element.android.libraries.matrixtest.timeline.FakeMatrixTimeline import io.element.android.libraries.matrixtest.timeline.FakeMatrixTimeline
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -36,9 +34,8 @@ class TimelinePresenterTest {
@Test @Test
fun `present - initial state`() = runTest { fun `present - initial state`() = runTest {
val presenter = TimelinePresenter( val presenter = TimelinePresenter(
testCoroutineDispatchers(), timelineItemsFactory = aTimelineItemsFactory(),
FakeMatrixClient(), room = FakeMatrixRoom(),
FakeMatrixRoom()
) )
moleculeFlow(RecompositionClock.Immediate) { moleculeFlow(RecompositionClock.Immediate) {
presenter.present() presenter.present()
@ -53,19 +50,19 @@ class TimelinePresenterTest {
val matrixTimeline = FakeMatrixTimeline() val matrixTimeline = FakeMatrixTimeline()
val matrixRoom = FakeMatrixRoom(matrixTimeline = matrixTimeline) val matrixRoom = FakeMatrixRoom(matrixTimeline = matrixTimeline)
val presenter = TimelinePresenter( val presenter = TimelinePresenter(
testCoroutineDispatchers(), timelineItemsFactory = aTimelineItemsFactory(),
FakeMatrixClient(), room = matrixRoom,
matrixRoom
) )
moleculeFlow(RecompositionClock.Immediate) { moleculeFlow(RecompositionClock.Immediate) {
presenter.present() presenter.present()
}.test { }.test {
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.hasMoreToLoad).isTrue() assertThat(initialState.paginationState.canBackPaginate).isTrue()
matrixTimeline.givenHasMoreToLoad(false) matrixTimeline.updatePaginationState {
initialState.eventSink.invoke(TimelineEvents.LoadMore) copy(canBackPaginate = false)
}
val loadedState = awaitItem() val loadedState = awaitItem()
assertThat(loadedState.hasMoreToLoad).isFalse() assertThat(loadedState.paginationState.canBackPaginate).isFalse()
} }
} }
@ -74,9 +71,8 @@ class TimelinePresenterTest {
val matrixTimeline = FakeMatrixTimeline() val matrixTimeline = FakeMatrixTimeline()
val matrixRoom = FakeMatrixRoom(matrixTimeline = matrixTimeline) val matrixRoom = FakeMatrixRoom(matrixTimeline = matrixTimeline)
val presenter = TimelinePresenter( val presenter = TimelinePresenter(
testCoroutineDispatchers(), timelineItemsFactory = aTimelineItemsFactory(),
FakeMatrixClient(), room = matrixRoom,
matrixRoom
) )
moleculeFlow(RecompositionClock.Immediate) { moleculeFlow(RecompositionClock.Immediate) {
presenter.present() presenter.present()
@ -91,26 +87,4 @@ class TimelinePresenterTest {
assertThat(withoutHighlightedState.highlightedEventId).isNull() assertThat(withoutHighlightedState.highlightedEventId).isNull()
} }
} }
@Test
fun `present - test callback`() = runTest {
val matrixTimeline = FakeMatrixTimeline()
val matrixRoom = FakeMatrixRoom(matrixTimeline = matrixTimeline)
val presenter = TimelinePresenter(
testCoroutineDispatchers(),
FakeMatrixClient(),
matrixRoom
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.timelineItems).isEmpty()
// Simulate callback from the SDK
matrixTimeline.callback?.onPushedTimelineItem(MatrixTimelineItem.Virtual)
val nonEmptyState = awaitItem()
assertThat(nonEmptyState.timelineItems).isNotEmpty()
assertThat(nonEmptyState.timelineItems[0]).isEqualTo(TimelineItem.Virtual("virtual_item_0"))
}
}
} }

4
libraries/matrixtest/src/main/kotlin/io/element/android/libraries/matrixtest/timeline/FakeMatrixTimeline.kt

@ -31,6 +31,10 @@ class FakeMatrixTimeline : MatrixTimeline {
MatrixTimeline.PaginationState(canBackPaginate = true, isBackPaginating = false) MatrixTimeline.PaginationState(canBackPaginate = true, isBackPaginating = false)
) )
fun updatePaginationState(update: (MatrixTimeline.PaginationState.() -> MatrixTimeline.PaginationState)) {
paginationState.value = update(paginationState.value)
}
override fun paginationState(): StateFlow<MatrixTimeline.PaginationState> { override fun paginationState(): StateFlow<MatrixTimeline.PaginationState> {
return paginationState return paginationState
} }

Loading…
Cancel
Save