diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index e507e34033..d10d1ad0d2 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationSettings const val A_USER_NAME = "alice" const val A_PASSWORD = "password" +const val A_SECRET = "secret" val A_USER_ID = UserId("@alice:server.org") val A_USER_ID_2 = UserId("@bob:server.org") diff --git a/libraries/pushproviders/unifiedpush/build.gradle.kts b/libraries/pushproviders/unifiedpush/build.gradle.kts index d5dcc9727d..d2ea2ccc23 100644 --- a/libraries/pushproviders/unifiedpush/build.gradle.kts +++ b/libraries/pushproviders/unifiedpush/build.gradle.kts @@ -60,4 +60,5 @@ dependencies { testImplementation(projects.libraries.matrix.test) testImplementation(projects.tests.testutils) testImplementation(projects.services.toolbox.test) + testImplementation(projects.services.appnavstate.test) } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/RegisterUnifiedPushUseCase.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/RegisterUnifiedPushUseCase.kt index 24f93b88dc..1839bb4d18 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/RegisterUnifiedPushUseCase.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/RegisterUnifiedPushUseCase.kt @@ -17,6 +17,8 @@ package io.element.android.libraries.pushproviders.unifiedpush import android.content.Context +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler @@ -30,12 +32,17 @@ import org.unifiedpush.android.connector.UnifiedPush import javax.inject.Inject import kotlin.time.Duration.Companion.seconds -class RegisterUnifiedPushUseCase @Inject constructor( +interface RegisterUnifiedPushUseCase { + suspend fun execute(distributor: Distributor, clientSecret: String): Result +} + +@ContributesBinding(AppScope::class) +class DefaultRegisterUnifiedPushUseCase @Inject constructor( @ApplicationContext private val context: Context, private val endpointRegistrationHandler: EndpointRegistrationHandler, private val coroutineScope: CoroutineScope, -) { - suspend fun execute(distributor: Distributor, clientSecret: String): Result { +) : RegisterUnifiedPushUseCase { + override suspend fun execute(distributor: Distributor, clientSecret: String): Result { UnifiedPush.saveDistributor(context, distributor.value) val completable = CompletableDeferred>() val job = coroutineScope.launch { diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt index 7b6ee5ef37..397ca381eb 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt @@ -19,22 +19,34 @@ package io.element.android.libraries.pushproviders.unifiedpush import android.content.Context import android.content.SharedPreferences import androidx.core.content.edit +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.DefaultPreferences import io.element.android.libraries.matrix.api.core.UserId import javax.inject.Inject -class UnifiedPushStore @Inject constructor( +interface UnifiedPushStore { + fun getEndpoint(clientSecret: String): String? + fun storeUpEndpoint(endpoint: String?, clientSecret: String) + fun getPushGateway(clientSecret: String): String? + fun storePushGateway(gateway: String?, clientSecret: String) + fun getDistributorValue(userId: UserId): String? + fun setDistributorValue(userId: UserId, value: String) +} + +@ContributesBinding(AppScope::class) +class DefaultUnifiedPushStore @Inject constructor( @ApplicationContext val context: Context, @DefaultPreferences private val defaultPrefs: SharedPreferences, -) { +) : UnifiedPushStore { /** * Retrieves the UnifiedPush Endpoint. * * @param clientSecret the client secret, to identify the session * @return the UnifiedPush Endpoint or null if not received */ - fun getEndpoint(clientSecret: String): String? { + override fun getEndpoint(clientSecret: String): String? { return defaultPrefs.getString(PREFS_ENDPOINT_OR_TOKEN + clientSecret, null) } @@ -44,7 +56,7 @@ class UnifiedPushStore @Inject constructor( * @param endpoint the endpoint to store * @param clientSecret the client secret, to identify the session */ - fun storeUpEndpoint(endpoint: String?, clientSecret: String) { + override fun storeUpEndpoint(endpoint: String?, clientSecret: String) { defaultPrefs.edit { putString(PREFS_ENDPOINT_OR_TOKEN + clientSecret, endpoint) } @@ -56,7 +68,7 @@ class UnifiedPushStore @Inject constructor( * @param clientSecret the client secret, to identify the session * @return the Push Gateway or null if not defined */ - fun getPushGateway(clientSecret: String): String? { + override fun getPushGateway(clientSecret: String): String? { return defaultPrefs.getString(PREFS_PUSH_GATEWAY + clientSecret, null) } @@ -66,17 +78,17 @@ class UnifiedPushStore @Inject constructor( * @param gateway the push gateway to store * @param clientSecret the client secret, to identify the session */ - fun storePushGateway(gateway: String?, clientSecret: String) { + override fun storePushGateway(gateway: String?, clientSecret: String) { defaultPrefs.edit { putString(PREFS_PUSH_GATEWAY + clientSecret, gateway) } } - fun getDistributorValue(userId: UserId): String? { + override fun getDistributorValue(userId: UserId): String? { return defaultPrefs.getString(PREFS_DISTRIBUTOR + userId, null) } - fun setDistributorValue(userId: UserId, value: String) { + override fun setDistributorValue(userId: UserId, value: String) { defaultPrefs.edit { putString(PREFS_DISTRIBUTOR + userId, value) } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnregisterUnifiedPushUseCase.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnregisterUnifiedPushUseCase.kt index b2dd33c252..1eb9876ae4 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnregisterUnifiedPushUseCase.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnregisterUnifiedPushUseCase.kt @@ -17,18 +17,25 @@ package io.element.android.libraries.pushproviders.unifiedpush import android.content.Context +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.pushproviders.api.PusherSubscriber import org.unifiedpush.android.connector.UnifiedPush import javax.inject.Inject -class UnregisterUnifiedPushUseCase @Inject constructor( +interface UnregisterUnifiedPushUseCase { + suspend fun execute(matrixClient: MatrixClient, clientSecret: String): Result +} + +@ContributesBinding(AppScope::class) +class DefaultUnregisterUnifiedPushUseCase @Inject constructor( @ApplicationContext private val context: Context, private val unifiedPushStore: UnifiedPushStore, private val pusherSubscriber: PusherSubscriber, -) { - suspend fun execute(matrixClient: MatrixClient, clientSecret: String): Result { +) : UnregisterUnifiedPushUseCase { + override suspend fun execute(matrixClient: MatrixClient, clientSecret: String): Result { val endpoint = unifiedPushStore.getEndpoint(clientSecret) val gateway = unifiedPushStore.getPushGateway(clientSecret) if (endpoint == null || gateway == null) { diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakePushClientSecret.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakePushClientSecret.kt new file mode 100644 index 0000000000..1ab65696aa --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakePushClientSecret.kt @@ -0,0 +1,33 @@ +/* + * 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 + +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret + +class FakePushClientSecret( + private val getSecretForUserResult: (SessionId) -> String = { TODO() }, + private val getUserIdFromSecretResult: (String) -> SessionId? = { TODO() } +) : PushClientSecret { + override suspend fun getSecretForUser(userId: SessionId): String { + return getSecretForUserResult(userId) + } + + override suspend fun getUserIdFromSecret(clientSecret: String): SessionId? { + return getUserIdFromSecretResult(clientSecret) + } +} diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeRegisterUnifiedPushUseCase.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeRegisterUnifiedPushUseCase.kt new file mode 100644 index 0000000000..b1995af699 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeRegisterUnifiedPushUseCase.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 + * + * 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 + +import io.element.android.libraries.pushproviders.api.Distributor + +class FakeRegisterUnifiedPushUseCase( + private val result: (Distributor, String) -> Result = { _, _ -> TODO("Not yet implemented") } +) : RegisterUnifiedPushUseCase { + override suspend fun execute(distributor: Distributor, clientSecret: String): Result { + return result(distributor, clientSecret) + } +} diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeUnifiedPushStore.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeUnifiedPushStore.kt new file mode 100644 index 0000000000..2fcdb367a9 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeUnifiedPushStore.kt @@ -0,0 +1,52 @@ +/* + * 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 + +import io.element.android.libraries.matrix.api.core.UserId + +class FakeUnifiedPushStore( + private val getEndpointResult: (String) -> String? = { TODO() }, + private val storeUpEndpointResult: (String?, String) -> Unit = { _, _ -> TODO() }, + private val getPushGatewayResult: (String) -> String? = { TODO() }, + private val storePushGatewayResult: (String?, String) -> Unit = { _, _ -> TODO() }, + private val getDistributorValueResult: (UserId) -> String? = { TODO() }, + private val setDistributorValueResult: (UserId, String) -> Unit = { _, _ -> TODO() }, +) : UnifiedPushStore { + override fun getEndpoint(clientSecret: String): String? { + return getEndpointResult(clientSecret) + } + + override fun storeUpEndpoint(endpoint: String?, clientSecret: String) { + storeUpEndpointResult(endpoint, clientSecret) + } + + override fun getPushGateway(clientSecret: String): String? { + return getPushGatewayResult(clientSecret) + } + + override fun storePushGateway(gateway: String?, clientSecret: String) { + storePushGatewayResult(gateway, clientSecret) + } + + override fun getDistributorValue(userId: UserId): String? { + return getDistributorValueResult(userId) + } + + override fun setDistributorValue(userId: UserId, value: String) { + setDistributorValueResult(userId, value) + } +} diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeUnregisterUnifiedPushUseCase.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeUnregisterUnifiedPushUseCase.kt new file mode 100644 index 0000000000..7aca65fe0d --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/FakeUnregisterUnifiedPushUseCase.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 + * + * 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 + +import io.element.android.libraries.matrix.api.MatrixClient + +class FakeUnregisterUnifiedPushUseCase( + private val result: (MatrixClient, String) -> Result = { _, _ -> TODO("Not yet implemented") } +) : UnregisterUnifiedPushUseCase { + override suspend fun execute(matrixClient: MatrixClient, clientSecret: String): Result { + return result(matrixClient, clientSecret) + } +} 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 new file mode 100644 index 0000000000..3ab0678ab5 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProviderTest.kt @@ -0,0 +1,321 @@ +/* + * 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 + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.UserId +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.unifiedpush.troubleshoot.FakeUnifiedPushDistributorProvider +import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret +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 + +class UnifiedPushProviderTest { + @Test + fun `test index and name`() { + val unifiedPushProvider = createUnifiedPushProvider() + assertThat(unifiedPushProvider.name).isEqualTo(UnifiedPushConfig.NAME) + assertThat(unifiedPushProvider.index).isEqualTo(UnifiedPushConfig.INDEX) + } + + @Test + fun `getDistributors return the available distributors`() { + val unifiedPushProvider = createUnifiedPushProvider( + unifiedPushDistributorProvider = FakeUnifiedPushDistributorProvider( + getDistributorsResult = listOf( + Distributor("value", "Name"), + ) + ) + ) + val result = unifiedPushProvider.getDistributors() + assertThat(result).containsExactly(Distributor("value", "Name")) + assertThat(unifiedPushProvider.isAvailable()).isTrue() + } + + @Test + fun `getDistributors return empty`() { + val unifiedPushProvider = createUnifiedPushProvider( + unifiedPushDistributorProvider = FakeUnifiedPushDistributorProvider( + getDistributorsResult = emptyList() + ) + ) + val result = unifiedPushProvider.getDistributors() + assertThat(result).isEmpty() + assertThat(unifiedPushProvider.isAvailable()).isFalse() + } + + @Test + fun `register ok`() = runTest { + val getSecretForUserResultLambda = lambdaRecorder { A_SECRET } + val executeLambda = lambdaRecorder> { _, _ -> Result.success(Unit) } + val setDistributorValueResultLambda = lambdaRecorder { _, _ -> } + val unifiedPushProvider = createUnifiedPushProvider( + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = getSecretForUserResultLambda, + ), + registerUnifiedPushUseCase = FakeRegisterUnifiedPushUseCase( + result = executeLambda, + ), + unifiedPushStore = FakeUnifiedPushStore( + setDistributorValueResult = setDistributorValueResultLambda, + ), + ) + val result = unifiedPushProvider.registerWith(FakeMatrixClient(), Distributor("value", "Name")) + assertThat(result).isEqualTo(Result.success(Unit)) + getSecretForUserResultLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(A_SESSION_ID))) + executeLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(Distributor("value", "Name")), value(A_SECRET))) + setDistributorValueResultLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(A_SESSION_ID), value("value"))) + } + + @Test + fun `register ko`() = runTest { + val getSecretForUserResultLambda = lambdaRecorder { A_SECRET } + val executeLambda = lambdaRecorder> { _, _ -> Result.failure(AN_EXCEPTION) } + val setDistributorValueResultLambda = lambdaRecorder(ensureNeverCalled = true) { _, _ -> } + val unifiedPushProvider = createUnifiedPushProvider( + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = getSecretForUserResultLambda, + ), + registerUnifiedPushUseCase = FakeRegisterUnifiedPushUseCase( + result = executeLambda, + ), + unifiedPushStore = FakeUnifiedPushStore( + setDistributorValueResult = setDistributorValueResultLambda, + ), + ) + val result = unifiedPushProvider.registerWith(FakeMatrixClient(), Distributor("value", "Name")) + assertThat(result).isEqualTo(Result.failure(AN_EXCEPTION)) + getSecretForUserResultLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(A_SESSION_ID))) + executeLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(Distributor("value", "Name")), value(A_SECRET))) + } + + @Test + fun `unregister ok`() = runTest { + val matrixClient = FakeMatrixClient() + val getSecretForUserResultLambda = lambdaRecorder { A_SECRET } + val executeLambda = lambdaRecorder> { _, _ -> Result.success(Unit) } + val unifiedPushProvider = createUnifiedPushProvider( + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = getSecretForUserResultLambda, + ), + unRegisterUnifiedPushUseCase = FakeUnregisterUnifiedPushUseCase( + result = executeLambda, + ), + ) + val result = unifiedPushProvider.unregister(matrixClient) + assertThat(result).isEqualTo(Result.success(Unit)) + getSecretForUserResultLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(A_SESSION_ID))) + executeLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(matrixClient), value(A_SECRET))) + } + + @Test + fun `unregister ko`() = runTest { + val matrixClient = FakeMatrixClient() + val getSecretForUserResultLambda = lambdaRecorder { A_SECRET } + val executeLambda = lambdaRecorder> { _, _ -> Result.failure(AN_EXCEPTION) } + val unifiedPushProvider = createUnifiedPushProvider( + pushClientSecret = FakePushClientSecret( + getSecretForUserResult = getSecretForUserResultLambda, + ), + unRegisterUnifiedPushUseCase = FakeUnregisterUnifiedPushUseCase( + result = executeLambda, + ), + ) + val result = unifiedPushProvider.unregister(matrixClient) + assertThat(result).isEqualTo(Result.failure(AN_EXCEPTION)) + getSecretForUserResultLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(A_SESSION_ID))) + executeLambda.assertions() + .isCalledExactly(1) + .withSequence(listOf(value(matrixClient), value(A_SECRET))) + } + + @Test + fun `getCurrentDistributor ok`() = runTest { + val distributor = Distributor("value", "Name") + val matrixClient = FakeMatrixClient() + val unifiedPushProvider = createUnifiedPushProvider( + unifiedPushStore = FakeUnifiedPushStore( + getDistributorValueResult = { distributor.value } + ), + unifiedPushDistributorProvider = FakeUnifiedPushDistributorProvider( + getDistributorsResult = listOf( + Distributor("value2", "Name2"), + distributor, + ) + ) + ) + val result = unifiedPushProvider.getCurrentDistributor(matrixClient) + assertThat(result).isEqualTo(distributor) + } + + @Test + fun `getCurrentDistributor not know`() = runTest { + val distributor = Distributor("value", "Name") + val matrixClient = FakeMatrixClient() + val unifiedPushProvider = createUnifiedPushProvider( + unifiedPushStore = FakeUnifiedPushStore( + getDistributorValueResult = { "unknown" } + ), + unifiedPushDistributorProvider = FakeUnifiedPushDistributorProvider( + getDistributorsResult = listOf( + distributor, + ) + ) + ) + val result = unifiedPushProvider.getCurrentDistributor(matrixClient) + assertThat(result).isNull() + } + + @Test + fun `getCurrentDistributor not found`() = runTest { + val distributor = Distributor("value", "Name") + val matrixClient = FakeMatrixClient() + val unifiedPushProvider = createUnifiedPushProvider( + unifiedPushStore = FakeUnifiedPushStore( + getDistributorValueResult = { distributor.value } + ), + unifiedPushDistributorProvider = FakeUnifiedPushDistributorProvider( + getDistributorsResult = emptyList() + ) + ) + val result = unifiedPushProvider.getCurrentDistributor(matrixClient) + assertThat(result).isNull() + } + + @Test + fun `getCurrentUserPushConfig no session`() = runTest { + val unifiedPushProvider = createUnifiedPushProvider() + val result = unifiedPushProvider.getCurrentUserPushConfig() + assertThat(result).isNull() + } + + @Test + fun `getCurrentUserPushConfig no push gateway`() = 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 = { null } + ), + ) + 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")) + } + + private fun createUnifiedPushProvider( + unifiedPushDistributorProvider: UnifiedPushDistributorProvider = FakeUnifiedPushDistributorProvider(), + registerUnifiedPushUseCase: RegisterUnifiedPushUseCase = FakeRegisterUnifiedPushUseCase(), + unRegisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase = FakeUnregisterUnifiedPushUseCase(), + pushClientSecret: PushClientSecret = FakePushClientSecret(), + unifiedPushStore: UnifiedPushStore = FakeUnifiedPushStore(), + appNavigationStateService: AppNavigationStateService = FakeAppNavigationStateService(), + ): UnifiedPushProvider { + return UnifiedPushProvider( + unifiedPushDistributorProvider = unifiedPushDistributorProvider, + registerUnifiedPushUseCase = registerUnifiedPushUseCase, + unRegisterUnifiedPushUseCase = unRegisterUnifiedPushUseCase, + pushClientSecret = pushClientSecret, + unifiedPushStore = unifiedPushStore, + appNavigationStateService = appNavigationStateService + ) + } +}