From 797c912ccdee7f91ffab0ffea98cd199516ae6f7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Apr 2024 17:51:08 +0200 Subject: [PATCH] Implement Knock action (until the SDK level) --- .../features/joinroom/impl/JoinRoomEvents.kt | 2 ++ .../features/joinroom/impl/JoinRoomNode.kt | 1 + .../joinroom/impl/JoinRoomPresenter.kt | 24 +++++++++++++ .../features/joinroom/impl/JoinRoomState.kt | 2 ++ .../joinroom/impl/JoinRoomStateProvider.kt | 3 ++ .../features/joinroom/impl/JoinRoomView.kt | 17 +++++++-- .../joinroom/impl/di/JoinRoomModule.kt | 2 ++ .../features/joinroom/impl/di/KnockRoom.kt | 32 +++++++++++++++++ .../features/joinroom/impl/FakeKnockRoom.kt | 26 ++++++++++++++ .../joinroom/impl/JoinRoomPresenterTest.kt | 36 +++++++++++++++++++ .../joinroom/impl/JoinRoomViewTest.kt | 21 +++++++++-- .../libraries/matrix/api/MatrixClient.kt | 1 + .../libraries/matrix/impl/RustMatrixClient.kt | 4 +++ .../libraries/matrix/test/FakeMatrixClient.kt | 6 +++- 14 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/KnockRoom.kt create mode 100644 features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/FakeKnockRoom.kt diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt index 7163fc2bad..312efd1ad2 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt @@ -19,6 +19,8 @@ package io.element.android.features.joinroom.impl sealed interface JoinRoomEvents { data object RetryFetchingContent : JoinRoomEvents data object JoinRoom : JoinRoomEvents + data object KnockRoom : JoinRoomEvents + data object ClearError : JoinRoomEvents data object AcceptInvite : JoinRoomEvents data object DeclineInvite : JoinRoomEvents } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt index d83a5f4b20..5d302abc8b 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt @@ -49,6 +49,7 @@ class JoinRoomNode @AssistedInject constructor( JoinRoomView( state = state, onBackPressed = ::navigateUp, + onKnockSuccess = ::navigateUp, modifier = modifier ) acceptDeclineInviteView.Render( diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt index fbf4aeab31..ce3f0274d6 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt @@ -18,19 +18,25 @@ package io.element.android.features.joinroom.impl import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents import io.element.android.features.invite.api.response.AcceptDeclineInviteState import io.element.android.features.invite.api.response.InviteData +import io.element.android.features.joinroom.impl.di.KnockRoom import io.element.android.features.roomdirectory.api.RoomDescription +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.architecture.runUpdatingState 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.RoomIdOrAlias @@ -39,6 +45,8 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.preview.RoomPreview import io.element.android.libraries.matrix.ui.model.toInviteSender +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import java.util.Optional class JoinRoomPresenter @AssistedInject constructor( @@ -46,6 +54,7 @@ class JoinRoomPresenter @AssistedInject constructor( @Assisted private val roomIdOrAlias: RoomIdOrAlias, @Assisted private val roomDescription: Optional, private val matrixClient: MatrixClient, + private val knockRoom: KnockRoom, private val acceptDeclineInvitePresenter: Presenter, ) : Presenter { interface Factory { @@ -58,8 +67,10 @@ class JoinRoomPresenter @AssistedInject constructor( @Composable override fun present(): JoinRoomState { + val coroutineScope = rememberCoroutineScope() var retryCount by remember { mutableIntStateOf(0) } val roomInfo by matrixClient.getRoomInfoFlow(roomId).collectAsState(initial = Optional.empty()) + val knockAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val contentState by produceState( initialValue = ContentState.Loading(roomIdOrAlias), key1 = roomInfo, @@ -101,6 +112,9 @@ class JoinRoomPresenter @AssistedInject constructor( AcceptDeclineInviteEvents.AcceptInvite(inviteData) ) } + JoinRoomEvents.KnockRoom -> { + coroutineScope.knockRoom(roomId, knockAction) + } JoinRoomEvents.DeclineInvite -> { val inviteData = contentState.toInviteData() ?: return acceptDeclineInviteState.eventSink( @@ -110,15 +124,25 @@ class JoinRoomPresenter @AssistedInject constructor( JoinRoomEvents.RetryFetchingContent -> { retryCount++ } + JoinRoomEvents.ClearError -> { + knockAction.value = AsyncAction.Uninitialized + } } } return JoinRoomState( contentState = contentState, acceptDeclineInviteState = acceptDeclineInviteState, + knockAction = knockAction.value, eventSink = ::handleEvents ) } + + private fun CoroutineScope.knockRoom(roomId: RoomId, knockAction: MutableState>) = launch { + knockAction.runUpdatingState { + knockRoom(roomId) + } + } } private fun RoomPreview.toContentState(): ContentState { diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt index 14f0cf2012..b32a63cc59 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt @@ -18,6 +18,7 @@ package io.element.android.features.joinroom.impl import androidx.compose.runtime.Immutable import io.element.android.features.invite.api.response.AcceptDeclineInviteState +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.core.RoomAlias @@ -29,6 +30,7 @@ import io.element.android.libraries.matrix.ui.model.InviteSender data class JoinRoomState( val contentState: ContentState, val acceptDeclineInviteState: AcceptDeclineInviteState, + val knockAction: AsyncAction, val eventSink: (JoinRoomEvents) -> Unit ) { val joinAuthorisationStatus = when (contentState) { diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt index 9afd4dd797..e6f50a3676 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt @@ -19,6 +19,7 @@ package io.element.android.features.joinroom.impl import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.invite.api.response.AcceptDeclineInviteState import io.element.android.features.invite.api.response.anAcceptDeclineInviteState +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.core.RoomAlias @@ -105,10 +106,12 @@ fun aLoadedContentState( fun aJoinRoomState( contentState: ContentState = aLoadedContentState(), acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(), + knockAction: AsyncAction = AsyncAction.Uninitialized, eventSink: (JoinRoomEvents) -> Unit = {} ) = JoinRoomState( contentState = contentState, acceptDeclineInviteState = acceptDeclineInviteState, + knockAction = knockAction, eventSink = eventSink ) diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt index f9bc97231b..7deed58450 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt @@ -41,6 +41,7 @@ import io.element.android.libraries.designsystem.atomic.molecules.RoomPreviewMem import io.element.android.libraries.designsystem.atomic.organisms.RoomPreviewOrganism import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.background.LightGradientBackground +import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton @@ -60,6 +61,7 @@ import io.element.android.libraries.ui.strings.CommonStrings fun JoinRoomView( state: JoinRoomState, onBackPressed: () -> Unit, + onKnockSuccess: () -> Unit, modifier: Modifier = Modifier, ) { val gradientBackground = remember { LightGradientBackground() } @@ -85,12 +87,21 @@ fun JoinRoomView( onJoinRoom = { state.eventSink(JoinRoomEvents.JoinRoom) }, + onKnockRoom = { + state.eventSink(JoinRoomEvents.KnockRoom) + }, onRetry = { state.eventSink(JoinRoomEvents.RetryFetchingContent) } ) } ) + + AsyncActionView( + async = state.knockAction, + onSuccess = { onKnockSuccess() }, + onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearError) }, + ) } @Composable @@ -99,6 +110,7 @@ private fun JoinRoomFooter( onAcceptInvite: () -> Unit, onDeclineInvite: () -> Unit, onJoinRoom: () -> Unit, + onKnockRoom: () -> Unit, onRetry: () -> Unit, modifier: Modifier = Modifier, ) { @@ -142,7 +154,7 @@ private fun JoinRoomFooter( JoinAuthorisationStatus.CanKnock -> { Button( text = stringResource(R.string.screen_join_room_knock_action), - onClick = onJoinRoom, + onClick = onKnockRoom, modifier = modifier.fillMaxWidth(), size = ButtonSize.Large, ) @@ -263,6 +275,7 @@ private fun JoinRoomTopBar( internal fun JoinRoomViewPreview(@PreviewParameter(JoinRoomStateProvider::class) state: JoinRoomState) = ElementPreview { JoinRoomView( state = state, - onBackPressed = { } + onBackPressed = { }, + onKnockSuccess = { }, ) } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/JoinRoomModule.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/JoinRoomModule.kt index 3a9e0aec48..b2f9790088 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/JoinRoomModule.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/JoinRoomModule.kt @@ -35,6 +35,7 @@ object JoinRoomModule { @Provides fun providesJoinRoomPresenterFactory( client: MatrixClient, + knockRoom: KnockRoom, acceptDeclineInvitePresenter: Presenter, ): JoinRoomPresenter.Factory { return object : JoinRoomPresenter.Factory { @@ -48,6 +49,7 @@ object JoinRoomModule { roomIdOrAlias = roomIdOrAlias, roomDescription = roomDescription, matrixClient = client, + knockRoom = knockRoom, acceptDeclineInvitePresenter = acceptDeclineInvitePresenter, ) } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/KnockRoom.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/KnockRoom.kt new file mode 100644 index 0000000000..e7bfab591b --- /dev/null +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/KnockRoom.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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.joinroom.impl.di + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.RoomId +import javax.inject.Inject + +interface KnockRoom { + suspend operator fun invoke(roomId: RoomId): Result +} + +@ContributesBinding(SessionScope::class) +class DefaultKnockRoom @Inject constructor(private val client: MatrixClient) : KnockRoom { + override suspend fun invoke(roomId: RoomId) = client.knockRoom(roomId) +} diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/FakeKnockRoom.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/FakeKnockRoom.kt new file mode 100644 index 0000000000..d21369d2c3 --- /dev/null +++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/FakeKnockRoom.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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.joinroom.impl + +import io.element.android.features.joinroom.impl.di.KnockRoom +import io.element.android.libraries.matrix.api.core.RoomId + +class FakeKnockRoom( + var lambda: (RoomId) -> Result = { Result.success(Unit) } +) : KnockRoom { + override suspend fun invoke(roomId: RoomId) = lambda(roomId) +} diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt index fb36532e2d..2934f09211 100644 --- a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt +++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt @@ -20,7 +20,9 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents import io.element.android.features.invite.api.response.AcceptDeclineInviteState import io.element.android.features.invite.api.response.anAcceptDeclineInviteState +import io.element.android.features.joinroom.impl.di.KnockRoom import io.element.android.features.roomdirectory.api.RoomDescription +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomAlias @@ -269,6 +271,38 @@ class JoinRoomPresenterTest { } } + @Test + fun `present - emit knock room event`() = runTest { + val knockRoomSuccess = lambdaRecorder { _: RoomId -> + Result.success(Unit) + } + val knockRoomFailure = lambdaRecorder { roomId: RoomId -> + Result.failure(RuntimeException("Failed to knock room $roomId")) + } + val fakeKnockRoom = FakeKnockRoom(knockRoomSuccess) + val presenter = createJoinRoomPresenter(knockRoom = fakeKnockRoom) + presenter.test { + skipItems(1) + awaitItem().also { state -> + state.eventSink(JoinRoomEvents.KnockRoom) + } + awaitItem().also { state -> + assertThat(state.knockAction).isEqualTo(AsyncAction.Success(Unit)) + fakeKnockRoom.lambda = knockRoomFailure + state.eventSink(JoinRoomEvents.KnockRoom) + } + awaitItem().also { state -> + assertThat(state.knockAction).isInstanceOf(AsyncAction.Failure::class.java) + } + } + assert(knockRoomSuccess) + .isCalledOnce() + .with(value(A_ROOM_ID)) + assert(knockRoomFailure) + .isCalledOnce() + .with(value(A_ROOM_ID)) + } + @Test fun `present - when room is not known RoomPreview is loaded`() = runTest { val client = FakeMatrixClient( @@ -377,6 +411,7 @@ class JoinRoomPresenterTest { roomId: RoomId = A_ROOM_ID, roomDescription: Optional = Optional.empty(), matrixClient: MatrixClient = FakeMatrixClient(), + knockRoom: KnockRoom = FakeKnockRoom(), acceptDeclineInvitePresenter: Presenter = Presenter { anAcceptDeclineInviteState() } ): JoinRoomPresenter { return JoinRoomPresenter( @@ -384,6 +419,7 @@ class JoinRoomPresenterTest { roomIdOrAlias = roomId.toRoomIdOrAlias(), roomDescription = roomDescription, matrixClient = matrixClient, + knockRoom = knockRoom, acceptDeclineInvitePresenter = acceptDeclineInvitePresenter ) } diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt index 8f3bd5bdd5..bd8f46295d 100644 --- a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt +++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt @@ -20,6 +20,7 @@ import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EventsRecorder @@ -72,11 +73,25 @@ class JoinRoomViewTest { ), ) rule.clickOn(R.string.screen_join_room_knock_action) - eventsRecorder.assertSingle(JoinRoomEvents.JoinRoom) + eventsRecorder.assertSingle(JoinRoomEvents.KnockRoom) + } + + @Test + fun `clicking on closing Knock error emits the expected Event`() { + val eventsRecorder = EventsRecorder() + rule.setJoinRoomView( + aJoinRoomState( + contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock), + knockAction = AsyncAction.Failure(Exception("Error")), + eventSink = eventsRecorder, + ), + ) + rule.clickOn(CommonStrings.action_ok) + eventsRecorder.assertSingle(JoinRoomEvents.ClearError) } @Test - fun `clicking on Accept invitationon IsInvited room emits the expected Event`() { + fun `clicking on Accept invitation IsInvited room emits the expected Event`() { val eventsRecorder = EventsRecorder() rule.setJoinRoomView( aJoinRoomState( @@ -118,11 +133,13 @@ class JoinRoomViewTest { private fun AndroidComposeTestRule.setJoinRoomView( state: JoinRoomState, onBackPressed: () -> Unit = EnsureNeverCalled(), + onKnockSuccess: () -> Unit = EnsureNeverCalled(), ) { setContent { JoinRoomView( state = state, onBackPressed = onBackPressed, + onKnockSuccess = onKnockSuccess, ) } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 3e9c1a264f..fb20e16c9d 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -66,6 +66,7 @@ interface MatrixClient : Closeable { suspend fun uploadAvatar(mimeType: String, data: ByteArray): Result suspend fun removeAvatar(): Result suspend fun joinRoom(roomId: RoomId): Result + suspend fun knockRoom(roomId: RoomId): Result fun syncService(): SyncService fun sessionVerificationService(): SessionVerificationService fun pushersService(): PushersService diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index f5ec5d71ee..a24c4a35bb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -451,6 +451,10 @@ class RustMatrixClient( } } + override suspend fun knockRoom(roomId: RoomId): Result { + return Result.failure(NotImplementedError("Not yet implemented")) + } + override suspend fun trackRecentlyVisitedRoom(roomId: RoomId): Result = withContext(sessionDispatcher) { runCatching { client.trackRecentlyVisitedRoom(roomId.value) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 8578105f7d..015f764ff5 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -106,7 +106,9 @@ class FakeMatrixClient( var joinRoomLambda: (RoomId) -> Result = { Result.success(Unit) } - + var knockRoomLambda: (RoomId) -> Result = { + Result.success(Unit) + } var getRoomInfoFlowLambda = { _: RoomId -> flowOf>(Optional.empty()) } @@ -199,6 +201,8 @@ class FakeMatrixClient( override suspend fun joinRoom(roomId: RoomId): Result = joinRoomLambda(roomId) + override suspend fun knockRoom(roomId: RoomId): Result = knockRoomLambda(roomId) + override fun sessionVerificationService(): SessionVerificationService = sessionVerificationService override fun pushersService(): PushersService = pushersService