Improve current push provider test: give info about the distributor.

This commit is contained in:
Benoit Marty 2025-01-02 10:56:57 +01:00
parent 0659174735
commit 6fb194f3dd
6 changed files with 165 additions and 15 deletions

View file

@ -7,10 +7,11 @@
package io.element.android.libraries.push.impl.troubleshoot package io.element.android.libraries.push.impl.troubleshoot
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesIntoSet import dev.zacsweers.metro.ContributesIntoSet
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.libraries.push.api.GetCurrentPushProvider import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.push.api.PushService
import io.element.android.libraries.push.impl.R import io.element.android.libraries.push.impl.R
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTest import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTest
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestDelegate import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestDelegate
@ -19,10 +20,11 @@ import io.element.android.services.toolbox.api.strings.StringProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@ContributesIntoSet(AppScope::class) @ContributesIntoSet(SessionScope::class)
@Inject @Inject
class CurrentPushProviderTest( class CurrentPushProviderTest(
private val getCurrentPushProvider: GetCurrentPushProvider, private val pushService: PushService,
private val sessionId: SessionId,
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
) : NotificationTroubleshootTest { ) : NotificationTroubleshootTest {
override val order = 110 override val order = 110
@ -35,17 +37,55 @@ class CurrentPushProviderTest(
override suspend fun run(coroutineScope: CoroutineScope) { override suspend fun run(coroutineScope: CoroutineScope) {
delegate.start() delegate.start()
val provider = getCurrentPushProvider.getCurrentPushProvider() val pushProvider = pushService.getCurrentPushProvider()
if (provider != null) { if (pushProvider == null) {
delegate.updateState(
description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_success, provider),
status = NotificationTroubleshootTestState.Status.Success
)
} else {
delegate.updateState( delegate.updateState(
description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_failure), description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_failure),
status = NotificationTroubleshootTestState.Status.Failure() status = NotificationTroubleshootTestState.Status.Failure()
) )
} else if (pushProvider.supportMultipleDistributors.not()) {
delegate.updateState(
description = stringProvider.getString(
R.string.troubleshoot_notifications_test_current_push_provider_success,
pushProvider.name
),
status = NotificationTroubleshootTestState.Status.Success
)
} else {
val distributorValue = pushProvider.getCurrentDistributorValue(sessionId)
if (distributorValue == null) {
// No distributors configured
delegate.updateState(
description = stringProvider.getString(
R.string.troubleshoot_notifications_test_current_push_provider_failure_no_distributor,
pushProvider.name
),
status = NotificationTroubleshootTestState.Status.Failure(false)
)
} else {
val distributor = pushProvider.getDistributors().find { it.value == distributorValue }
if (distributor == null) {
// Distributor has been uninstalled?
delegate.updateState(
description = stringProvider.getString(
R.string.troubleshoot_notifications_test_current_push_provider_failure_distributor_not_found,
pushProvider.name,
distributorValue,
distributorValue,
),
status = NotificationTroubleshootTestState.Status.Failure(false)
)
} else {
delegate.updateState(
description = stringProvider.getString(
R.string.troubleshoot_notifications_test_current_push_provider_success_with_distributor,
pushProvider.name,
distributorValue,
),
status = NotificationTroubleshootTestState.Status.Success
)
}
}
} }
} }

View file

