Browse Source

StartDM : add tests

pull/1938/head
ganfra 6 months ago
parent
commit
3efbf4747d
  1. 1
      features/createroom/impl/build.gradle.kts
  2. 1
      features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt
  3. 84
      features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultStartDMActionTests.kt
  4. 164
      features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt
  5. 32
      features/createroom/test/build.gradle.kts
  6. 39
      features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt
  7. 1
      features/roomdetails/impl/build.gradle.kts
  8. 3
      features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt
  9. 1
      features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt
  10. 3
      features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt
  11. 1
      features/roomdetails/impl/src/main/res/values/localazy.xml
  12. 59
      features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt
  13. 88
      features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt
  14. 2
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt
  15. 8
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/StartDM.kt
  16. 5
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt
  17. 19
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt
  18. 4
      settings.gradle.kts
  19. 3
      tools/localazy/config.json

1
features/createroom/impl/build.gradle.kts

@ -67,6 +67,7 @@ dependencies { @@ -67,6 +67,7 @@ dependencies {
testImplementation(projects.libraries.mediaupload.test)
testImplementation(projects.libraries.permissions.test)
testImplementation(projects.libraries.usersearch.test)
testImplementation(projects.features.createroom.test)
testImplementation(projects.tests.testutils)
ksp(libs.showkase.processor)

1
features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt

@ -21,7 +21,6 @@ import com.squareup.anvil.annotations.ContributesBinding @@ -21,7 +21,6 @@ import com.squareup.anvil.annotations.ContributesBinding
import im.vector.app.features.analytics.plan.CreatedRoom
import io.element.android.features.createroom.api.StartDMAction
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId

84
features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultStartDMActionTests.kt

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
/*
* 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.createroom.impl
import androidx.compose.runtime.mutableStateOf
import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.CreatedRoom
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.StartDMResult
import io.element.android.libraries.matrix.test.A_FAILURE_REASON
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.test.FakeAnalyticsService
import kotlinx.coroutines.test.runTest
import org.junit.Test
class DefaultStartDMActionTests {
@Test
fun `when dm is found, assert state is updated with given room id`() = runTest {
val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(A_ROOM_ID)
}
val action = createStartDMAction(matrixClient)
val state = mutableStateOf<Async<RoomId>>(Async.Uninitialized)
action.execute(A_USER_ID, state)
assertThat(state.value).isEqualTo(Async.Success(A_ROOM_ID))
}
@Test
fun `when dm is not found, assert dm is created, state is updated with given room id and analytics get called`() = runTest {
val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(null)
givenCreateDmResult(Result.success(A_ROOM_ID))
}
val analyticsService = FakeAnalyticsService()
val action = createStartDMAction(matrixClient, analyticsService)
val state = mutableStateOf<Async<RoomId>>(Async.Uninitialized)
action.execute(A_USER_ID, state)
assertThat(state.value).isEqualTo(Async.Success(A_ROOM_ID))
assertThat(analyticsService.capturedEvents).containsExactly(CreatedRoom(isDM = true))
}
@Test
fun `when dm creation fails, assert state is updated with given error`() = runTest {
val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(null)
givenCreateDmResult(Result.failure(A_THROWABLE))
}
val action = createStartDMAction(matrixClient)
val state = mutableStateOf<Async<RoomId>>(Async.Uninitialized)
action.execute(A_USER_ID, state)
assertThat(state.value).isEqualTo(Async.Failure<RoomId>(StartDMResult.Failure(A_FAILURE_REASON)))
}
private fun createStartDMAction(
matrixClient: MatrixClient = FakeMatrixClient(),
analyticsService: AnalyticsService = FakeAnalyticsService(),
): DefaultStartDMAction {
return DefaultStartDMAction(
matrixClient = matrixClient,
analyticsService = analyticsService,
)
}
}

164
features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt

@ -20,25 +20,22 @@ import app.cash.molecule.RecompositionMode @@ -20,25 +20,22 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.CreatedRoom
import io.element.android.features.createroom.api.StartDMAction
import io.element.android.features.createroom.impl.userlist.FakeUserListPresenter
import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory
import io.element.android.features.createroom.impl.userlist.UserListDataStore
import io.element.android.features.createroom.impl.userlist.aUserListState
import io.element.android.features.createroom.test.FakeStartDMAction
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.StartDMResult
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.A_FAILURE_REASON
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.usersearch.test.FakeUserRepository
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -47,142 +44,57 @@ class CreateRoomRootPresenterTests { @@ -47,142 +44,57 @@ class CreateRoomRootPresenterTests {
@get:Rule
val warmUpRule = WarmUpRule()
private lateinit var userRepository: FakeUserRepository
private lateinit var presenter: CreateRoomRootPresenter
private lateinit var fakeUserListPresenter: FakeUserListPresenter
private lateinit var fakeMatrixClient: FakeMatrixClient
private lateinit var fakeAnalyticsService: FakeAnalyticsService
@Before
fun setup() {
fakeUserListPresenter = FakeUserListPresenter()
fakeMatrixClient = FakeMatrixClient()
fakeAnalyticsService = FakeAnalyticsService()
userRepository = FakeUserRepository()
presenter = CreateRoomRootPresenter(
presenterFactory = FakeUserListPresenterFactory(fakeUserListPresenter),
userRepository = userRepository,
userListDataStore = UserListDataStore(),
matrixClient = fakeMatrixClient,
analyticsService = fakeAnalyticsService,
buildMeta = aBuildMeta(),
)
}
@Test
fun `present - initial state`() = runTest {
fun `present - start DM action complete scenario`() = runTest {
val startDMAction = FakeStartDMAction()
val presenter = createCreateRoomRootPresenter(startDMAction)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.startDmAction).isInstanceOf(Async.Uninitialized::class.java)
assertThat(initialState.applicationName).isEqualTo(aBuildMeta().applicationName)
assertThat(initialState.userListState.selectedUsers).isEmpty()
assertThat(initialState.userListState.isSearchActive).isFalse()
assertThat(initialState.userListState.isMultiSelectionEnabled).isFalse()
}
}
@Test
fun `present - trigger create DM action`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:domain"))
val createDmResult = Result.success(RoomId("!createDmResult:domain"))
fakeMatrixClient.givenFindDmResult(null)
fakeMatrixClient.givenCreateDmResult(createDmResult)
initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
assertThat(awaitItem().startDmAction).isInstanceOf(Async.Loading::class.java)
val stateAfterStartDM = awaitItem()
assertThat(stateAfterStartDM.startDmAction).isInstanceOf(Async.Success::class.java)
assertThat(stateAfterStartDM.startDmAction.dataOrNull()).isEqualTo(createDmResult.getOrNull())
}
}
@Test
fun `present - creating a DM records analytics event`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:domain"))
val createDmResult = Result.success(RoomId("!createDmResult:domain"))
fakeMatrixClient.givenFindDmResult(null)
fakeMatrixClient.givenCreateDmResult(createDmResult)
initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
skipItems(2)
val analyticsEvent = fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>().firstOrNull()
assertThat(analyticsEvent).isNotNull()
assertThat(analyticsEvent?.isDM).isTrue()
}
}
@Test
fun `present - trigger retrieve DM action`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:domain"))
val fakeDmResult = FakeMatrixRoom(roomId = RoomId("!fakeDmResult:domain"))
fakeMatrixClient.givenFindDmResult(fakeDmResult)
initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
val stateAfterStartDM = awaitItem()
assertThat(stateAfterStartDM.startDmAction).isInstanceOf(Async.Success::class.java)
assertThat(stateAfterStartDM.startDmAction.dataOrNull()).isEqualTo(fakeDmResult.roomId)
assertThat(fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()
}
}
@Test
fun `present - trigger retry create DM action`() = runTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:domain"))
val createDmResult = Result.success(RoomId("!createDmResult:domain"))
fakeUserListPresenter.givenState(aUserListState().copy(selectedUsers = persistentListOf(matrixUser)))
fakeMatrixClient.givenFindDmResult(null)
fakeMatrixClient.givenCreateDmError(A_THROWABLE)
fakeMatrixClient.givenCreateDmResult(createDmResult)
val startDMSuccessResult = Async.Success(A_ROOM_ID)
val startDMFailureResult = Async.Failure<RoomId>(StartDMResult.Failure(A_FAILURE_REASON))
// Failure
startDMAction.givenExecuteResult(startDMFailureResult)
initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
assertThat(awaitItem().startDmAction).isInstanceOf(Async.Loading::class.java)
val stateAfterStartDM = awaitItem()
assertThat(stateAfterStartDM.startDmAction).isInstanceOf(Async.Failure::class.java)
assertThat(fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()
// Cancel
stateAfterStartDM.eventSink(CreateRoomRootEvents.CancelStartDM)
val stateAfterCancel = awaitItem()
assertThat(stateAfterCancel.startDmAction).isInstanceOf(Async.Uninitialized::class.java)
// Failure
stateAfterCancel.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
awaitItem().also { state ->
assertThat(state.startDmAction).isEqualTo(startDMFailureResult)
state.eventSink(CreateRoomRootEvents.CancelStartDM)
}
// Success
startDMAction.givenExecuteResult(startDMSuccessResult)
awaitItem().also { state ->
assertThat(state.startDmAction).isEqualTo(Async.Uninitialized)
state.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
}
assertThat(awaitItem().startDmAction).isInstanceOf(Async.Loading::class.java)
val stateAfterSecondAttempt = awaitItem()
assertThat(stateAfterSecondAttempt.startDmAction).isInstanceOf(Async.Failure::class.java)
assertThat(fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()
awaitItem().also { state ->
assertThat(state.startDmAction).isEqualTo(startDMSuccessResult)
}
// Retry with success
fakeMatrixClient.givenCreateDmError(null)
stateAfterSecondAttempt.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
assertThat(awaitItem().startDmAction).isInstanceOf(Async.Loading::class.java)
val stateAfterRetryStartDM = awaitItem()
assertThat(stateAfterRetryStartDM.startDmAction).isInstanceOf(Async.Success::class.java)
assertThat(stateAfterRetryStartDM.startDmAction.dataOrNull()).isEqualTo(createDmResult.getOrNull())
}
}
private fun createCreateRoomRootPresenter(
startDMAction: StartDMAction = FakeStartDMAction(),
): CreateRoomRootPresenter {
return CreateRoomRootPresenter(
presenterFactory = FakeUserListPresenterFactory(FakeUserListPresenter()),
userRepository = FakeUserRepository(),
userListDataStore = UserListDataStore(),
startDMAction = startDMAction,
buildMeta = aBuildMeta(),
)
}
}

32
features/createroom/test/build.gradle.kts

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 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.
*/
plugins {
id("io.element.android-compose-library")
}
android {
namespace = "io.element.android.features.createroom.test"
}
dependencies {
implementation(libs.coroutines.core)
implementation(projects.libraries.matrix.api)
implementation(projects.libraries.matrix.test)
implementation(projects.tests.testutils)
implementation(projects.libraries.architecture)
api(projects.features.createroom.api)
}

39
features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
/*
* 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.createroom.test
import androidx.compose.runtime.MutableState
import io.element.android.features.createroom.api.StartDMAction
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.tests.testutils.simulateLongTask
class FakeStartDMAction : StartDMAction {
private var executeResult: Async<RoomId> = Async.Success(A_ROOM_ID)
fun givenExecuteResult(result: Async<RoomId>) {
executeResult = result
}
override suspend fun execute(userId: UserId, actionState: MutableState<Async<RoomId>>) = simulateLongTask {
actionState.value = Async.Loading()
actionState.value = executeResult
}
}

1
features/roomdetails/impl/build.gradle.kts

@ -68,6 +68,7 @@ dependencies { @@ -68,6 +68,7 @@ dependencies {
testImplementation(projects.libraries.featureflag.test)
testImplementation(projects.tests.testutils)
testImplementation(projects.features.leaveroom.test)
testImplementation(projects.features.createroom.test)
ksp(libs.showkase.processor)
}

3
features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt

@ -25,16 +25,13 @@ import androidx.compose.runtime.produceState @@ -25,16 +25,13 @@ import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import com.squareup.anvil.annotations.ContributesBinding
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.element.android.features.createroom.api.StartDMAction
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState.ConfirmationDialog
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.di.RoomScope
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.UserId

1
features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt

@ -28,6 +28,7 @@ open class RoomMemberDetailsStateProvider : PreviewParameterProvider<RoomMemberD @@ -28,6 +28,7 @@ open class RoomMemberDetailsStateProvider : PreviewParameterProvider<RoomMemberD
aRoomMemberDetailsState().copy(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Block),
aRoomMemberDetailsState().copy(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Unblock),
aRoomMemberDetailsState().copy(isBlocked = Async.Loading(true)),
aRoomMemberDetailsState().copy(startDmActionState = Async.Loading()),
// Add other states here
)
}

3
features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt

@ -30,6 +30,7 @@ import androidx.compose.ui.res.stringResource @@ -30,6 +30,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.roomdetails.impl.R
import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs
import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection
import io.element.android.libraries.designsystem.components.async.AsyncView
@ -91,7 +92,7 @@ fun RoomMemberDetailsView( @@ -91,7 +92,7 @@ fun RoomMemberDetailsView(
async = state.startDmActionState,
progressText = stringResource(CommonStrings.common_starting_chat),
onSuccess = onDMStarted,
errorMessage = { stringResource(CommonStrings.common_error) },
errorMessage = { stringResource(R.string.screen_start_chat_error_starting_chat) },
onRetry = { state.eventSink(RoomMemberDetailsEvents.StartDM) },
onErrorDismiss = { state.eventSink(RoomMemberDetailsEvents.ClearStartDMState) },
)

1
features/roomdetails/impl/src/main/res/values/localazy.xml

@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
<string name="screen_room_notification_settings_mentions_only_disclaimer">"Your homeserver does not support this option in encrypted rooms, you won\'t get notified in this room."</string>
<string name="screen_room_notification_settings_mode_all_messages">"All messages"</string>
<string name="screen_room_notification_settings_room_custom_settings_title">"In this room, notify me for"</string>
<string name="screen_start_chat_error_starting_chat">"An error occurred when trying to start a chat"</string>
<string name="screen_dm_details_block_alert_action">"Block"</string>
<string name="screen_dm_details_block_alert_description">"Blocked users won\'t be able to send you messages and all their messages will be hidden. You can unblock them anytime."</string>
<string name="screen_dm_details_block_user">"Block user"</string>

59
features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt

@ -20,6 +20,7 @@ import app.cash.molecule.RecompositionMode @@ -20,6 +20,7 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.createroom.test.FakeStartDMAction
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
import io.element.android.features.leaveroom.fake.FakeLeaveRoomPresenter
@ -45,10 +46,11 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2 @@ -45,10 +46,11 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.consumeItemsUntilPredicate
import io.element.android.tests.testutils.testCoroutineDispatchers
import io.element.android.tests.testutils.WarmUpRule
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@ -60,16 +62,16 @@ class RoomDetailsPresenterTests { @@ -60,16 +62,16 @@ class RoomDetailsPresenterTests {
@get:Rule
val warmUpRule = WarmUpRule()
private fun createRoomDetailsPresenter(
private fun TestScope.createRoomDetailsPresenter(
room: MatrixRoom,
leaveRoomPresenter: LeaveRoomPresenter = FakeLeaveRoomPresenter(),
dispatchers: CoroutineDispatchers,
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService()
): RoomDetailsPresenter {
val matrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService)
val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory {
override fun create(roomMemberId: UserId): RoomMemberDetailsPresenter {
return RoomMemberDetailsPresenter(matrixClient, room, roomMemberId)
return RoomMemberDetailsPresenter(roomMemberId, matrixClient, room, FakeStartDMAction())
}
}
val featureFlagService = FakeFeatureFlagService(
@ -89,7 +91,7 @@ class RoomDetailsPresenterTests { @@ -89,7 +91,7 @@ class RoomDetailsPresenterTests {
@Test
fun `present - initial state is created from room info`() = runTest {
val room = aMatrixRoom()
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -108,7 +110,7 @@ class RoomDetailsPresenterTests { @@ -108,7 +110,7 @@ class RoomDetailsPresenterTests {
@Test
fun `present - initial state with no room name`() = runTest {
val room = aMatrixRoom(name = null)
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -130,7 +132,7 @@ class RoomDetailsPresenterTests { @@ -130,7 +132,7 @@ class RoomDetailsPresenterTests {
val roomMembers = listOf(myRoomMember, otherRoomMember)
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -164,7 +166,7 @@ class RoomDetailsPresenterTests { @@ -164,7 +166,7 @@ class RoomDetailsPresenterTests {
val room = aMatrixRoom().apply {
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -179,7 +181,7 @@ class RoomDetailsPresenterTests { @@ -179,7 +181,7 @@ class RoomDetailsPresenterTests {
val room = aMatrixRoom().apply {
givenCanInviteResult(Result.failure(Throwable("Whoops")))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -197,7 +199,7 @@ class RoomDetailsPresenterTests { @@ -197,7 +199,7 @@ class RoomDetailsPresenterTests {
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.failure(Throwable("Whelp")))
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -226,7 +228,7 @@ class RoomDetailsPresenterTests { @@ -226,7 +228,7 @@ class RoomDetailsPresenterTests {
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -241,6 +243,7 @@ class RoomDetailsPresenterTests { @@ -241,6 +243,7 @@ class RoomDetailsPresenterTests {
cancelAndIgnoreRemainingEvents()
}
}
@Test
fun `present - initial state when in a DM with no topic`() = runTest {
val myRoomMember = aRoomMember(A_SESSION_ID)
@ -255,7 +258,7 @@ class RoomDetailsPresenterTests { @@ -255,7 +258,7 @@ class RoomDetailsPresenterTests {
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -276,7 +279,7 @@ class RoomDetailsPresenterTests { @@ -276,7 +279,7 @@ class RoomDetailsPresenterTests {
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -297,7 +300,7 @@ class RoomDetailsPresenterTests { @@ -297,7 +300,7 @@ class RoomDetailsPresenterTests {
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(false))
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -315,7 +318,7 @@ class RoomDetailsPresenterTests { @@ -315,7 +318,7 @@ class RoomDetailsPresenterTests {
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -333,7 +336,7 @@ class RoomDetailsPresenterTests { @@ -333,7 +336,7 @@ class RoomDetailsPresenterTests {
givenCanInviteResult(Result.success(false))
}
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -351,7 +354,11 @@ class RoomDetailsPresenterTests { @@ -351,7 +354,11 @@ class RoomDetailsPresenterTests {
fun `present - leave room event is passed on to leave room presenter`() = runTest {
val leaveRoomPresenter = FakeLeaveRoomPresenter()
val room = aMatrixRoom()
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers())
val presenter = createRoomDetailsPresenter(
room = room,
leaveRoomPresenter = leaveRoomPresenter,
dispatchers = testCoroutineDispatchers()
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -368,14 +375,18 @@ class RoomDetailsPresenterTests { @@ -368,14 +375,18 @@ class RoomDetailsPresenterTests {
val leaveRoomPresenter = FakeLeaveRoomPresenter()
val notificationSettingsService = FakeNotificationSettingsService()
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
val presenter = createRoomDetailsPresenter(
room = room,
leaveRoomPresenter = leaveRoomPresenter,
notificationSettingsService = notificationSettingsService,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
notificationSettingsService.setRoomNotificationMode(room.roomId, RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
val updatedState = consumeItemsUntilPredicate {
it.roomNotificationSettings?.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
it.roomNotificationSettings?.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
}.last()
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
cancelAndIgnoreRemainingEvents()
@ -384,16 +395,15 @@ class RoomDetailsPresenterTests { @@ -384,16 +395,15 @@ class RoomDetailsPresenterTests {
@Test
fun `present - mute room notifications`() = runTest {
val leaveRoomPresenter = FakeLeaveRoomPresenter()
val notificationSettingsService = FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
val presenter = createRoomDetailsPresenter(room = room, notificationSettingsService = notificationSettingsService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
awaitItem().eventSink(RoomDetailsEvent.MuteNotification)
val updatedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) {
it.roomNotificationSettings?.mode == RoomNotificationMode.MUTE
it.roomNotificationSettings?.mode == RoomNotificationMode.MUTE
}.last()
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MUTE)
cancelAndIgnoreRemainingEvents()
@ -402,19 +412,18 @@ class RoomDetailsPresenterTests { @@ -402,19 +412,18 @@ class RoomDetailsPresenterTests {
@Test
fun `present - unmute room notifications`() = runTest {
val leaveRoomPresenter = FakeLeaveRoomPresenter()
val notificationSettingsService = FakeNotificationSettingsService(
initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
initialEncryptedGroupDefaultMode = RoomNotificationMode.ALL_MESSAGES
)
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
val presenter = createRoomDetailsPresenter(room = room, notificationSettingsService = notificationSettingsService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
awaitItem().eventSink(RoomDetailsEvent.UnmuteNotification)
val updatedState = consumeItemsUntilPredicate {
it.roomNotificationSettings?.mode == RoomNotificationMode.ALL_MESSAGES
it.roomNotificationSettings?.mode == RoomNotificationMode.ALL_MESSAGES
}.last()
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.ALL_MESSAGES)
cancelAndIgnoreRemainingEvents()

88
features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt

@ -20,13 +20,22 @@ import app.cash.molecule.RecompositionMode @@ -20,13 +20,22 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth
import io.element.android.features.createroom.api.StartDMAction
import io.element.android.features.createroom.test.FakeStartDMAction
import io.element.android.features.roomdetails.aMatrixRoom
import io.element.android.features.roomdetails.impl.members.aRoomMember
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsEvents
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.StartDMResult
import io.element.android.libraries.matrix.test.A_FAILURE_REASON
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.tests.testutils.WarmUpRule
@ -49,7 +58,10 @@ class RoomMemberDetailsPresenterTests { @@ -49,7 +58,10 @@ class RoomMemberDetailsPresenterTests {
givenUserAvatarUrlResult(Result.success("A custom avatar"))
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
}
val presenter = RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter(
room = room,
roomMember = roomMember
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -73,7 +85,10 @@ class RoomMemberDetailsPresenterTests { @@ -73,7 +85,10 @@ class RoomMemberDetailsPresenterTests {
givenUserAvatarUrlResult(Result.failure(Throwable()))
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
}
val presenter = RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter(
room = room,
roomMember = roomMember
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -93,7 +108,10 @@ class RoomMemberDetailsPresenterTests { @@ -93,7 +108,10 @@ class RoomMemberDetailsPresenterTests {
givenUserAvatarUrlResult(Result.success(null))
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
}
val presenter = RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter(
room = room,
roomMember = roomMember
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -107,9 +125,7 @@ class RoomMemberDetailsPresenterTests { @@ -107,9 +125,7 @@ class RoomMemberDetailsPresenterTests {
@Test
fun `present - BlockUser needing confirmation displays confirmation dialog`() = runTest {
val room = aMatrixRoom()
val roomMember = aRoomMember()
val presenter = RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -128,9 +144,7 @@ class RoomMemberDetailsPresenterTests { @@ -128,9 +144,7 @@ class RoomMemberDetailsPresenterTests {
@Test
fun `present - BlockUser and UnblockUser without confirmation change the 'blocked' state`() = runTest {
val room = aMatrixRoom()
val roomMember = aRoomMember()
val presenter = RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -147,11 +161,9 @@ class RoomMemberDetailsPresenterTests { @@ -147,11 +161,9 @@ class RoomMemberDetailsPresenterTests {
@Test
fun `present - BlockUser with error`() = runTest {
val room = aMatrixRoom()
val roomMember = aRoomMember()
val matrixClient = FakeMatrixClient()
matrixClient.givenIgnoreUserResult(Result.failure(A_THROWABLE))
val presenter = RoomMemberDetailsPresenter(matrixClient, room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter(client = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -168,9 +180,7 @@ class RoomMemberDetailsPresenterTests { @@ -168,9 +180,7 @@ class RoomMemberDetailsPresenterTests {
@Test
fun `present - UnblockUser needing confirmation displays confirmation dialog`() = runTest {
val room = aMatrixRoom()
val roomMember = aRoomMember()
val presenter = RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMember.userId)
val presenter = createRoomMemberDetailsPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
@ -186,4 +196,52 @@ class RoomMemberDetailsPresenterTests { @@ -186,4 +196,52 @@ class RoomMemberDetailsPresenterTests {
ensureAllEventsConsumed()
}
}
@Test
fun `present - start DM action complete scenario`() = runTest {
val startDMAction = FakeStartDMAction()
val presenter = createRoomMemberDetailsPresenter(startDMAction = startDMAction)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
Truth.assertThat(initialState.startDmActionState).isInstanceOf(Async.Uninitialized::class.java)
val startDMSuccessResult = Async.Success(A_ROOM_ID)
val startDMFailureResult = Async.Failure<RoomId>(StartDMResult.Failure(A_FAILURE_REASON))
// Failure
startDMAction.givenExecuteResult(startDMFailureResult)
initialState.eventSink(RoomMemberDetailsEvents.StartDM)
Truth.assertThat(awaitItem().startDmActionState).isInstanceOf(Async.Loading::class.java)
awaitItem().also { state ->
Truth.assertThat(state.startDmActionState).isEqualTo(startDMFailureResult)
state.eventSink(RoomMemberDetailsEvents.ClearStartDMState)
}
// Success
startDMAction.givenExecuteResult(startDMSuccessResult)
awaitItem().also { state ->
Truth.assertThat(state.startDmActionState).isEqualTo(Async.Uninitialized)
state.eventSink(RoomMemberDetailsEvents.StartDM)
}
Truth.assertThat(awaitItem().startDmActionState).isInstanceOf(Async.Loading::class.java)
awaitItem().also { state ->
Truth.assertThat(state.startDmActionState).isEqualTo(startDMSuccessResult)
}
}
}
private fun createRoomMemberDetailsPresenter(
client: MatrixClient = FakeMatrixClient(),
room: MatrixRoom = aMatrixRoom(),
roomMember: RoomMember = aRoomMember(),
startDMAction: StartDMAction = FakeStartDMAction()
): RoomMemberDetailsPresenter {
return RoomMemberDetailsPresenter(
roomMemberId = roomMember.userId,
client = client,
room = room,
startDMAction = startDMAction
)
}
}

2
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt

@ -41,7 +41,7 @@ interface MatrixClient : Closeable { @@ -41,7 +41,7 @@ interface MatrixClient : Closeable {
val roomListService: RoomListService
val mediaLoader: MatrixMediaLoader
suspend fun getRoom(roomId: RoomId): MatrixRoom?
suspend fun findDM(userId: UserId): MatrixRoom?
suspend fun findDM(userId: UserId): RoomId?
suspend fun ignoreUser(userId: UserId): Result<Unit>
suspend fun unignoreUser(userId: UserId): Result<Unit>
suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId>

8
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/StartDM.kt

@ -24,11 +24,9 @@ import io.element.android.libraries.matrix.api.core.UserId @@ -24,11 +24,9 @@ import io.element.android.libraries.matrix.api.core.UserId
* Try to find an existing DM with the given user, or create one if none exists.
*/
suspend fun MatrixClient.startDM(userId: UserId): StartDMResult {
val existingRoomId = findDM(userId)?.use { existingDM ->
existingDM.roomId
}
return if (existingRoomId != null) {
StartDMResult.Success(existingRoomId, isNew = false)
val existingDM = findDM(userId)
return if (existingDM != null) {
StartDMResult.Success(existingDM, isNew = false)
} else {
createDM(userId).fold(
{ StartDMResult.Success(it, isNew = true) },

5
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt

@ -240,9 +240,8 @@ class RustMatrixClient constructor( @@ -240,9 +240,8 @@ class RustMatrixClient constructor(
}
}
override suspend fun findDM(userId: UserId): MatrixRoom? {
val roomId = client.getDmRoom(userId.value)?.use { RoomId(it.id()) }
return roomId?.let { getRoom(it) }
override suspend fun findDM(userId: UserId): RoomId? {
return client.getDmRoom(userId.value)?.use { RoomId(it.id()) }
}
override suspend fun ignoreUser(userId: UserId): Result<Unit> = withContext(sessionDispatcher) {

19
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt

@ -39,7 +39,6 @@ import io.element.android.libraries.matrix.test.media.FakeMediaLoader @@ -39,7 +39,6 @@ import io.element.android.libraries.matrix.test.media.FakeMediaLoader
import io.element.android.libraries.matrix.test.notification.FakeNotificationService
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.pushers.FakePushersService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
@ -72,8 +71,7 @@ class FakeMatrixClient( @@ -72,8 +71,7 @@ class FakeMatrixClient(
private var unignoreUserResult: Result<Unit> = Result.success(Unit)
private var createRoomResult: Result<RoomId> = Result.success(A_ROOM_ID)
private var createDmResult: Result<RoomId> = Result.success(A_ROOM_ID)
private var createDmFailure: Throwable? = null
private var findDmResult: MatrixRoom? = FakeMatrixRoom()
private var findDmResult: RoomId? = A_ROOM_ID
private var logoutFailure: Throwable? = null
private val getRoomResults = mutableMapOf<RoomId, MatrixRoom>()
private val searchUserResults = mutableMapOf<String, Result<MatrixSearchUserResults>>()
@ -87,7 +85,7 @@ class FakeMatrixClient( @@ -87,7 +85,7 @@ class FakeMatrixClient(
return getRoomResults[roomId]
}
override suspend fun findDM(userId: UserId): MatrixRoom? {
override suspend fun findDM(userId: UserId): RoomId? {
return findDmResult
}
@ -99,14 +97,11 @@ class FakeMatrixClient( @@ -99,14 +97,11 @@ class FakeMatrixClient(
return unignoreUserResult
}
override suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId> {
delay(100)
override suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId> = simulateLongTask {
return createRoomResult
}
override suspend fun createDM(userId: UserId): Result<RoomId> {
delay(100)
createDmFailure?.let { throw it }
override suspend fun createDM(userId: UserId): Result<RoomId> = simulateLongTask {
return createDmResult
}
@ -206,11 +201,7 @@ class FakeMatrixClient( @@ -206,11 +201,7 @@ class FakeMatrixClient(
unignoreUserResult = result
}
fun givenCreateDmError(failure: Throwable?) {
createDmFailure = failure
}
fun givenFindDmResult(result: MatrixRoom?) {
fun givenFindDmResult(result: RoomId?) {
findDmResult = result
}

4
settings.gradle.kts

@ -82,9 +82,9 @@ includeProjects(File(rootDir, "services"), ":services") @@ -82,9 +82,9 @@ includeProjects(File(rootDir, "services"), ":services")
// Uncomment to include the compound-android module as a local dependency so you can work on it locally.
// You will also need to clone it in the specified folder.
//includeBuild("checkouts/compound-android") {
// includeBuild("checkouts/compound-android") {
// dependencySubstitution {
// // substitute remote dependency with local module
// substitute(module("io.element.android:compound-android")).using(project(":compound"))
// }
//}
// }

3
tools/localazy/config.json

@ -115,7 +115,8 @@ @@ -115,7 +115,8 @@
"screen_room_member_list_.*",
"screen_dm_details_.*",
"screen_room_notification_settings_.*",
"screen_notification_settings_edit_failed_updating_default_mode"
"screen_notification_settings_edit_failed_updating_default_mode",
"screen_start_chat_error_starting_chat"
]
},
{

Loading…
Cancel
Save