@ -18,23 +18,31 @@ package io.element.android.libraries.matrix.impl.roomlist
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import com.sun.jna.Pointer
import com.sun.jna.Pointer
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
import io.element.android.libraries.matrix.test.A_ROOM_NAME
import io.element.android.libraries.matrix.test.room.aRoomSummary
import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled
import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.Test
import org.matrix.rustcomponents.sdk.EventTimelineItem
import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.RoomHero
import org.matrix.rustcomponents.sdk.RoomInfo
import org.matrix.rustcomponents.sdk.RoomList
import org.matrix.rustcomponents.sdk.RoomList
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
import org.matrix.rustcomponents.sdk.RoomListEntry
import org.matrix.rustcomponents.sdk.RoomListInput
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.RoomListServiceInterface
import org.matrix.rustcomponents.sdk.RoomListServiceInterface
import org.matrix.rustcomponents.sdk.RoomListServiceStateListener
import org.matrix.rustcomponents.sdk.RoomListServiceStateListener
import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicatorListener
import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicatorListener
import org.matrix.rustcomponents.sdk.RoomMember
import org.matrix.rustcomponents.sdk.RoomNotificationMode
import org.matrix.rustcomponents.sdk.TaskHandle
import org.matrix.rustcomponents.sdk.TaskHandle
// NOTE: this class is using a fake implementation of a Rust SDK interface which returns actual Rust objects with pointers.
// NOTE: this class is using a fake implementation of a Rust SDK interface which returns actual Rust objects with pointers.
@ -44,33 +52,34 @@ class RoomSummaryListProcessorTest {
@Test
@Test
fun `Append adds new entries at the end of the list` ( ) = runTest {
fun `Append adds new entries at the end of the list` ( ) = runTest {
summaries . value = listOf ( aRoomSummaryFilled ( ) )
summaries . value = listOf ( aRoomSummary ( ) )
val processor = createProcessor ( )
val processor = createProcessor ( )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Append ( listOf ( RoomListEntry . Empty , RoomListEntry . Empty , RoomListEntry . Empty ) ) ) )
val newEntry = FakeRoomListItem ( A _ROOM _ID _2 )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Append ( listOf ( newEntry , newEntry , newEntry ) ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 4 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 4 )
assertThat ( summaries . value . subList ( 1 , 4 ) . all { it is RoomSummary . Empty } ) . isTrue ( )
assertThat ( summaries . value . subList ( 1 , 4 ) . all { it . roomId == A _ROOM _ID _2 } ) . isTrue ( )
}
}
@Test
@Test
fun `PushBack adds a new entry at the end of the list` ( ) = runTest {
fun `PushBack adds a new entry at the end of the list` ( ) = runTest {
summaries . value = listOf ( aRoomSummaryFilled ( ) )
summaries . value = listOf ( aRoomSummaryFilled ( ) )
val processor = createProcessor ( )
val processor = createProcessor ( )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PushBack ( RoomListEntry . Empty ) ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PushBack ( FakeRoomListItem ( A _ROOM _ID _2 ) ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 2 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 2 )
assertThat ( summaries . value . last ( ) ) . isInstanceOf ( RoomSummary . Empty :: class . java )
assertThat ( summaries . value . last ( ) . roomId ) . isEqualTo ( A _ROOM _ID _2 )
}
}
@Test
@Test
fun `PushFront inserts a new entry at the start of the list` ( ) = runTest {
fun `PushFront inserts a new entry at the start of the list` ( ) = runTest {
summaries . value = listOf ( aRoomSummaryFilled ( ) )
summaries . value = listOf ( aRoomSummaryFilled ( ) )
val processor = createProcessor ( )
val processor = createProcessor ( )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PushFront ( RoomListEntry . Empty ) ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PushFront ( FakeRoomListItem ( A _ROOM _ID _2 ) ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 2 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 2 )
assertThat ( summaries . value . first ( ) ) . isInstanceOf ( RoomSummary . Empty :: class . java )
assertThat ( summaries . value . first ( ) . roomId ) . isEqualTo ( A _ROOM _ID _2 )
}
}
@Test
@Test
@ -79,10 +88,10 @@ class RoomSummaryListProcessorTest {
val processor = createProcessor ( )
val processor = createProcessor ( )
val index = 0
val index = 0
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Set ( index . toUInt ( ) , RoomListEntry . Empty ) ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Set ( index . toUInt ( ) , FakeRoomListItem ( A _ROOM _ID _2 ) ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( summaries . value [ index ] ) . isInstanceOf ( RoomSummary . Empty :: class . java )
assertThat ( summaries . value [ index ] . roomId ) . isEqualTo ( A _ROOM _ID _2 )
}
}
@Test
@Test
@ -91,10 +100,10 @@ class RoomSummaryListProcessorTest {
val processor = createProcessor ( )
val processor = createProcessor ( )
val index = 0
val index = 0
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Insert ( index . toUInt ( ) , RoomListEntry . Empty ) ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Insert ( index . toUInt ( ) , FakeRoomListItem ( A _ROOM _ID _2 ) ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 2 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 2 )
assertThat ( summaries . value [ index ] ) . isInstanceOf ( RoomSummary . Empty :: class . java )
assertThat ( summaries . value [ index ] . roomId ) . isEqualTo ( A _ROOM _ID _2 )
}
}
@Test
@Test
@ -106,7 +115,7 @@ class RoomSummaryListProcessorTest {
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Remove ( index . toUInt ( ) ) ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Remove ( index . toUInt ( ) ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( ( summaries . value [ index ] as RoomSummary . Filled ) . identifier ( ) ) . isEqualTo ( A _ROOM _ID _2 . value )
assertThat ( summaries . value [ index ] . roomId ) . isEqualTo ( A _ROOM _ID _2 )
}
}
@Test
@Test
@ -118,7 +127,7 @@ class RoomSummaryListProcessorTest {
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PopBack ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PopBack ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( ( summaries . value [ index ] as RoomSummary . Filled ) . identifier ( ) ) . isEqualTo ( A _ROOM _ID . value )
assertThat ( summaries . value [ index ] . roomId ) . isEqualTo ( A _ROOM _ID )
}
}
@Test
@Test
@ -130,7 +139,7 @@ class RoomSummaryListProcessorTest {
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PopFront ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . PopFront ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( ( summaries . value [ index ] as RoomSummary . Filled ) . identifier ( ) ) . isEqualTo ( A _ROOM _ID _2 . value )
assertThat ( summaries . value [ index ] . roomId ) . isEqualTo ( A _ROOM _ID _2 )
}
}
@Test
@Test
@ -152,7 +161,7 @@ class RoomSummaryListProcessorTest {
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Truncate ( 1u ) ) )
processor . postUpdate ( listOf ( RoomListEntriesUpdate . Truncate ( 1u ) ) )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( summaries . value . count ( ) ) . isEqualTo ( 1 )
assertThat ( ( summaries . value [ index ] as RoomSummary . Filled ) . identifier ( ) ) . isEqualTo ( A _ROOM _ID . value )
assertThat ( summaries . value [ index ] . roomId ) . isEqualTo ( A _ROOM _ID )
}
}
private fun TestScope . createProcessor ( ) = RoomSummaryListProcessor (
private fun TestScope . createProcessor ( ) = RoomSummaryListProcessor (
@ -168,8 +177,6 @@ class RoomSummaryListProcessorTest {
return RoomList ( Pointer . NULL )
return RoomList ( Pointer . NULL )
}
}
override suspend fun applyInput ( input : RoomListInput ) = Unit
override fun room ( roomId : String ) : RoomListItem {
override fun room ( roomId : String ) : RoomListItem {
return RoomListItem ( Pointer . NULL )
return RoomListItem ( Pointer . NULL )
}
}
@ -183,3 +190,81 @@ class RoomSummaryListProcessorTest {
}
}
}
}
}
}
private fun aRustRoomInfo (
id : String = A _ROOM _ID . value ,
displayName : String = A _ROOM _NAME ,
rawName : String = A _ROOM _NAME ,
topic : String ? = null ,
avatarUrl : String ? = null ,
isDirect : Boolean = false ,
isPublic : Boolean = false ,
isSpace : Boolean = false ,
isTombstoned : Boolean = false ,
isFavourite : Boolean = false ,
canonicalAlias : String ? = null ,
alternativeAliases : List < String > = listOf ( ) ,
membership : Membership = Membership . JOINED ,
inviter : RoomMember ? = null ,
heroes : List < RoomHero > = listOf ( ) ,
activeMembersCount : ULong = 0uL ,
invitedMembersCount : ULong = 0uL ,
joinedMembersCount : ULong = 0uL ,
userPowerLevels : Map < String , Long > = mapOf ( ) ,
highlightCount : ULong = 0uL ,
notificationCount : ULong = 0uL ,
userDefinedNotificationMode : RoomNotificationMode ? = null ,
hasRoomCall : Boolean = false ,
activeRoomCallParticipants : List < String > = listOf ( ) ,
isMarkedUnread : Boolean = false ,
numUnreadMessages : ULong = 0uL ,
numUnreadNotifications : ULong = 0uL ,
numUnreadMentions : ULong = 0uL ,
) = RoomInfo (
id = id ,
displayName = displayName ,
rawName = rawName ,
topic = topic ,
avatarUrl = avatarUrl ,
isDirect = isDirect ,
isPublic = isPublic ,
isSpace = isSpace ,
isTombstoned = isTombstoned ,
isFavourite = isFavourite ,
canonicalAlias = canonicalAlias ,
alternativeAliases = alternativeAliases ,
membership = membership ,
inviter = inviter ,
heroes = heroes ,
activeMembersCount = activeMembersCount ,
invitedMembersCount = invitedMembersCount ,
joinedMembersCount = joinedMembersCount ,
userPowerLevels = userPowerLevels ,
highlightCount = highlightCount ,
notificationCount = notificationCount ,
userDefinedNotificationMode = userDefinedNotificationMode ,
hasRoomCall = hasRoomCall ,
activeRoomCallParticipants = activeRoomCallParticipants ,
isMarkedUnread = isMarkedUnread ,
numUnreadMessages = numUnreadMessages ,
numUnreadNotifications = numUnreadNotifications ,
numUnreadMentions = numUnreadMentions
)
class FakeRoomListItem (
private val roomId : RoomId ,
private val roomInfo : RoomInfo = aRustRoomInfo ( id = roomId . value ) ,
private val latestEvent : EventTimelineItem ? = null ,
) : RoomListItem ( NoPointer ) {
override fun id ( ) : String {
return roomId . value
}
override suspend fun roomInfo ( ) : RoomInfo {
return roomInfo
}
override suspend fun latestEvent ( ) : EventTimelineItem ? {
return latestEvent
}
}