Merge branch 'vector-im:develop' into develop
This commit is contained in:
commit
ff99cf3625
42 changed files with 118 additions and 197 deletions
5
.maestro/tests/assertions/assertRoomListSynced.yaml
Normal file
5
.maestro/tests/assertions/assertRoomListSynced.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
appId: ${APP_ID}
|
||||||
|
---
|
||||||
|
- extendedWaitUntil:
|
||||||
|
visible: ${ROOM_NAME}
|
||||||
|
timeout: 10_000
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
appId: ${APP_ID}
|
appId: ${APP_ID}
|
||||||
---
|
---
|
||||||
|
- runFlow: ../assertions/assertRoomListSynced.yaml
|
||||||
- tapOn: "search"
|
- tapOn: "search"
|
||||||
- inputText: ${ROOM_NAME.substring(0, 3)}
|
- inputText: ${ROOM_NAME.substring(0, 3)}
|
||||||
- takeScreenshot: build/maestro/400-SearchRoom
|
- takeScreenshot: build/maestro/400-SearchRoom
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.appnav
|
package io.element.android.appnav
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -30,7 +28,6 @@ import io.element.android.features.rageshake.test.crash.FakeCrashDataStore
|
||||||
import io.element.android.features.rageshake.test.rageshake.FakeRageShake
|
import io.element.android.features.rageshake.test.rageshake.FakeRageShake
|
||||||
import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore
|
import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore
|
||||||
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.appnav.loggedin
|
package io.element.android.appnav.loggedin
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -29,7 +27,6 @@ import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter
|
||||||
import io.element.android.libraries.push.api.PushService
|
import io.element.android.libraries.push.api.PushService
|
||||||
import io.element.android.libraries.push.providers.api.Distributor
|
import io.element.android.libraries.push.providers.api.Distributor
|
||||||
import io.element.android.libraries.push.providers.api.PushProvider
|
import io.element.android.libraries.push.providers.api.PushProvider
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,12 @@ class CreateRoomRootPresenter @Inject constructor(
|
||||||
|
|
||||||
fun startDm(matrixUser: MatrixUser) {
|
fun startDm(matrixUser: MatrixUser) {
|
||||||
startDmAction.value = Async.Uninitialized
|
startDmAction.value = Async.Uninitialized
|
||||||
val existingDM = matrixClient.findDM(matrixUser.userId)
|
matrixClient.findDM(matrixUser.userId).use { existingDM ->
|
||||||
if (existingDM == null) {
|
if (existingDM == null) {
|
||||||
localCoroutineScope.createDM(matrixUser, startDmAction)
|
localCoroutineScope.createDM(matrixUser, startDmAction)
|
||||||
} else {
|
} else {
|
||||||
startDmAction.value = Async.Success(existingDM.roomId)
|
startDmAction.value = Async.Success(existingDM.roomId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,9 @@ import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
internal class AllMatrixUsersDataSourceTest {
|
internal class AllMatrixUsersDataSourceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.addpeople
|
package io.element.android.features.createroom.impl.addpeople
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -26,7 +24,6 @@ import io.element.android.features.createroom.impl.CreateRoomDataStore
|
||||||
import io.element.android.features.userlist.api.UserListDataStore
|
import io.element.android.features.userlist.api.UserListDataStore
|
||||||
import io.element.android.features.userlist.test.FakeUserListDataSource
|
import io.element.android.features.userlist.test.FakeUserListDataSource
|
||||||
import io.element.android.features.userlist.test.FakeUserListPresenterFactory
|
import io.element.android.features.userlist.test.FakeUserListPresenterFactory
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
|
@ -36,7 +34,6 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.root
|
package io.element.android.features.createroom.impl.root
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -35,7 +33,6 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
||||||
|
|
@ -131,14 +131,18 @@ class InviteListPresenter @Inject constructor(
|
||||||
|
|
||||||
private fun CoroutineScope.acceptInvite(roomId: RoomId, acceptedAction: MutableState<Async<RoomId>>) = launch {
|
private fun CoroutineScope.acceptInvite(roomId: RoomId, acceptedAction: MutableState<Async<RoomId>>) = launch {
|
||||||
suspend {
|
suspend {
|
||||||
client.getRoom(roomId)?.acceptInvitation()?.getOrThrow()
|
client.getRoom(roomId)?.use {
|
||||||
|
it.acceptInvitation().getOrThrow()
|
||||||
|
}
|
||||||
roomId
|
roomId
|
||||||
}.execute(acceptedAction)
|
}.execute(acceptedAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CoroutineScope.declineInvite(roomId: RoomId, declinedAction: MutableState<Async<Unit>>) = launch {
|
private fun CoroutineScope.declineInvite(roomId: RoomId, declinedAction: MutableState<Async<Unit>>) = launch {
|
||||||
suspend {
|
suspend {
|
||||||
client.getRoom(roomId)?.rejectInvitation()?.getOrThrow() ?: Unit
|
client.getRoom(roomId)?.use {
|
||||||
|
it.rejectInvitation().getOrThrow()
|
||||||
|
} ?: Unit
|
||||||
}.execute(declinedAction)
|
}.execute(declinedAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,9 @@ import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
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.FakeRoomSummaryDataSource
|
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
class InviteListPresenterTests {
|
class InviteListPresenterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -509,5 +507,4 @@ class InviteListPresenterTests {
|
||||||
unreadNotificationCount = 0,
|
unreadNotificationCount = 0,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.login.impl.changeserver
|
package io.element.android.features.login.impl.changeserver
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -28,11 +26,9 @@ import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
|
||||||
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL_2
|
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL_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.auth.FakeAuthenticationService
|
import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
class ChangeServerPresenterTest {
|
class ChangeServerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - should start with default homeserver`() = runTest {
|
fun `present - should start with default homeserver`() = runTest {
|
||||||
|
|
|
||||||
|
|
@ -14,25 +14,18 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.login.impl.root
|
package io.element.android.features.login.impl.root
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
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.login.impl.root.LoggedInState
|
|
||||||
import io.element.android.features.login.impl.root.LoginFormState
|
|
||||||
import io.element.android.features.login.impl.root.LoginRootEvents
|
|
||||||
import io.element.android.features.login.impl.root.LoginRootPresenter
|
|
||||||
import io.element.android.libraries.matrix.test.A_HOMESERVER
|
import io.element.android.libraries.matrix.test.A_HOMESERVER
|
||||||
import io.element.android.libraries.matrix.test.A_PASSWORD
|
import io.element.android.libraries.matrix.test.A_PASSWORD
|
||||||
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_THROWABLE
|
import io.element.android.libraries.matrix.test.A_THROWABLE
|
||||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||||
import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
|
import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.logout.impl
|
package io.element.android.features.logout.impl
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -28,7 +26,6 @@ import io.element.android.libraries.architecture.Async
|
||||||
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_THROWABLE
|
import io.element.android.libraries.matrix.test.A_THROWABLE
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.messages
|
package io.element.android.features.messages
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -40,7 +38,6 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.mediapickers.test.FakePickerProvider
|
import io.element.android.libraries.mediapickers.test.FakePickerProvider
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
import io.element.android.libraries.textcomposer.MessageComposerMode
|
import io.element.android.libraries.textcomposer.MessageComposerMode
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.messages.actionlist
|
package io.element.android.features.messages.actionlist
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -23,9 +21,9 @@ 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.impl.actionlist.ActionListEvents
|
import io.element.android.features.messages.impl.actionlist.ActionListEvents
|
||||||
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListState
|
import io.element.android.features.messages.impl.actionlist.ActionListState
|
||||||
|
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItemReactions
|
import io.element.android.features.messages.impl.timeline.model.TimelineItemReactions
|
||||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||||
|
|
@ -37,7 +35,6 @@ import io.element.android.libraries.matrix.test.A_MESSAGE
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.messages.fixtures
|
package io.element.android.features.messages.fixtures
|
||||||
|
|
||||||
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
|
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
|
||||||
|
|
@ -34,7 +32,6 @@ import io.element.android.features.messages.impl.timeline.factories.virtual.Time
|
||||||
import io.element.android.features.messages.impl.timeline.factories.virtual.TimelineItemVirtualFactory
|
import io.element.android.features.messages.impl.timeline.factories.virtual.TimelineItemVirtualFactory
|
||||||
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
|
|
||||||
internal fun aTimelineItemsFactory() = TimelineItemsFactory(
|
internal fun aTimelineItemsFactory() = TimelineItemsFactory(
|
||||||
dispatchers = testCoroutineDispatchers(),
|
dispatchers = testCoroutineDispatchers(),
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,10 @@ import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
import io.element.android.libraries.textcomposer.MessageComposerMode
|
import io.element.android.libraries.textcomposer.MessageComposerMode
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.android.awaitFrame
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.test.runCurrent
|
import kotlinx.coroutines.test.runCurrent
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import kotlinx.coroutines.test.setMain
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
@ -302,30 +298,32 @@ class MessageComposerPresenterTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom()
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
pickerProvider.givenMimeType(MimeTypes.Images)
|
pickerProvider.givenMimeType(MimeTypes.Images)
|
||||||
mediaPreProcessor.givenResult(Result.success(
|
mediaPreProcessor.givenResult(
|
||||||
MediaUploadInfo.Image(
|
Result.success(
|
||||||
file = File("/some/path"),
|
MediaUploadInfo.Image(
|
||||||
info = ImageInfo(
|
|
||||||
width = null,
|
|
||||||
height = null,
|
|
||||||
mimetype = null,
|
|
||||||
size = null,
|
|
||||||
thumbnailInfo = null,
|
|
||||||
thumbnailUrl = null,
|
|
||||||
blurhash = null,
|
|
||||||
),
|
|
||||||
thumbnailInfo = ThumbnailProcessingInfo(
|
|
||||||
file = File("/some/path"),
|
file = File("/some/path"),
|
||||||
info = ThumbnailInfo(
|
info = ImageInfo(
|
||||||
width = null,
|
width = null,
|
||||||
height = null,
|
height = null,
|
||||||
mimetype = null,
|
mimetype = null,
|
||||||
size = null,
|
size = null,
|
||||||
|
thumbnailInfo = null,
|
||||||
|
thumbnailUrl = null,
|
||||||
|
blurhash = null,
|
||||||
),
|
),
|
||||||
blurhash = "",
|
thumbnailInfo = ThumbnailProcessingInfo(
|
||||||
|
file = File("/some/path"),
|
||||||
|
info = ThumbnailInfo(
|
||||||
|
width = null,
|
||||||
|
height = null,
|
||||||
|
mimetype = null,
|
||||||
|
size = null,
|
||||||
|
),
|
||||||
|
blurhash = "",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
))
|
)
|
||||||
moleculeFlow(RecompositionClock.Immediate) {
|
moleculeFlow(RecompositionClock.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -342,31 +340,33 @@ class MessageComposerPresenterTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom()
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
pickerProvider.givenMimeType(MimeTypes.Videos)
|
pickerProvider.givenMimeType(MimeTypes.Videos)
|
||||||
mediaPreProcessor.givenResult(Result.success(
|
mediaPreProcessor.givenResult(
|
||||||
MediaUploadInfo.Video(
|
Result.success(
|
||||||
file = File("/some/path"),
|
MediaUploadInfo.Video(
|
||||||
info = VideoInfo(
|
|
||||||
width = null,
|
|
||||||
height = null,
|
|
||||||
mimetype = null,
|
|
||||||
duration = null,
|
|
||||||
size = null,
|
|
||||||
thumbnailInfo = null,
|
|
||||||
thumbnailUrl = null,
|
|
||||||
blurhash = null,
|
|
||||||
),
|
|
||||||
thumbnailInfo = ThumbnailProcessingInfo(
|
|
||||||
file = File("/some/path"),
|
file = File("/some/path"),
|
||||||
info = ThumbnailInfo(
|
info = VideoInfo(
|
||||||
width = null,
|
width = null,
|
||||||
height = null,
|
height = null,
|
||||||
mimetype = null,
|
mimetype = null,
|
||||||
|
duration = null,
|
||||||
size = null,
|
size = null,
|
||||||
|
thumbnailInfo = null,
|
||||||
|
thumbnailUrl = null,
|
||||||
|
blurhash = null,
|
||||||
),
|
),
|
||||||
blurhash = "",
|
thumbnailInfo = ThumbnailProcessingInfo(
|
||||||
|
file = File("/some/path"),
|
||||||
|
info = ThumbnailInfo(
|
||||||
|
width = null,
|
||||||
|
height = null,
|
||||||
|
mimetype = null,
|
||||||
|
size = null,
|
||||||
|
),
|
||||||
|
blurhash = "",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
))
|
)
|
||||||
moleculeFlow(RecompositionClock.Immediate) {
|
moleculeFlow(RecompositionClock.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -394,7 +394,7 @@ class MessageComposerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - Pick media from gallery & cancel does nothing`() = runTest {
|
fun `present - Pick media from gallery & cancel does nothing`() = runTest {
|
||||||
val presenter = createPresenter(this)
|
val presenter = createPresenter(this)
|
||||||
with(pickerProvider){
|
with(pickerProvider) {
|
||||||
givenResult(null) // Simulate a user canceling the flow
|
givenResult(null) // Simulate a user canceling the flow
|
||||||
givenMimeType(MimeTypes.Images)
|
givenMimeType(MimeTypes.Images)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.messages.timeline
|
package io.element.android.features.messages.timeline
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -27,8 +25,6 @@ import io.element.android.features.messages.impl.timeline.TimelineEvents
|
||||||
import io.element.android.features.messages.impl.timeline.TimelinePresenter
|
import io.element.android.features.messages.impl.timeline.TimelinePresenter
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
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.timeline.FakeMatrixTimeline
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.preferences.impl.developer
|
package io.element.android.features.preferences.impl.developer
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -24,7 +22,6 @@ import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.preferences.impl.root
|
package io.element.android.features.preferences.impl.root
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -29,7 +27,6 @@ import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataSto
|
||||||
import io.element.android.libraries.architecture.Async
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.core.meta.BuildType
|
import io.element.android.libraries.core.meta.BuildType
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.rageshake.impl.bugreport
|
package io.element.android.features.rageshake.impl.bugreport
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -28,7 +26,6 @@ import io.element.android.features.rageshake.test.screenshot.A_SCREENSHOT_URI
|
||||||
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
||||||
import io.element.android.libraries.architecture.Async
|
import io.element.android.libraries.architecture.Async
|
||||||
import io.element.android.libraries.matrix.test.A_FAILURE_REASON
|
import io.element.android.libraries.matrix.test.A_FAILURE_REASON
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.rageshake.impl.crash.ui
|
package io.element.android.features.rageshake.impl.crash.ui
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -26,7 +24,6 @@ import io.element.android.features.rageshake.api.crash.CrashDetectionEvents
|
||||||
import io.element.android.features.rageshake.impl.crash.DefaultCrashDetectionPresenter
|
import io.element.android.features.rageshake.impl.crash.DefaultCrashDetectionPresenter
|
||||||
import io.element.android.features.rageshake.test.crash.A_CRASH_DATA
|
import io.element.android.features.rageshake.test.crash.A_CRASH_DATA
|
||||||
import io.element.android.features.rageshake.test.crash.FakeCrashDataStore
|
import io.element.android.features.rageshake.test.crash.FakeCrashDataStore
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.rageshake.impl.detection
|
package io.element.android.features.rageshake.impl.detection
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
|
@ -31,10 +29,10 @@ import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataSto
|
||||||
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
||||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class RageshakeDetectionPresenterTest {
|
class RageshakeDetectionPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -101,7 +99,7 @@ class RageshakeDetectionPresenterTest {
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionClock.Immediate) {
|
moleculeFlow(RecompositionClock.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test(timeout = 30.seconds) {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.isStarted).isFalse()
|
assertThat(initialState.isStarted).isFalse()
|
||||||
|
|
@ -155,7 +153,7 @@ class RageshakeDetectionPresenterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - screenshot then disable`() = runTest {
|
fun `present - screenshot then disable`() = runTest(timeout = 1.seconds) {
|
||||||
val screenshotHolder = FakeScreenshotHolder(screenshotUri = null)
|
val screenshotHolder = FakeScreenshotHolder(screenshotUri = null)
|
||||||
val rageshake = FakeRageShake(isAvailableValue = true)
|
val rageshake = FakeRageShake(isAvailableValue = true)
|
||||||
val rageshakeDataStore = FakeRageshakeDataStore(isEnabled = true)
|
val rageshakeDataStore = FakeRageshakeDataStore(isEnabled = true)
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.features.rageshake.impl.preferences
|
package io.element.android.features.rageshake.impl.preferences
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
import app.cash.molecule.RecompositionClock
|
||||||
|
|
@ -26,7 +24,6 @@ import io.element.android.features.rageshake.api.preferences.RageshakePreference
|
||||||
import io.element.android.features.rageshake.test.rageshake.A_SENSITIVITY
|
import io.element.android.features.rageshake.test.rageshake.A_SENSITIVITY
|
||||||
import io.element.android.features.rageshake.test.rageshake.FakeRageShake
|
import io.element.android.features.rageshake.test.rageshake.FakeRageShake
|
||||||
import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore
|
import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,9 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
||||||
import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled
|
import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
internal class DefaultInviteStateDataSourceTest {
|
internal class DefaultInviteStateDataSourceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -133,5 +131,4 @@ internal class DefaultInviteStateDataSourceTest {
|
||||||
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.NoInvites)
|
Truth.assertThat(awaitItem()).isEqualTo(InvitesState.NoInvites)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,11 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
|
||||||
import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled
|
import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled
|
||||||
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class) class RoomListPresenterTests {
|
class RoomListPresenterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - should start with no user and then load user with success`() = runTest {
|
fun `present - should start with no user and then load user with success`() = runTest {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.element.android.features.userlist.impl
|
package io.element.android.features.userlist.impl
|
||||||
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import app.cash.molecule.RecompositionClock
|
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
|
||||||
|
|
@ -30,14 +29,10 @@ import io.element.android.features.userlist.test.FakeUserListDataSource
|
||||||
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.user.MatrixUser
|
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
||||||
import io.mockk.coJustRun
|
|
||||||
import io.mockk.mockkConstructor
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
class DefaultUserListPresenterTests {
|
class DefaultUserListPresenterTests {
|
||||||
|
|
||||||
private val userListDataSource = FakeUserListDataSource()
|
private val userListDataSource = FakeUserListDataSource()
|
||||||
|
|
@ -136,9 +131,6 @@ class DefaultUserListPresenterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - select a user`() = runTest {
|
fun `present - select a user`() = runTest {
|
||||||
mockkConstructor(LazyListState::class)
|
|
||||||
coJustRun { anyConstructed<LazyListState>().scrollToItem(index = any()) }
|
|
||||||
|
|
||||||
val presenter = DefaultUserListPresenter(
|
val presenter = DefaultUserListPresenter(
|
||||||
UserListPresenterArgs(selectionMode = SelectionMode.Single),
|
UserListPresenterArgs(selectionMode = SelectionMode.Single),
|
||||||
userListDataSource,
|
userListDataSource,
|
||||||
|
|
@ -158,16 +150,15 @@ class DefaultUserListPresenterTests {
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(userA)
|
assertThat(awaitItem().selectedUsers).containsExactly(userA)
|
||||||
|
|
||||||
initialState.eventSink(UserListEvents.AddToSelection(userB))
|
initialState.eventSink(UserListEvents.AddToSelection(userB))
|
||||||
// the last added user should be presented first
|
assertThat(awaitItem().selectedUsers).containsExactly(userA, userB)
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(userB, userA)
|
|
||||||
|
|
||||||
initialState.eventSink(UserListEvents.AddToSelection(userABis))
|
initialState.eventSink(UserListEvents.AddToSelection(userABis))
|
||||||
initialState.eventSink(UserListEvents.AddToSelection(userC))
|
initialState.eventSink(UserListEvents.AddToSelection(userC))
|
||||||
// duplicated users should be ignored
|
// duplicated users should be ignored
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(userC, userB, userA)
|
assertThat(awaitItem().selectedUsers).containsExactly(userA, userB, userC)
|
||||||
|
|
||||||
initialState.eventSink(UserListEvents.RemoveFromSelection(userB))
|
initialState.eventSink(UserListEvents.RemoveFromSelection(userB))
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(userC, userA)
|
assertThat(awaitItem().selectedUsers).containsExactly(userA, userC)
|
||||||
initialState.eventSink(UserListEvents.RemoveFromSelection(userA))
|
initialState.eventSink(UserListEvents.RemoveFromSelection(userA))
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(userC)
|
assertThat(awaitItem().selectedUsers).containsExactly(userC)
|
||||||
initialState.eventSink(UserListEvents.RemoveFromSelection(userC))
|
initialState.eventSink(UserListEvents.RemoveFromSelection(userC))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ compose_bom = "2023.04.01"
|
||||||
composecompiler = "1.4.7"
|
composecompiler = "1.4.7"
|
||||||
|
|
||||||
# Coroutines
|
# Coroutines
|
||||||
coroutines = "1.6.4"
|
coroutines = "1.7.0"
|
||||||
|
|
||||||
# Accompanist
|
# Accompanist
|
||||||
accompanist = "0.30.1"
|
accompanist = "0.30.1"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.impl
|
package io.element.android.libraries.matrix.impl
|
||||||
|
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
|
|
@ -300,7 +302,6 @@ class RustMatrixClient constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
slidingSyncUpdateJob?.cancel()
|
slidingSyncUpdateJob?.cancel()
|
||||||
stopSync()
|
stopSync()
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,18 @@ import org.matrix.rustcomponents.sdk.RoomMember as RustRoomMember
|
||||||
|
|
||||||
object RoomMemberMapper {
|
object RoomMemberMapper {
|
||||||
|
|
||||||
fun map(roomMember: RustRoomMember): RoomMember =
|
fun map(roomMember: RustRoomMember): RoomMember = roomMember.use {
|
||||||
RoomMember(
|
RoomMember(
|
||||||
UserId(roomMember.userId()),
|
UserId(it.userId()),
|
||||||
roomMember.displayName(),
|
it.displayName(),
|
||||||
roomMember.avatarUrl(),
|
it.avatarUrl(),
|
||||||
mapMembership(roomMember.membership()),
|
mapMembership(it.membership()),
|
||||||
roomMember.isNameAmbiguous(),
|
it.isNameAmbiguous(),
|
||||||
roomMember.powerLevel(),
|
it.powerLevel(),
|
||||||
roomMember.normalizedPowerLevel(),
|
it.normalizedPowerLevel(),
|
||||||
roomMember.isIgnored(),
|
it.isIgnored(),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun mapMembership(membershipState: RustMembershipState): RoomMembershipState =
|
fun mapMembership(membershipState: RustMembershipState): RoomMembershipState =
|
||||||
when (membershipState) {
|
when (membershipState) {
|
||||||
|
|
|
||||||
|
|
@ -161,9 +161,10 @@ class RustMatrixRoom(
|
||||||
|
|
||||||
override suspend fun sendMessage(message: String): Result<Unit> = withContext(coroutineDispatchers.io) {
|
override suspend fun sendMessage(message: String): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||||
val transactionId = genTransactionId()
|
val transactionId = genTransactionId()
|
||||||
val content = messageEventContentFromMarkdown(message)
|
messageEventContentFromMarkdown(message).use { content ->
|
||||||
runCatching {
|
runCatching {
|
||||||
innerRoom.send(content, transactionId)
|
innerRoom.send(content, transactionId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@ class MatrixTimelineItemMapper(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun map(timelineItem: TimelineItem): MatrixTimelineItem = timelineItem.use {
|
fun map(timelineItem: TimelineItem): MatrixTimelineItem = timelineItem.use {
|
||||||
val asEvent = timelineItem.asEvent()
|
val asEvent = it.asEvent()
|
||||||
if (asEvent != null) {
|
if (asEvent != null) {
|
||||||
val eventTimelineItem = eventTimelineItemMapper.map(asEvent)
|
val eventTimelineItem = eventTimelineItemMapper.map(asEvent)
|
||||||
return MatrixTimelineItem.Event(eventTimelineItem)
|
return MatrixTimelineItem.Event(eventTimelineItem)
|
||||||
}
|
}
|
||||||
val asVirtual = timelineItem.asVirtual()
|
val asVirtual = it.asVirtual()
|
||||||
if (asVirtual != null) {
|
if (asVirtual != null) {
|
||||||
val virtualTimelineItem = virtualTimelineItemMapper.map(asVirtual)
|
val virtualTimelineItem = virtualTimelineItemMapper.map(asVirtual)
|
||||||
return MatrixTimelineItem.Virtual(virtualTimelineItem)
|
return MatrixTimelineItem.Virtual(virtualTimelineItem)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import org.matrix.rustcomponents.sdk.MessageFormat as RustMessageFormat
|
||||||
class EventMessageMapper {
|
class EventMessageMapper {
|
||||||
|
|
||||||
fun map(message: Message): MessageContent = message.use {
|
fun map(message: Message): MessageContent = message.use {
|
||||||
val type = message.msgtype().use { type ->
|
val type = it.msgtype().use { type ->
|
||||||
when (type) {
|
when (type) {
|
||||||
is MessageType.Audio -> {
|
is MessageType.Audio -> {
|
||||||
AudioMessageType(type.content.body, type.content.source.useUrl(), type.content.info?.map())
|
AudioMessageType(type.content.body, type.content.source.useUrl(), type.content.info?.map())
|
||||||
|
|
@ -68,9 +68,9 @@ class EventMessageMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MessageContent(
|
MessageContent(
|
||||||
body = message.body(),
|
body = it.body(),
|
||||||
inReplyTo = message.inReplyTo()?.eventId?.let(::EventId),
|
inReplyTo = it.inReplyTo()?.eventId?.let(::EventId),
|
||||||
isEdited = message.isEdited(),
|
isEdited = it.isEdited(),
|
||||||
type = type
|
type = type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,18 +31,18 @@ class EventTimelineItemMapper(private val contentMapper: TimelineEventContentMap
|
||||||
|
|
||||||
fun map(eventTimelineItem: RustEventTimelineItem): EventTimelineItem = eventTimelineItem.use {
|
fun map(eventTimelineItem: RustEventTimelineItem): EventTimelineItem = eventTimelineItem.use {
|
||||||
EventTimelineItem(
|
EventTimelineItem(
|
||||||
uniqueIdentifier = eventTimelineItem.uniqueIdentifier(),
|
uniqueIdentifier = it.uniqueIdentifier(),
|
||||||
eventId = eventTimelineItem.eventId()?.let { EventId(it) },
|
eventId = it.eventId()?.let { EventId(it) },
|
||||||
isEditable = eventTimelineItem.isEditable(),
|
isEditable = it.isEditable(),
|
||||||
isLocal = eventTimelineItem.isLocal(),
|
isLocal = it.isLocal(),
|
||||||
isOwn = eventTimelineItem.isOwn(),
|
isOwn = it.isOwn(),
|
||||||
isRemote = eventTimelineItem.isRemote(),
|
isRemote = it.isRemote(),
|
||||||
localSendState = eventTimelineItem.localSendState()?.map(),
|
localSendState = it.localSendState()?.map(),
|
||||||
reactions = eventTimelineItem.reactions().map(),
|
reactions = it.reactions().map(),
|
||||||
sender = UserId(eventTimelineItem.sender()),
|
sender = UserId(it.sender()),
|
||||||
senderProfile = eventTimelineItem.senderProfile().map(),
|
senderProfile = it.senderProfile().map(),
|
||||||
timestamp = eventTimelineItem.timestamp().toLong(),
|
timestamp = it.timestamp().toLong(),
|
||||||
content = contentMapper.map(eventTimelineItem.content())
|
content = contentMapper.map(it.content())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package io.element.android.libraries.matrix.impl.timeline.item.event
|
package io.element.android.libraries.matrix.impl.timeline.item.event
|
||||||
|
|
||||||
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.event.EventContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
||||||
|
|
@ -26,7 +27,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.RedactedConte
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventContent
|
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
|
||||||
import io.element.android.libraries.matrix.impl.media.map
|
import io.element.android.libraries.matrix.impl.media.map
|
||||||
|
|
@ -39,7 +39,7 @@ import org.matrix.rustcomponents.sdk.OtherState as RustOtherState
|
||||||
class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) {
|
class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) {
|
||||||
|
|
||||||
fun map(content: TimelineItemContent): EventContent = content.use {
|
fun map(content: TimelineItemContent): EventContent = content.use {
|
||||||
when (val kind = content.kind()) {
|
when (val kind = it.kind()) {
|
||||||
is TimelineItemContentKind.FailedToParseMessageLike -> {
|
is TimelineItemContentKind.FailedToParseMessageLike -> {
|
||||||
FailedToParseMessageLikeContent(
|
FailedToParseMessageLikeContent(
|
||||||
eventType = kind.eventType,
|
eventType = kind.eventType,
|
||||||
|
|
@ -54,7 +54,7 @@ class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMap
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TimelineItemContentKind.Message -> {
|
TimelineItemContentKind.Message -> {
|
||||||
val message = content.asMessage()
|
val message = it.asMessage()
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
UnknownContent
|
UnknownContent
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class, ExperimentalPermissionsApi::class)
|
@file:OptIn(ExperimentalPermissionsApi::class)
|
||||||
|
|
||||||
package io.element.android.libraries.permissions.impl
|
package io.element.android.libraries.permissions.impl
|
||||||
|
|
||||||
|
|
@ -25,7 +25,6 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.PermissionStatus
|
import com.google.accompanist.permissions.PermissionStatus
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.permissions.api.PermissionsEvents
|
import io.element.android.libraries.permissions.api.PermissionsEvents
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.libraries.permissions.noop
|
package io.element.android.libraries.permissions.noop
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionClock
|
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 kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.libraries.pushstore.impl.clientsecret
|
package io.element.android.libraries.pushstore.impl.clientsecret
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,10 @@ import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver
|
import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver
|
||||||
import io.element.android.libraries.matrix.session.SessionData
|
import io.element.android.libraries.matrix.session.SessionData
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
class DatabaseSessionStoreTests {
|
class DatabaseSessionStoreTests {
|
||||||
|
|
||||||
private lateinit var database: SessionDatabase
|
private lateinit var database: SessionDatabase
|
||||||
|
|
|
||||||
|
|
@ -33,17 +33,16 @@ import io.element.android.libraries.dateformatter.impl.LocalDateTimeProvider
|
||||||
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.asCoroutineDispatcher
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.TimeZone
|
import kotlinx.datetime.TimeZone
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.Executors
|
|
||||||
|
|
||||||
class RoomListScreen(
|
class RoomListScreen(
|
||||||
context: Context,
|
context: Context,
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
|
private val coroutineDispatchers: CoroutineDispatchers = Singleton.coroutineDispatchers,
|
||||||
) {
|
) {
|
||||||
private val clock = Clock.System
|
private val clock = Clock.System
|
||||||
private val locale = Locale.getDefault()
|
private val locale = Locale.getDefault()
|
||||||
|
|
@ -58,28 +57,24 @@ class RoomListScreen(
|
||||||
sessionVerificationService = sessionVerificationService,
|
sessionVerificationService = sessionVerificationService,
|
||||||
networkMonitor = NetworkMonitorImpl(context),
|
networkMonitor = NetworkMonitorImpl(context),
|
||||||
snackbarDispatcher = SnackbarDispatcher(),
|
snackbarDispatcher = SnackbarDispatcher(),
|
||||||
inviteStateDataSource = DefaultInviteStateDataSource(
|
inviteStateDataSource = DefaultInviteStateDataSource(matrixClient, DefaultSeenInvitesStore(context), coroutineDispatchers)
|
||||||
matrixClient,
|
|
||||||
DefaultSeenInvitesStore(context),
|
|
||||||
CoroutineDispatchers(
|
|
||||||
io = Dispatchers.IO,
|
|
||||||
computation = Dispatchers.Default,
|
|
||||||
main = Dispatchers.Main,
|
|
||||||
diffUpdateDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Content(modifier: Modifier = Modifier) {
|
fun Content(modifier: Modifier = Modifier) {
|
||||||
fun onRoomClicked(roomId: RoomId) {
|
fun onRoomClicked(roomId: RoomId) {
|
||||||
val room = matrixClient.getRoom(roomId)!!
|
|
||||||
val timeline = room.timeline()
|
|
||||||
Singleton.appScope.launch {
|
Singleton.appScope.launch {
|
||||||
timeline.apply {
|
withContext(coroutineDispatchers.io) {
|
||||||
initialize()
|
matrixClient.getRoom(roomId)!!.use { room ->
|
||||||
paginateBackwards(20, 50)
|
val timeline = room.timeline()
|
||||||
dispose()
|
|
||||||
|
timeline.apply {
|
||||||
|
// TODO This doesn't work reliably as initialize is asynchronous, and the timeline can't be used until it's finished
|
||||||
|
initialize()
|
||||||
|
paginateBackwards(20, 50)
|
||||||
|
dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
|
|
||||||
package io.element.android.services.appnavstate.impl
|
package io.element.android.services.appnavstate.impl
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
|
@ -28,11 +26,11 @@ import io.element.android.services.appnavstate.test.A_ROOM_OWNER
|
||||||
import io.element.android.services.appnavstate.test.A_SESSION_OWNER
|
import io.element.android.services.appnavstate.test.A_SESSION_OWNER
|
||||||
import io.element.android.services.appnavstate.test.A_SPACE_OWNER
|
import io.element.android.services.appnavstate.test.A_SPACE_OWNER
|
||||||
import io.element.android.services.appnavstate.test.A_THREAD_OWNER
|
import io.element.android.services.appnavstate.test.A_THREAD_OWNER
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertThrows
|
import org.junit.Assert.assertThrows
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class DefaultAppNavigationStateServiceTest {
|
class DefaultAppNavigationStateServiceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue