From 452e5681a98b4e6833b563c97cd9132e957307c2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 11 Jun 2024 16:50:53 +0200 Subject: [PATCH] Sending queue : rename fake and add tests --- .../android/appnav/LoggedInFlowNode.kt | 2 +- .../android/appnav/loggedin/SendingQueue.kt | 12 ++- .../appnav/loggedin/SendingQueueTest.kt | 81 +++++++++++++++++++ .../libraries/matrix/test/FakeMatrixClient.kt | 4 +- 4 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendingQueueTest.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 2f8dda9e8c..911ec52d7c 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -160,7 +160,7 @@ class LoggedInFlowNode @AssistedInject constructor( } private fun setupSendingQueue() { - sendingQueue.setupWith(lifecycleScope) + sendingQueue.launchIn(lifecycleScope) } @OptIn(FlowPreview::class) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendingQueue.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendingQueue.kt index b761f013ba..2bee213e4b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendingQueue.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendingQueue.kt @@ -16,6 +16,7 @@ package io.element.android.appnav.loggedin +import androidx.annotation.VisibleForTesting import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.libraries.di.SessionScope @@ -30,8 +31,10 @@ import timber.log.Timber import java.util.concurrent.atomic.AtomicInteger import javax.inject.Inject -private const val MIN_RETRY_DELAY = 250L -private const val MAX_RETRY_DELAY = 5000L +private const val SENDING_QUEUE_MIN_RETRY_DELAY = 250L + +@VisibleForTesting +const val SENDING_QUEUE_MAX_RETRY_DELAY = 5000L @SingleIn(SessionScope::class) class SendingQueue @Inject constructor( @@ -41,7 +44,7 @@ class SendingQueue @Inject constructor( private val retryCount = AtomicInteger(0) - fun setupWith(coroutineScope: CoroutineScope) { + fun launchIn(coroutineScope: CoroutineScope) { combine( networkMonitor.connectivity, matrixClient.sendingQueueStatus(), @@ -50,7 +53,8 @@ class SendingQueue @Inject constructor( }.onEach { (networkStatus, isSendingQueueEnabled) -> Timber.d("Network status: $networkStatus, isSendingQueueEnabled: $isSendingQueueEnabled") if (networkStatus == NetworkStatus.Online && !isSendingQueueEnabled) { - val retryDelay = (MIN_RETRY_DELAY * retryCount.incrementAndGet()).coerceIn(MIN_RETRY_DELAY, MAX_RETRY_DELAY) + val retryDelay = + (SENDING_QUEUE_MIN_RETRY_DELAY * retryCount.incrementAndGet()).coerceIn(SENDING_QUEUE_MIN_RETRY_DELAY, SENDING_QUEUE_MAX_RETRY_DELAY) Timber.d("Retry enabling sending queue in $retryDelay ms") delay(retryDelay) } else { diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendingQueueTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendingQueueTest.kt new file mode 100644 index 0000000000..937370e75f --- /dev/null +++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendingQueueTest.kt @@ -0,0 +1,81 @@ +/* + * 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.appnav.loggedin + +import io.element.android.features.networkmonitor.api.NetworkStatus +import io.element.android.features.networkmonitor.test.FakeNetworkMonitor +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) class SendingQueueTest { + + private val matrixClient = FakeMatrixClient() + private val networkMonitor = FakeNetworkMonitor() + private val sut = SendingQueue(matrixClient, networkMonitor) + + @Test + fun `test network status online and sending queue is disabled`() = runTest { + val sendingQueueStatusFlow = MutableStateFlow(false) + val setEnableSendingQueueLambda = lambdaRecorder { _: Boolean -> } + matrixClient.sendingQueueStatusFlow = sendingQueueStatusFlow + matrixClient.setSendingQueueEnabledLambda = setEnableSendingQueueLambda + + sut.launchIn(backgroundScope) + + advanceTimeBy(SENDING_QUEUE_MAX_RETRY_DELAY) + sendingQueueStatusFlow.value = true + advanceTimeBy(SENDING_QUEUE_MAX_RETRY_DELAY) + + assert(setEnableSendingQueueLambda) + .isCalledExactly(2) + .withSequence( + listOf(value(true)), + listOf(value(true)) + ) + } + + @Test + fun `test network status getting offline and online`() = runTest { + val sendingQueueStatusFlow = MutableStateFlow(true) + val setEnableSendingQueueLambda = lambdaRecorder { _: Boolean -> } + matrixClient.sendingQueueStatusFlow = sendingQueueStatusFlow + matrixClient.setSendingQueueEnabledLambda = setEnableSendingQueueLambda + + sut.launchIn(backgroundScope) + advanceTimeBy(SENDING_QUEUE_MAX_RETRY_DELAY) + networkMonitor.connectivity.value = NetworkStatus.Offline + advanceTimeBy(SENDING_QUEUE_MAX_RETRY_DELAY) + networkMonitor.connectivity.value = NetworkStatus.Online + advanceTimeBy(SENDING_QUEUE_MAX_RETRY_DELAY) + + assert(setEnableSendingQueueLambda) + .isCalledExactly(3) + .withSequence( + listOf(value(true)), + listOf(value(false)), + listOf(value(true)), + ) + } + +} 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 43bc91d886..0f7fae3a91 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 @@ -300,11 +300,11 @@ class FakeMatrixClient( override fun getRoomInfoFlow(roomId: RoomId) = getRoomInfoFlowLambda(roomId) - var enableSendingQueueLambda = lambdaRecorder(ensureNeverCalled = true) { enable: Boolean -> + var setSendingQueueEnabledLambda = lambdaRecorder(ensureNeverCalled = true) { _: Boolean -> // no-op } - override suspend fun setSendingQueueEnabled(enable: Boolean) = enableSendingQueueLambda(enable) + override suspend fun setSendingQueueEnabled(enabled: Boolean) = setSendingQueueEnabledLambda(enabled) var sendingQueueStatusFlow = MutableStateFlow(true) override fun sendingQueueStatus(): StateFlow = sendingQueueStatusFlow