@ -8,7 +8,10 @@
package io.element.android.libraries.push.impl.troubleshoot package io.element.android.libraries.push.impl.troubleshoot
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.push.test.FakeGetCurrentPushProvider import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.push.test.FakePushService
import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.libraries.pushproviders.test.FakePushProvider
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState
import io.element.android.libraries.troubleshoot.test.runAndTestState import io.element.android.libraries.troubleshoot.test.runAndTestState
import io.element.android.services.toolbox.test.strings.FakeStringProvider import io.element.android.services.toolbox.test.strings.FakeStringProvider
@ -17,10 +20,18 @@ import org.junit.Test
class CurrentPushProviderTestTest { class CurrentPushProviderTestTest {
@Test @Test
fun `test CurrentPushProviderTest with a push provider`() = runTest { fun `test CurrentPushProviderTest with a push provider and a distributor`() = runTest {
val sut = CurrentPushProviderTest( val sut = CurrentPushProviderTest(
getCurrentPushProvider = FakeGetCurrentPushProvider("foo"), pushService = FakePushService(
currentPushProvider = {
FakePushProvider(
name = "foo",
currentDistributorValue = { "aDistributor" },
)
}
),
stringProvider = FakeStringProvider(), stringProvider = FakeStringProvider(),
sessionId = A_SESSION_ID,
) )
sut.runAndTestState { sut.runAndTestState {
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
@ -31,11 +42,86 @@ class CurrentPushProviderTestTest {
} }
} }
@Test
fun `test CurrentPushProviderTest with a push provider supporting multiple distributors, distributor found`() = runTest {
val sut = CurrentPushProviderTest(
pushService = FakePushService(
currentPushProvider = {
FakePushProvider(
name = "foo",
currentDistributorValue = { "aDistributor" },
supportMultipleDistributors = true,
distributors = listOf(Distributor("aDistributor", "aDistributor"))
)
},
),
stringProvider = FakeStringProvider(),
sessionId = A_SESSION_ID,
)
sut.runAndTestState {
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
val lastItem = awaitItem()
assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Success)
assertThat(lastItem.description).contains("foo")
}
}
@Test
fun `test CurrentPushProviderTest with a push provider supporting multiple distributors, no distributor`() = runTest {
val sut = CurrentPushProviderTest(
pushService = FakePushService(
currentPushProvider = {
FakePushProvider(
name = "foo",
currentDistributorValue = { null },
supportMultipleDistributors = true,
)
},
),
stringProvider = FakeStringProvider(),
sessionId = A_SESSION_ID,
)
sut.runAndTestState {
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
val lastItem = awaitItem()
assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure())
}
}
@Test
fun `test CurrentPushProviderTest with a push provider supporting multiple distributors, distributor not found`() = runTest {
val sut = CurrentPushProviderTest(
pushService = FakePushService(
currentPushProvider = {
FakePushProvider(
name = "foo",
currentDistributorValue = { "aDistributor" },
supportMultipleDistributors = true,
distributors = emptyList()
)
},
),
stringProvider = FakeStringProvider(),
sessionId = A_SESSION_ID,
)
sut.runAndTestState {
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
val lastItem = awaitItem()
assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure())
}
}
@Test @Test
fun `test CurrentPushProviderTest without push provider`() = runTest { fun `test CurrentPushProviderTest without push provider`() = runTest {
val sut = CurrentPushProviderTest( val sut = CurrentPushProviderTest(
getCurrentPushProvider = FakeGetCurrentPushProvider(null), pushService = FakePushService(
currentPushProvider = { null },
),
stringProvider = FakeStringProvider(), stringProvider = FakeStringProvider(),
sessionId = A_SESSION_ID,
) )
sut.runAndTestState { sut.runAndTestState {
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))

View file

@ -24,6 +24,11 @@ interface PushProvider {
*/ */
val name: String val name: String
/**
* true if the Push provider supports multiple distributors.
*/
val supportMultipleDistributors: Boolean
/** /**
* Return the list of available distributors. * Return the list of available distributors.
*/ */
@ -34,6 +39,11 @@ interface PushProvider {
*/ */
suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor): Result<Unit> suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor): Result<Unit>
/**
* Return the current distributor, or null if none.
*/
suspend fun getCurrentDistributorValue(sessionId: SessionId): String?
/** /**
* Return the current distributor, or null if none. * Return the current distributor, or null if none.
*/ */

View file

@ -32,6 +32,7 @@ class FirebasePushProvider(
) : PushProvider { ) : PushProvider {
override val index = FirebaseConfig.INDEX override val index = FirebaseConfig.INDEX
override val name = FirebaseConfig.NAME override val name = FirebaseConfig.NAME
override val supportMultipleDistributors = false
override fun getDistributors(): List<Distributor> { override fun getDistributors(): List<Distributor> {
return listOfNotNull( return listOfNotNull(
@ -54,6 +55,8 @@ class FirebasePushProvider(
) )
} }
override suspend fun getCurrentDistributorValue(sessionId: SessionId): String = firebaseDistributor.value
override suspend fun getCurrentDistributor(sessionId: SessionId) = firebaseDistributor override suspend fun getCurrentDistributor(sessionId: SessionId) = firebaseDistributor
override suspend fun unregister(matrixClient: MatrixClient): Result<Unit> { override suspend fun unregister(matrixClient: MatrixClient): Result<Unit> {

View file

@ -17,7 +17,9 @@ import io.element.android.tests.testutils.lambda.lambdaError
class FakePushProvider( class FakePushProvider(
override val index: Int = 0, override val index: Int = 0,
override val name: String = "aFakePushProvider", override val name: String = "aFakePushProvider",
override val supportMultipleDistributors: Boolean = false,
private val distributors: List<Distributor> = listOf(Distributor("aDistributorValue", "aDistributorName")), private val distributors: List<Distributor> = listOf(Distributor("aDistributorValue", "aDistributorName")),
private val currentDistributorValue: () -> String? = { lambdaError() },
private val currentDistributor: () -> Distributor? = { distributors.firstOrNull() }, private val currentDistributor: () -> Distributor? = { distributors.firstOrNull() },
private val currentUserPushConfig: CurrentUserPushConfig? = null, private val currentUserPushConfig: CurrentUserPushConfig? = null,
private val registerWithResult: (MatrixClient, Distributor) -> Result<Unit> = { _, _ -> lambdaError() }, private val registerWithResult: (MatrixClient, Distributor) -> Result<Unit> = { _, _ -> lambdaError() },
@ -32,6 +34,10 @@ class FakePushProvider(
return registerWithResult(matrixClient, distributor) return registerWithResult(matrixClient, distributor)
} }
override suspend fun getCurrentDistributorValue(sessionId: SessionId): String? {
return currentDistributorValue()
}
override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? { override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? {
return currentDistributor() return currentDistributor()
} }

View file

@ -29,6 +29,7 @@ class UnifiedPushProvider(
) : PushProvider { ) : PushProvider {
override val index = UnifiedPushConfig.INDEX override val index = UnifiedPushConfig.INDEX
override val name = UnifiedPushConfig.NAME override val name = UnifiedPushConfig.NAME
override val supportMultipleDistributors = true
override fun getDistributors(): List<Distributor> { override fun getDistributors(): List<Distributor> {
return unifiedPushDistributorProvider.getDistributors() return unifiedPushDistributorProvider.getDistributors()
@ -42,6 +43,10 @@ class UnifiedPushProvider(
} }
} }
override suspend fun getCurrentDistributorValue(sessionId: SessionId): String? {
return unifiedPushStore.getDistributorValue(sessionId)
}
override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? { override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? {
val distributorValue = unifiedPushStore.getDistributorValue(sessionId) val distributorValue = unifiedPushStore.getDistributorValue(sessionId)
return getDistributors().find { it.value == distributorValue } return getDistributors().find { it.value == distributorValue }