From 0423c36e08a0809758ededf0ffcccaeac9d3a5d5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 10:48:18 +0200 Subject: [PATCH 1/8] Always use the custom url, even if no Matrix gateway is detected. --- .../push/impl/DefaultPushServiceTest.kt | 6 +- .../push/impl/test/DefaultTestPushTest.kt | 7 +- .../libraries/pushproviders/test/Fixtures.kt | 27 ++++ .../unifiedpush/build.gradle.kts | 1 + .../unifiedpush/UnifiedPushConfig.kt | 4 +- .../unifiedpush/UnifiedPushGatewayResolver.kt | 22 +-- .../unifiedpush/network/UnifiedPushApi.kt | 3 +- .../UnifiedPushMatrixGatewayTest.kt | 90 +++++++++++++ .../DefaultUnifiedPushGatewayResolverTest.kt | 32 ++--- .../UnifiedPushMatrixGatewayTestTest.kt | 126 ++++++++++++++++++ 10 files changed, 282 insertions(+), 36 deletions(-) create mode 100644 libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/Fixtures.kt create mode 100644 libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt create mode 100644 libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt index f253030a74..aee24c8a1b 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt @@ -29,6 +29,7 @@ import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider import io.element.android.libraries.pushproviders.test.FakePushProvider +import io.element.android.libraries.pushproviders.test.aCurrentUserPushConfig import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.test.userpushstore.FakeUserPushStore import io.element.android.libraries.pushstore.test.userpushstore.FakeUserPushStoreFactory @@ -57,10 +58,7 @@ class DefaultPushServiceTest { @Test fun `test push ok`() = runTest { - val aConfig = CurrentUserPushConfig( - url = "aUrl", - pushKey = "aPushKey", - ) + val aConfig = aCurrentUserPushConfig() val testPushResult = lambdaRecorder { } val aPushProvider = FakePushProvider( currentUserPushConfig = aConfig diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/test/DefaultTestPushTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/test/DefaultTestPushTest.kt index 0ccd08df82..012c9c043e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/test/DefaultTestPushTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/test/DefaultTestPushTest.kt @@ -18,7 +18,7 @@ package io.element.android.libraries.push.impl.test import io.element.android.appconfig.PushConfig import io.element.android.libraries.push.impl.pushgateway.PushGatewayNotifyRequest -import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig +import io.element.android.libraries.pushproviders.test.aCurrentUserPushConfig import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.test.runTest @@ -33,10 +33,7 @@ class DefaultTestPushTest { executeResult = executeResult, ) ) - val aConfig = CurrentUserPushConfig( - url = "aUrl", - pushKey = "aPushKey", - ) + val aConfig = aCurrentUserPushConfig() defaultTestPush.execute(aConfig) executeResult.assertions() .isCalledOnce() diff --git a/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/Fixtures.kt b/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/Fixtures.kt new file mode 100644 index 0000000000..a5fd319dcb --- /dev/null +++ b/libraries/pushproviders/test/src/main/kotlin/io/element/android/libraries/pushproviders/test/Fixtures.kt @@ -0,0 +1,27 @@ +/* + * 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 + * + * https://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.libraries.pushproviders.test + +import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig + +fun aCurrentUserPushConfig( + url: String = "aUrl", + pushKey: String = "aPushKey", +) = CurrentUserPushConfig( + url = url, + pushKey = pushKey, +) diff --git a/libraries/pushproviders/unifiedpush/build.gradle.kts b/libraries/pushproviders/unifiedpush/build.gradle.kts index d1c8cf5ee1..3651230721 100644 --- a/libraries/pushproviders/unifiedpush/build.gradle.kts +++ b/libraries/pushproviders/unifiedpush/build.gradle.kts @@ -60,6 +60,7 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.push.test) + testImplementation(projects.libraries.pushproviders.test) testImplementation(projects.libraries.pushstore.test) testImplementation(projects.tests.testutils) testImplementation(projects.services.toolbox.test) diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt index b1d321f42f..82db2d6021 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt @@ -17,11 +17,13 @@ package io.element.android.libraries.pushproviders.unifiedpush object UnifiedPushConfig { + const val PUSH_GATEWAY_PATH: String = "_matrix/push/v1/notify" + /** * It is the push gateway for UnifiedPush. * Note: default_push_gateway_http_url should have path '/_matrix/push/v1/notify' */ - const val DEFAULT_PUSH_GATEWAY_HTTP_URL: String = "https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify" + const val DEFAULT_PUSH_GATEWAY_HTTP_URL: String = "https://matrix.gateway.unifiedpush.org/$PUSH_GATEWAY_PATH" const val UNIFIED_PUSH_DISTRIBUTORS_URL = "https://unifiedpush.org/users/distributors/" diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt index c39c7ec066..9da92e7315 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt @@ -18,6 +18,7 @@ package io.element.android.libraries.pushproviders.unifiedpush import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.di.AppScope import kotlinx.coroutines.withContext import timber.log.Timber @@ -34,12 +35,18 @@ class DefaultUnifiedPushGatewayResolver @Inject constructor( private val coroutineDispatchers: CoroutineDispatchers, ) : UnifiedPushGatewayResolver { override suspend fun getGateway(endpoint: String): String { - val gateway = UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL - try { - val url = URL(endpoint) + val url = tryOrNull( + onError = { Timber.d(it, "Cannot parse endpoint as an URL") } + ) { + URL(endpoint) + } + return if (url == null) { + Timber.d("Using default gateway") + UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL + } else { val port = if (url.port != -1) ":${url.port}" else "" val customBase = "${url.protocol}://${url.host}$port" - val customUrl = "$customBase/_matrix/push/v1/notify" + val customUrl = "$customBase/${UnifiedPushConfig.PUSH_GATEWAY_PATH}" Timber.i("Testing $customUrl") return withContext(coroutineDispatchers.io) { val api = unifiedPushApiFactory.create(customBase) @@ -47,16 +54,13 @@ class DefaultUnifiedPushGatewayResolver @Inject constructor( val discoveryResponse = api.discover() if (discoveryResponse.unifiedpush.gateway == "matrix") { Timber.d("Using custom gateway") - return@withContext customUrl } } catch (throwable: Throwable) { Timber.tag("UnifiedPushHelper").e(throwable) } - return@withContext gateway + // Always return the custom url. + customUrl } - } catch (e: Throwable) { - Timber.d(e, "Cannot try custom gateway") } - return gateway } } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt index cd6cd7440e..6f9ff5679d 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt @@ -16,9 +16,10 @@ package io.element.android.libraries.pushproviders.unifiedpush.network +import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushConfig import retrofit2.http.GET interface UnifiedPushApi { - @GET("_matrix/push/v1/notify") + @GET(UnifiedPushConfig.PUSH_GATEWAY_PATH) suspend fun discover(): DiscoveryResponse } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt new file mode 100644 index 0000000000..f11ae99965 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt @@ -0,0 +1,90 @@ +/* + * 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.libraries.pushproviders.unifiedpush.troubleshoot + +import com.squareup.anvil.annotations.ContributesMultibinding +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.pushproviders.api.PushProvider +import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushApiFactory +import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushConfig +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.NotificationTroubleshootTestState +import io.element.android.libraries.troubleshoot.api.test.TestFilterData +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@ContributesMultibinding(AppScope::class) +class UnifiedPushMatrixGatewayTest @Inject constructor( + private val unifiedPushApiFactory: UnifiedPushApiFactory, + private val coroutineDispatchers: CoroutineDispatchers, + private val pushProvider: PushProvider, +) : NotificationTroubleshootTest { + override val order = 450 + private val delegate = NotificationTroubleshootTestDelegate( + defaultName = "Test push gateway", + defaultDescription = "Ensure that the push gateway is valid.", + visibleWhenIdle = false, + fakeDelay = NotificationTroubleshootTestDelegate.SHORT_DELAY, + ) + override val state: StateFlow = delegate.state + + override fun isRelevant(data: TestFilterData): Boolean { + return data.currentPushProviderName == UnifiedPushConfig.NAME + } + + override suspend fun run(coroutineScope: CoroutineScope) { + delegate.start() + val config = pushProvider.getCurrentUserPushConfig() + if (config == null) { + delegate.updateState( + description = "No current push provider", + status = NotificationTroubleshootTestState.Status.Failure(false) + ) + } else { + val gatewayBaseUrl = config.url.removeSuffix("/${UnifiedPushConfig.PUSH_GATEWAY_PATH}") + // Checking if the gateway is a Matrix gateway + coroutineScope.launch(coroutineDispatchers.io) { + val api = unifiedPushApiFactory.create(gatewayBaseUrl) + try { + val discoveryResponse = api.discover() + if (discoveryResponse.unifiedpush.gateway == "matrix") { + delegate.updateState( + description = "${config.url} is a Matrix gateway.", + status = NotificationTroubleshootTestState.Status.Success + ) + } else { + delegate.updateState( + description = "${config.url} is not a Matrix gateway.", + status = NotificationTroubleshootTestState.Status.Failure(false) + ) + } + } catch (throwable: Throwable) { + delegate.updateState( + description = "Fail to check the gateway ${config.url}: ${throwable.localizedMessage}", + status = NotificationTroubleshootTestState.Status.Failure(false) + ) + } + } + } + } + + override suspend fun reset() = delegate.reset() +} diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt index e180e36c38..cee74bfa31 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt @@ -25,23 +25,23 @@ import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test +internal val matrixDiscoveryResponse = { + DiscoveryResponse( + unifiedpush = DiscoveryUnifiedPush( + gateway = "matrix" + ) + ) +} + +internal val invalidDiscoveryResponse = { + DiscoveryResponse( + unifiedpush = DiscoveryUnifiedPush( + gateway = "" + ) + ) +} + class DefaultUnifiedPushGatewayResolverTest { - private val matrixDiscoveryResponse = { - DiscoveryResponse( - unifiedpush = DiscoveryUnifiedPush( - gateway = "matrix" - ) - ) - } - - private val invalidDiscoveryResponse = { - DiscoveryResponse( - unifiedpush = DiscoveryUnifiedPush( - gateway = "" - ) - ) - } - @Test fun `when a custom url provide a correct matrix gateway, the custom url is returned`() = runTest { val unifiedPushApiFactory = FakeUnifiedPushApiFactory( diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt new file mode 100644 index 0000000000..7b4d48070c --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt @@ -0,0 +1,126 @@ +/* + * 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.libraries.pushproviders.unifiedpush.troubleshoot + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig +import io.element.android.libraries.pushproviders.test.FakePushProvider +import io.element.android.libraries.pushproviders.test.aCurrentUserPushConfig +import io.element.android.libraries.pushproviders.unifiedpush.FakeUnifiedPushApiFactory +import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushConfig +import io.element.android.libraries.pushproviders.unifiedpush.invalidDiscoveryResponse +import io.element.android.libraries.pushproviders.unifiedpush.matrixDiscoveryResponse +import io.element.android.libraries.pushproviders.unifiedpush.network.DiscoveryResponse +import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState +import io.element.android.libraries.troubleshoot.api.test.TestFilterData +import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class UnifiedPushMatrixGatewayTestTest { + @Test + fun `test UnifiedPushMatrixGatewayTest success`() = runTest { + val sut = createUnifiedPushMatrixGatewayTest( + currentUserPushConfig = aCurrentUserPushConfig(), + discoveryResponse = matrixDiscoveryResponse, + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Success) + } + } + + @Test + fun `test UnifiedPushMatrixGatewayTest no config found`() = runTest { + val sut = createUnifiedPushMatrixGatewayTest( + currentUserPushConfig = null, + discoveryResponse = matrixDiscoveryResponse, + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + } + } + + @Test + fun `test UnifiedPushMatrixGatewayTest not valid gateway`() = runTest { + val sut = createUnifiedPushMatrixGatewayTest( + currentUserPushConfig = aCurrentUserPushConfig(), + discoveryResponse = invalidDiscoveryResponse, + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + // Reset the error + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + } + } + + @Test + fun `test UnifiedPushMatrixGatewayTest network error`() = runTest { + val sut = createUnifiedPushMatrixGatewayTest( + currentUserPushConfig = aCurrentUserPushConfig(), + discoveryResponse = { throw RuntimeException("Network error") }, + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + } + } + + @Test + fun `test isRelevant`() = runTest { + val sut = createUnifiedPushMatrixGatewayTest() + assertThat(sut.isRelevant(TestFilterData(currentPushProviderName = UnifiedPushConfig.NAME))).isTrue() + assertThat(sut.isRelevant(TestFilterData(currentPushProviderName = "other"))).isFalse() + } + + private fun TestScope.createUnifiedPushMatrixGatewayTest( + currentUserPushConfig: CurrentUserPushConfig? = null, + discoveryResponse: () -> DiscoveryResponse = matrixDiscoveryResponse, + ): UnifiedPushMatrixGatewayTest { + return UnifiedPushMatrixGatewayTest( + unifiedPushApiFactory = FakeUnifiedPushApiFactory(discoveryResponse), + coroutineDispatchers = testCoroutineDispatchers(), + pushProvider = FakePushProvider(currentUserPushConfig = currentUserPushConfig), + ) + } +} From 6eb5610bcc59f293c26d8a2f837798d8aa154b4f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 10:57:14 +0200 Subject: [PATCH 2/8] Add missing test on reset methods. --- ...ficationTroubleshootCheckPermissionTest.kt | 2 +- ...tionTroubleshootCheckPermissionTestTest.kt | 28 ++++++++++++++++++ .../CurrentPushProviderTestTest.kt | 2 ++ .../impl/troubleshoot/NotificationTestTest.kt | 2 ++ .../impl/troubleshoot/PushLoopbackTestTest.kt | 2 ++ .../troubleshoot/PushProvidersTestTest.kt | 2 ++ .../FirebaseAvailabilityTestTest.kt | 2 ++ .../troubleshoot/FirebaseTokenTestTest.kt | 25 ++++++++++++++++ .../troubleshoot/UnifiedPushTestTest.kt | 29 +++++++++++++++++++ 9 files changed, 93 insertions(+), 1 deletion(-) diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt index 7e916c37b5..ef710d1167 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt @@ -37,7 +37,7 @@ class NotificationTroubleshootCheckPermissionTest @Inject constructor( private val permissionStateProvider: PermissionStateProvider, private val sdkVersionProvider: BuildVersionSdkIntProvider, private val permissionActions: PermissionActions, - private val stringProvider: StringProvider, + stringProvider: StringProvider, ) : NotificationTroubleshootTest { override val order: Int = 0 diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt index b38d00ee22..808fda579f 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt @@ -101,4 +101,32 @@ class NotificationTroubleshootCheckPermissionTestTest { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Success) } } + + @Test + fun `test NotificationTroubleshootCheckPermissionTest error and reset`() = runTest { + val permissionStateProvider = FakePermissionStateProvider( + permissionGranted = false + ) + val actions = FakePermissionActions( + openSettingsAction = { + permissionStateProvider.setPermissionGranted() + } + ) + val sut = NotificationTroubleshootCheckPermissionTest( + permissionStateProvider = permissionStateProvider, + sdkVersionProvider = FakeBuildVersionSdkIntProvider(sdkInt = Build.VERSION_CODES.TIRAMISU), + permissionActions = actions, + stringProvider = FakeStringProvider(), + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(true)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) + } + } } 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 7f7beb9d9b..599f805c19 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 @@ -58,6 +58,8 @@ class CurrentPushProviderTestTest { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) val lastItem = awaitItem() assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) } } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/NotificationTestTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/NotificationTestTest.kt index 1f5b1c43db..a90e6e6f93 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/NotificationTestTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/NotificationTestTest.kt @@ -61,6 +61,8 @@ class NotificationTestTest { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.WaitingForUser) assertThat(awaitItem().status).isInstanceOf(NotificationTroubleshootTestState.Status.Failure::class.java) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTestTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTestTest.kt index 2c1363af78..ee89befef4 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTestTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTestTest.kt @@ -71,6 +71,8 @@ class PushLoopbackTestTest { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) val lastItem = awaitItem() assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushProvidersTestTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushProvidersTestTest.kt index e58a490715..9f9ad21e2a 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushProvidersTestTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushProvidersTestTest.kt @@ -40,6 +40,8 @@ class PushProvidersTestTest { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) val lastItem = awaitItem() assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true)) } } diff --git a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseAvailabilityTestTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseAvailabilityTestTest.kt index fae5ba9f12..17c812a89c 100644 --- a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseAvailabilityTestTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseAvailabilityTestTest.kt @@ -59,6 +59,8 @@ class FirebaseAvailabilityTestTest { assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) val lastItem = awaitItem() assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(false)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) } } diff --git a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseTokenTestTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseTokenTestTest.kt index 245a6095d4..f317dba7e8 100644 --- a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseTokenTestTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/troubleshoot/FirebaseTokenTestTest.kt @@ -77,6 +77,31 @@ class FirebaseTokenTestTest { } } + @Test + fun `test FirebaseTokenTest error and reset`() = runTest { + val firebaseStore = InMemoryFirebaseStore(null) + val sut = FirebaseTokenTest( + firebaseStore = firebaseStore, + firebaseTroubleshooter = FakeFirebaseTroubleshooter( + troubleShootResult = { + firebaseStore.storeFcmToken(FAKE_TOKEN) + Result.success(Unit) + } + ), + stringProvider = FakeStringProvider(), + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(true)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + } + } + @Test fun `test FirebaseTokenTest isRelevant`() { val sut = FirebaseTokenTest( diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushTestTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushTestTest.kt index 9f79f7363b..29255a3f26 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushTestTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushTestTest.kt @@ -84,6 +84,35 @@ class UnifiedPushTestTest { } } + @Test + fun `test UnifiedPushTest error and reset`() = runTest { + val providers = FakeUnifiedPushDistributorProvider() + val sut = UnifiedPushTest( + unifiedPushDistributorProvider = providers, + openDistributorWebPageAction = FakeOpenDistributorWebPageAction( + executeAction = { + providers.setDistributorsResult( + listOf( + Distributor("value", "Name"), + ) + ) + } + ), + stringProvider = FakeStringProvider(), + ) + launch { + sut.run(this) + } + sut.state.test { + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress) + val lastItem = awaitItem() + assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(true)) + sut.reset() + assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(false)) + } + } + @Test fun `test isRelevant`() { val sut = UnifiedPushTest( From 90352bd1ad6c4477ab12f782e0d2ca592d1be4aa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 11:09:27 +0200 Subject: [PATCH 3/8] Remove `const val PUSH_GATEWAY_PATH`, it makes the code more complex for no added value. --- .../libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt | 4 +--- .../pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt | 2 +- .../pushproviders/unifiedpush/network/UnifiedPushApi.kt | 3 +-- .../unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt index 82db2d6021..b1d321f42f 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushConfig.kt @@ -17,13 +17,11 @@ package io.element.android.libraries.pushproviders.unifiedpush object UnifiedPushConfig { - const val PUSH_GATEWAY_PATH: String = "_matrix/push/v1/notify" - /** * It is the push gateway for UnifiedPush. * Note: default_push_gateway_http_url should have path '/_matrix/push/v1/notify' */ - const val DEFAULT_PUSH_GATEWAY_HTTP_URL: String = "https://matrix.gateway.unifiedpush.org/$PUSH_GATEWAY_PATH" + const val DEFAULT_PUSH_GATEWAY_HTTP_URL: String = "https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify" const val UNIFIED_PUSH_DISTRIBUTORS_URL = "https://unifiedpush.org/users/distributors/" diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt index 9da92e7315..ff04d007ab 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt @@ -46,7 +46,7 @@ class DefaultUnifiedPushGatewayResolver @Inject constructor( } else { val port = if (url.port != -1) ":${url.port}" else "" val customBase = "${url.protocol}://${url.host}$port" - val customUrl = "$customBase/${UnifiedPushConfig.PUSH_GATEWAY_PATH}" + val customUrl = "$customBase/_matrix/push/v1/notify" Timber.i("Testing $customUrl") return withContext(coroutineDispatchers.io) { val api = unifiedPushApiFactory.create(customBase) diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt index 6f9ff5679d..cd6cd7440e 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/network/UnifiedPushApi.kt @@ -16,10 +16,9 @@ package io.element.android.libraries.pushproviders.unifiedpush.network -import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushConfig import retrofit2.http.GET interface UnifiedPushApi { - @GET(UnifiedPushConfig.PUSH_GATEWAY_PATH) + @GET("_matrix/push/v1/notify") suspend fun discover(): DiscoveryResponse } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt index f11ae99965..368b0d58c3 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt @@ -59,7 +59,7 @@ class UnifiedPushMatrixGatewayTest @Inject constructor( status = NotificationTroubleshootTestState.Status.Failure(false) ) } else { - val gatewayBaseUrl = config.url.removeSuffix("/${UnifiedPushConfig.PUSH_GATEWAY_PATH}") + val gatewayBaseUrl = config.url.removeSuffix("/_matrix/push/v1/notify") // Checking if the gateway is a Matrix gateway coroutineScope.launch(coroutineDispatchers.io) { val api = unifiedPushApiFactory.create(gatewayBaseUrl) From 35b019318e0c2e3234ff455fed398f848e08ca58 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 11:12:21 +0200 Subject: [PATCH 4/8] Imporve logs. --- .../unifiedpush/UnifiedPushGatewayResolver.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt index ff04d007ab..9190560b70 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt @@ -34,29 +34,33 @@ class DefaultUnifiedPushGatewayResolver @Inject constructor( private val unifiedPushApiFactory: UnifiedPushApiFactory, private val coroutineDispatchers: CoroutineDispatchers, ) : UnifiedPushGatewayResolver { + private val logger = Timber.tag("DefaultUnifiedPushGatewayResolver") + override suspend fun getGateway(endpoint: String): String { val url = tryOrNull( - onError = { Timber.d(it, "Cannot parse endpoint as an URL") } + onError = { logger.d(it, "Cannot parse endpoint as an URL") } ) { URL(endpoint) } return if (url == null) { - Timber.d("Using default gateway") + logger.d("Using default gateway") UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL } else { val port = if (url.port != -1) ":${url.port}" else "" val customBase = "${url.protocol}://${url.host}$port" val customUrl = "$customBase/_matrix/push/v1/notify" - Timber.i("Testing $customUrl") + logger.i("Testing $customUrl") return withContext(coroutineDispatchers.io) { val api = unifiedPushApiFactory.create(customBase) try { val discoveryResponse = api.discover() if (discoveryResponse.unifiedpush.gateway == "matrix") { - Timber.d("Using custom gateway") + logger.d("The endpoint seems to be a valid UnifiedPush gateway") + } else { + logger.e("The endpoint does not seem to be a valid UnifiedPush gateway") } } catch (throwable: Throwable) { - Timber.tag("UnifiedPushHelper").e(throwable) + logger.e(throwable, "Error checking for UnifiedPush endpoint") } // Always return the custom url. customUrl From 22f9e5515c1285e42428855b6b82391a02a6abcf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 11:16:20 +0200 Subject: [PATCH 5/8] Fix quality issue. --- .../troubleshoot/UnifiedPushMatrixGatewayTestTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt index 7b4d48070c..f9f2dbeb2e 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt @@ -93,7 +93,7 @@ class UnifiedPushMatrixGatewayTestTest { fun `test UnifiedPushMatrixGatewayTest network error`() = runTest { val sut = createUnifiedPushMatrixGatewayTest( currentUserPushConfig = aCurrentUserPushConfig(), - discoveryResponse = { throw RuntimeException("Network error") }, + discoveryResponse = { error("Network error") }, ) launch { sut.run(this) From 3e74fa05d7f9bbec91a66b6ec2ace2249c69dace Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 11:31:46 +0200 Subject: [PATCH 6/8] Fix injection issue. --- ...nifiedPushCurrentUserPushConfigProvider.kt | 47 +++++++++++++++++++ .../UnifiedPushMatrixGatewayTest.kt | 6 +-- ...nifiedPushCurrentUserPushConfigProvider.kt | 29 ++++++++++++ .../UnifiedPushMatrixGatewayTestTest.kt | 5 +- 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushCurrentUserPushConfigProvider.kt create mode 100644 libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/FakeUnifiedPushCurrentUserPushConfigProvider.kt diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushCurrentUserPushConfigProvider.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushCurrentUserPushConfigProvider.kt new file mode 100644 index 0000000000..d71e04c2e2 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushCurrentUserPushConfigProvider.kt @@ -0,0 +1,47 @@ +/* + * 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 + * + * https://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.libraries.pushproviders.unifiedpush + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig +import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret +import io.element.android.services.appnavstate.api.AppNavigationStateService +import io.element.android.services.appnavstate.api.currentSessionId +import javax.inject.Inject + +interface UnifiedPushCurrentUserPushConfigProvider { + suspend fun provide(): CurrentUserPushConfig? +} + +@ContributesBinding(AppScope::class) +class DefaultUnifiedPushCurrentUserPushConfigProvider @Inject constructor( + private val pushClientSecret: PushClientSecret, + private val unifiedPushStore: UnifiedPushStore, + private val appNavigationStateService: AppNavigationStateService, +) : UnifiedPushCurrentUserPushConfigProvider { + override suspend fun provide(): CurrentUserPushConfig? { + val currentSession = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() ?: return null + val clientSecret = pushClientSecret.getSecretForUser(currentSession) + val url = unifiedPushStore.getPushGateway(clientSecret) ?: return null + val pushKey = unifiedPushStore.getEndpoint(clientSecret) ?: return null + return CurrentUserPushConfig( + url = url, + pushKey = pushKey, + ) + } +} diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt index 368b0d58c3..a5926ed387 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTest.kt @@ -19,9 +19,9 @@ package io.element.android.libraries.pushproviders.unifiedpush.troubleshoot import com.squareup.anvil.annotations.ContributesMultibinding import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.AppScope -import io.element.android.libraries.pushproviders.api.PushProvider import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushApiFactory import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushConfig +import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushCurrentUserPushConfigProvider 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.NotificationTroubleshootTestState @@ -35,7 +35,7 @@ import javax.inject.Inject class UnifiedPushMatrixGatewayTest @Inject constructor( private val unifiedPushApiFactory: UnifiedPushApiFactory, private val coroutineDispatchers: CoroutineDispatchers, - private val pushProvider: PushProvider, + private val unifiedPushCurrentUserPushConfigProvider: UnifiedPushCurrentUserPushConfigProvider, ) : NotificationTroubleshootTest { override val order = 450 private val delegate = NotificationTroubleshootTestDelegate( @@ -52,7 +52,7 @@ class UnifiedPushMatrixGatewayTest @Inject constructor( override suspend fun run(coroutineScope: CoroutineScope) { delegate.start() - val config = pushProvider.getCurrentUserPushConfig() + val config = unifiedPushCurrentUserPushConfigProvider.provide() if (config == null) { delegate.updateState( description = "No current push provider", diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/FakeUnifiedPushCurrentUserPushConfigProvider.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/FakeUnifiedPushCurrentUserPushConfigProvider.kt new file mode 100644 index 0000000000..c7c5bf9189 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/FakeUnifiedPushCurrentUserPushConfigProvider.kt @@ -0,0 +1,29 @@ +/* + * 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 + * + * https://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.libraries.pushproviders.unifiedpush.troubleshoot + +import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig +import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushCurrentUserPushConfigProvider +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeUnifiedPushCurrentUserPushConfigProvider( + private val currentUserPushConfig: () -> CurrentUserPushConfig? = { lambdaError() }, +) : UnifiedPushCurrentUserPushConfigProvider { + override suspend fun provide(): CurrentUserPushConfig? { + return currentUserPushConfig() + } +} diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt index f9f2dbeb2e..46ea679679 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/troubleshoot/UnifiedPushMatrixGatewayTestTest.kt @@ -19,7 +19,6 @@ package io.element.android.libraries.pushproviders.unifiedpush.troubleshoot import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig -import io.element.android.libraries.pushproviders.test.FakePushProvider import io.element.android.libraries.pushproviders.test.aCurrentUserPushConfig import io.element.android.libraries.pushproviders.unifiedpush.FakeUnifiedPushApiFactory import io.element.android.libraries.pushproviders.unifiedpush.UnifiedPushConfig @@ -120,7 +119,9 @@ class UnifiedPushMatrixGatewayTestTest { return UnifiedPushMatrixGatewayTest( unifiedPushApiFactory = FakeUnifiedPushApiFactory(discoveryResponse), coroutineDispatchers = testCoroutineDispatchers(), - pushProvider = FakePushProvider(currentUserPushConfig = currentUserPushConfig), + unifiedPushCurrentUserPushConfigProvider = FakeUnifiedPushCurrentUserPushConfigProvider( + currentUserPushConfig = { currentUserPushConfig } + ), ) } } From 264d1bc694b4e1c41d080772e22c0c618d01fae8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 11:42:40 +0200 Subject: [PATCH 7/8] Let UnifiedPushProvider use UnifiedPushCurrentUserPushConfigProvider --- .../unifiedpush/UnifiedPushProvider.kt | 13 +- ...edPushCurrentUserPushConfigProviderTest.kt | 120 ++++++++++++++++++ .../unifiedpush/UnifiedPushProviderTest.kt | 87 ++----------- 3 files changed, 132 insertions(+), 88 deletions(-) create mode 100644 libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushCurrentUserPushConfigProviderTest.kt 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 680b264f29..667be5ab5d 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 @@ -23,8 +23,6 @@ import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret -import io.element.android.services.appnavstate.api.AppNavigationStateService -import io.element.android.services.appnavstate.api.currentSessionId import javax.inject.Inject @ContributesMultibinding(AppScope::class) @@ -34,7 +32,7 @@ class UnifiedPushProvider @Inject constructor( private val unRegisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase, private val pushClientSecret: PushClientSecret, private val unifiedPushStore: UnifiedPushStore, - private val appNavigationStateService: AppNavigationStateService, + private val unifiedPushCurrentUserPushConfigProvider: UnifiedPushCurrentUserPushConfigProvider, ) : PushProvider { override val index = UnifiedPushConfig.INDEX override val name = UnifiedPushConfig.NAME @@ -62,13 +60,6 @@ class UnifiedPushProvider @Inject constructor( } override suspend fun getCurrentUserPushConfig(): CurrentUserPushConfig? { - val currentSession = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() ?: return null - val clientSecret = pushClientSecret.getSecretForUser(currentSession) - val url = unifiedPushStore.getPushGateway(clientSecret) ?: return null - val pushKey = unifiedPushStore.getEndpoint(clientSecret) ?: return null - return CurrentUserPushConfig( - url = url, - pushKey = pushKey, - ) + return unifiedPushCurrentUserPushConfigProvider.provide() } } diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushCurrentUserPushConfigProviderTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushCurrentUserPushConfigProviderTest.kt new file mode 100644 index 0000000000..b115d193fe --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushCurrentUserPushConfigProviderTest.kt @@ -0,0 +1,120 @@ +/* + * 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 + * + * https://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.libraries.pushproviders.unifiedpush + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.test.A_SECRET +import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig +import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret +import io.element.android.libraries.pushstore.test.userpushstore.clientsecret.FakePushClientSecret +import io.element.android.services.appnavstate.api.AppNavigationState +import io.element.android.services.appnavstate.api.AppNavigationStateService +import io.element.android.services.appnavstate.api.NavigationState +import io.element.android.services.appnavstate.test.FakeAppNavigationStateService +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class DefaultUnifiedPushCurrentUserPushConfigProviderTest { + @Test + fun `getCurrentUserPushConfig no session`() = runTest { + val sut = createDefaultUnifiedPushCurrentUserPushConfigProvider() + val result = sut.provide() + assertThat(result).isNull() + } + + @Test + fun `getCurrentUserPushConfig no push gateway`() = runTest { + val sut = createDefaultUnifiedPushCurrentUserPushConfigProvider( + appNavigationStateService = FakeAppNavigationStateService( + appNavigationState = MutableStateFlow( + AppNavigationState( + navigationState = NavigationState.Session(owner = "owner", sessionId = A_SESSION_ID), + isInForeground = true + ) + ) + ), + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = { A_SECRET } + ), + unifiedPushStore = FakeUnifiedPushStore( + getPushGatewayResult = { null } + ), + ) + val result = sut.provide() + assertThat(result).isNull() + } + + @Test + fun `getCurrentUserPushConfig no push key`() = runTest { + val sut = createDefaultUnifiedPushCurrentUserPushConfigProvider( + appNavigationStateService = FakeAppNavigationStateService( + appNavigationState = MutableStateFlow( + AppNavigationState( + navigationState = NavigationState.Session(owner = "owner", sessionId = A_SESSION_ID), + isInForeground = true + ) + ) + ), + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = { A_SECRET } + ), + unifiedPushStore = FakeUnifiedPushStore( + getPushGatewayResult = { "aPushGateway" }, + getEndpointResult = { null } + ), + ) + val result = sut.provide() + assertThat(result).isNull() + } + + @Test + fun `getCurrentUserPushConfig ok`() = runTest { + val sut = createDefaultUnifiedPushCurrentUserPushConfigProvider( + appNavigationStateService = FakeAppNavigationStateService( + appNavigationState = MutableStateFlow( + AppNavigationState( + navigationState = NavigationState.Session(owner = "owner", sessionId = A_SESSION_ID), + isInForeground = true + ) + ) + ), + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = { A_SECRET } + ), + unifiedPushStore = FakeUnifiedPushStore( + getPushGatewayResult = { "aPushGateway" }, + getEndpointResult = { "aEndpoint" } + ), + ) + val result = sut.provide() + assertThat(result).isEqualTo(CurrentUserPushConfig("aPushGateway", "aEndpoint")) + } + + private fun createDefaultUnifiedPushCurrentUserPushConfigProvider( + pushClientSecret: PushClientSecret = FakePushClientSecret(), + unifiedPushStore: UnifiedPushStore = FakeUnifiedPushStore(), + appNavigationStateService: AppNavigationStateService = FakeAppNavigationStateService(), + ): DefaultUnifiedPushCurrentUserPushConfigProvider { + return DefaultUnifiedPushCurrentUserPushConfigProvider( + pushClientSecret = pushClientSecret, + unifiedPushStore = unifiedPushStore, + appNavigationStateService = appNavigationStateService, + ) + } +} diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProviderTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProviderTest.kt index 0e3bf1655c..a7c0623a33 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProviderTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProviderTest.kt @@ -24,18 +24,14 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_SECRET import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient -import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig import io.element.android.libraries.pushproviders.api.Distributor +import io.element.android.libraries.pushproviders.test.aCurrentUserPushConfig +import io.element.android.libraries.pushproviders.unifiedpush.troubleshoot.FakeUnifiedPushCurrentUserPushConfigProvider import io.element.android.libraries.pushproviders.unifiedpush.troubleshoot.FakeUnifiedPushDistributorProvider import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret import io.element.android.libraries.pushstore.test.userpushstore.clientsecret.FakePushClientSecret -import io.element.android.services.appnavstate.api.AppNavigationState -import io.element.android.services.appnavstate.api.AppNavigationStateService -import io.element.android.services.appnavstate.api.NavigationState -import io.element.android.services.appnavstate.test.FakeAppNavigationStateService import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest import org.junit.Test @@ -226,78 +222,15 @@ class UnifiedPushProviderTest { } @Test - fun `getCurrentUserPushConfig no session`() = runTest { - val unifiedPushProvider = createUnifiedPushProvider() - val result = unifiedPushProvider.getCurrentUserPushConfig() - assertThat(result).isNull() - } - - @Test - fun `getCurrentUserPushConfig no push gateway`() = runTest { + fun `getCurrentUserPushConfig invokes the provider methods`() = runTest { + val currentUserPushConfig = aCurrentUserPushConfig() val unifiedPushProvider = createUnifiedPushProvider( - appNavigationStateService = FakeAppNavigationStateService( - appNavigationState = MutableStateFlow( - AppNavigationState( - navigationState = NavigationState.Session(owner = "owner", sessionId = A_SESSION_ID), - isInForeground = true - ) - ) - ), - pushClientSecret = FakePushClientSecret( - getSecretForUserResult = { A_SECRET } - ), - unifiedPushStore = FakeUnifiedPushStore( - getPushGatewayResult = { null } - ), + unifiedPushCurrentUserPushConfigProvider = FakeUnifiedPushCurrentUserPushConfigProvider( + currentUserPushConfig = { currentUserPushConfig } + ) ) val result = unifiedPushProvider.getCurrentUserPushConfig() - assertThat(result).isNull() - } - - @Test - fun `getCurrentUserPushConfig no push key`() = runTest { - val unifiedPushProvider = createUnifiedPushProvider( - appNavigationStateService = FakeAppNavigationStateService( - appNavigationState = MutableStateFlow( - AppNavigationState( - navigationState = NavigationState.Session(owner = "owner", sessionId = A_SESSION_ID), - isInForeground = true - ) - ) - ), - pushClientSecret = FakePushClientSecret( - getSecretForUserResult = { A_SECRET } - ), - unifiedPushStore = FakeUnifiedPushStore( - getPushGatewayResult = { "aPushGateway" }, - getEndpointResult = { null } - ), - ) - val result = unifiedPushProvider.getCurrentUserPushConfig() - assertThat(result).isNull() - } - - @Test - fun `getCurrentUserPushConfig ok`() = runTest { - val unifiedPushProvider = createUnifiedPushProvider( - appNavigationStateService = FakeAppNavigationStateService( - appNavigationState = MutableStateFlow( - AppNavigationState( - navigationState = NavigationState.Session(owner = "owner", sessionId = A_SESSION_ID), - isInForeground = true - ) - ) - ), - pushClientSecret = FakePushClientSecret( - getSecretForUserResult = { A_SECRET } - ), - unifiedPushStore = FakeUnifiedPushStore( - getPushGatewayResult = { "aPushGateway" }, - getEndpointResult = { "aEndpoint" } - ), - ) - val result = unifiedPushProvider.getCurrentUserPushConfig() - assertThat(result).isEqualTo(CurrentUserPushConfig("aPushGateway", "aEndpoint")) + assertThat(result).isEqualTo(currentUserPushConfig) } private fun createUnifiedPushProvider( @@ -306,7 +239,7 @@ class UnifiedPushProviderTest { unRegisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase = FakeUnregisterUnifiedPushUseCase(), pushClientSecret: PushClientSecret = FakePushClientSecret(), unifiedPushStore: UnifiedPushStore = FakeUnifiedPushStore(), - appNavigationStateService: AppNavigationStateService = FakeAppNavigationStateService(), + unifiedPushCurrentUserPushConfigProvider: UnifiedPushCurrentUserPushConfigProvider = FakeUnifiedPushCurrentUserPushConfigProvider(), ): UnifiedPushProvider { return UnifiedPushProvider( unifiedPushDistributorProvider = unifiedPushDistributorProvider, @@ -314,7 +247,7 @@ class UnifiedPushProviderTest { unRegisterUnifiedPushUseCase = unRegisterUnifiedPushUseCase, pushClientSecret = pushClientSecret, unifiedPushStore = unifiedPushStore, - appNavigationStateService = appNavigationStateService + unifiedPushCurrentUserPushConfigProvider = unifiedPushCurrentUserPushConfigProvider, ) } } From 7db5ac81959905be0726ace48789a369d5d82e36 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Sep 2024 12:23:52 +0200 Subject: [PATCH 8/8] Fix the test according to the behavior change. --- .../unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt index cee74bfa31..00d397d421 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultUnifiedPushGatewayResolverTest.kt @@ -95,7 +95,7 @@ class DefaultUnifiedPushGatewayResolverTest { } @Test - fun `when a custom url is not reachable, the default url is returned`() = runTest { + fun `when a custom url is not reachable, the custom url is still returned`() = runTest { val unifiedPushApiFactory = FakeUnifiedPushApiFactory( discoveryResponse = { throw AN_EXCEPTION } ) @@ -104,7 +104,7 @@ class DefaultUnifiedPushGatewayResolverTest { ) val result = sut.getGateway("http://custom.url") assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("http://custom.url") - assertThat(result).isEqualTo(UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL) + assertThat(result).isEqualTo("http://custom.url/_matrix/push/v1/notify") } @Test @@ -121,7 +121,7 @@ class DefaultUnifiedPushGatewayResolverTest { } @Test - fun `when a custom url provides a invalid matrix gateway, the default url is returned`() = runTest { + fun `when a custom url provides a invalid matrix gateway, the custom url is still returned`() = runTest { val unifiedPushApiFactory = FakeUnifiedPushApiFactory( discoveryResponse = invalidDiscoveryResponse ) @@ -130,7 +130,7 @@ class DefaultUnifiedPushGatewayResolverTest { ) val result = sut.getGateway("https://custom.url") assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("https://custom.url") - assertThat(result).isEqualTo(UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL) + assertThat(result).isEqualTo("https://custom.url/_matrix/push/v1/notify") } private fun TestScope.createDefaultUnifiedPushGatewayResolver(