mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 03:06:14 +00:00
Stop waiting for a room alias that the remote server never resolves (#7446)
Tapping a room alias whose server is down left the resolver screen on a spinner for as long as the screen stayed open, with no way forward other than going back. Bound the resolution with the ten second timeout already used when joining a room by address, so the retry dialog is shown instead. The fake client's resolve lambda becomes suspending so a server that never answers can be simulated.
This commit is contained in:
+9
-1
@@ -24,7 +24,10 @@ import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import java.util.concurrent.TimeoutException
|
||||
import kotlin.jvm.optionals.getOrElse
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@AssistedInject
|
||||
class RoomAliasResolverPresenter(
|
||||
@@ -61,9 +64,14 @@ class RoomAliasResolverPresenter(
|
||||
|
||||
private fun CoroutineScope.resolveAlias(resolveState: MutableState<AsyncData<ResolvedRoomAlias>>) = launch {
|
||||
suspend {
|
||||
matrixClient.resolveRoomAlias(roomAlias)
|
||||
val result = withTimeoutOrNull(ALIAS_RESOLVE_TIMEOUT_IN_SECONDS.seconds) {
|
||||
matrixClient.resolveRoomAlias(roomAlias)
|
||||
} ?: throw TimeoutException("Timed out while resolving ${roomAlias.value}")
|
||||
result
|
||||
.getOrThrow()
|
||||
.getOrElse { throw RoomAliasResolverFailures.UnknownAlias }
|
||||
}.runCatchingUpdatingState(resolveState)
|
||||
}
|
||||
}
|
||||
|
||||
private const val ALIAS_RESOLVE_TIMEOUT_IN_SECONDS = 10
|
||||
|
||||
+18
@@ -22,10 +22,12 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_SERVER_LIST
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
class RoomAliasHelperPresenterTest {
|
||||
@get:Rule
|
||||
@@ -60,6 +62,22 @@ class RoomAliasHelperPresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - a server that never answers ends up in an error state`() = runTest {
|
||||
val client = FakeMatrixClient(
|
||||
resolveRoomAliasResult = { awaitCancellation() }
|
||||
)
|
||||
val presenter = createPresenter(matrixClient = client)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
assertThat(awaitItem().resolveState.isUninitialized()).isTrue()
|
||||
assertThat(awaitItem().resolveState.isLoading()).isTrue()
|
||||
val resultState = awaitItem()
|
||||
assertThat(resultState.resolveState.errorOrNull()).isInstanceOf(TimeoutException::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - resolve alias error and retry`() = runTest {
|
||||
val client = FakeMatrixClient(
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ class FakeMatrixClient(
|
||||
override val roomMembershipObserver: RoomMembershipObserver = RoomMembershipObserver(),
|
||||
private val homeserverCapabilitiesProvider: FakeHomeserverCapabilitiesProvider = FakeHomeserverCapabilitiesProvider(),
|
||||
private val accountManagementUrlResult: (AccountManagementAction?) -> Result<String?> = { lambdaError() },
|
||||
private val resolveRoomAliasResult: (RoomAlias) -> Result<Optional<ResolvedRoomAlias>> = {
|
||||
private val resolveRoomAliasResult: suspend (RoomAlias) -> Result<Optional<ResolvedRoomAlias>> = {
|
||||
Result.success(
|
||||
Optional.of(ResolvedRoomAlias(A_ROOM_ID, emptyList()))
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user