diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt index 5033274998..3eeaae1b2d 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt @@ -7,10 +7,11 @@ package io.element.android.libraries.push.impl.troubleshoot -import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesIntoSet 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.troubleshoot.api.test.NotificationTroubleshootTest 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.flow.StateFlow -@ContributesIntoSet(AppScope::class) +@ContributesIntoSet(SessionScope::class) @Inject class CurrentPushProviderTest( - private val getCurrentPushProvider: GetCurrentPushProvider, + private val pushService: PushService, + private val sessionId: SessionId, private val stringProvider: StringProvider, ) : NotificationTroubleshootTest { override val order = 110 @@ -35,17 +37,55 @@ class CurrentPushProviderTest( override suspend fun run(coroutineScope: CoroutineScope) { delegate.start() - val provider = getCurrentPushProvider.getCurrentPushProvider() - if (provider != null) { - delegate.updateState( - description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_success, provider), - status = NotificationTroubleshootTestState.Status.Success - ) - } else { + val pushProvider = pushService.getCurrentPushProvider() + if (pushProvider == null) { delegate.updateState( description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_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 + ) + } + } } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt index 95bfced7de..a11c6b147e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTestTest.kt @@ -8,7 +8,10 @@ package io.element.android.libraries.push.impl.troubleshoot 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.test.runAndTestState import io.element.android.services.toolbox.test.strings.FakeStringProvider @@ -17,10 +20,18 @@ import org.junit.Test class CurrentPushProviderTestTest { @Test - fun `test CurrentPushProviderTest with a push provider`() = runTest { + fun `test CurrentPushProviderTest with a push provider and a distributor`() = runTest { val sut = CurrentPushProviderTest( - getCurrentPushProvider = FakeGetCurrentPushProvider("foo"), + pushService = FakePushService( + currentPushProvider = { + FakePushProvider( + name = "foo", + currentDistributorValue = { "aDistributor" }, + ) + } + ), stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, ) sut.runAndTestState { 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 fun `test CurrentPushProviderTest without push provider`() = runTest { val sut = CurrentPushProviderTest( - getCurrentPushProvider = FakeGetCurrentPushProvider(null), + pushService = FakePushService( + currentPushProvider = { null }, + ), stringProvider = FakeStringProvider(), + sessionId = A_SESSION_ID, ) sut.runAndTestState { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt index bb6943d439..38a7135b75 100644 --- a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt @@ -24,6 +24,11 @@ interface PushProvider { */ val name: String + /** + * true if the Push provider supports multiple distributors. + */ + val supportMultipleDistributors: Boolean + /** * Return the list of available distributors. */ @@ -34,6 +39,11 @@ interface PushProvider { */ suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor): Result + /** + * Return the current distributor, or null if none. + */ + suspend fun getCurrentDistributorValue(sessionId: SessionId): String? + /** * Return the current distributor, or null if none. */ diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt index 806eb98bf5..4f8c99cd3e 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt @@ -32,6 +32,7 @@ class FirebasePushProvider( ) : PushProvider { override val index = FirebaseConfig.INDEX override val name = FirebaseConfig.NAME + override val supportMultipleDistributors = false override fun getDistributors(): List { 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 unregister(matrixClient: MatrixClient): Result { diff --git a/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt b/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt index 86792457ce..afb4d833d4 100644 --- a/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt +++ b/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/FakePushProvider.kt @@ -17,7 +17,9 @@ import io.element.android.tests.testutils.lambda.lambdaError class FakePushProvider( override val index: Int = 0, override val name: String = "aFakePushProvider", + override val supportMultipleDistributors: Boolean = false, private val distributors: List = listOf(Distributor("aDistributorValue", "aDistributorName")), + private val currentDistributorValue: () -> String? = { lambdaError() }, private val currentDistributor: () -> Distributor? = { distributors.firstOrNull() }, private val currentUserPushConfig: CurrentUserPushConfig? = null, private val registerWithResult: (MatrixClient, Distributor) -> Result = { _, _ -> lambdaError() }, @@ -32,6 +34,10 @@ class FakePushProvider( return registerWithResult(matrixClient, distributor) } + override suspend fun getCurrentDistributorValue(sessionId: SessionId): String? { + return currentDistributorValue() + } + override suspend fun getCurrentDistributor(sessionId: SessionId): Distributor? { return currentDistributor() } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt index 03b754e26f..92d7c9ebc3 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt @@ -29,6 +29,7 @@ class UnifiedPushProvider( ) : PushProvider { override val index = UnifiedPushConfig.INDEX override val name = UnifiedPushConfig.NAME + override val supportMultipleDistributors = true override fun getDistributors(): List { 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? { val distributorValue = unifiedPushStore.getDistributorValue(sessionId) return getDistributors().find { it.value == distributorValue }