Merge pull request #7345 from hayaksi1/fix/6426-unifiedpush-account-name

Show the account a UnifiedPush registration belongs to in the distributor
This commit is contained in:
Benoit Marty
2026-08-13 09:09:57 +02:00
committed by GitHub
5 changed files with 17 additions and 14 deletions
@@ -12,6 +12,7 @@ import android.content.Context
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.annotations.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
@@ -21,7 +22,7 @@ import org.unifiedpush.android.connector.UnifiedPush
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
interface RegisterUnifiedPushUseCase { interface RegisterUnifiedPushUseCase {
suspend fun execute(distributor: Distributor, clientSecret: String): Result<Unit> suspend fun execute(distributor: Distributor, clientSecret: String, sessionId: SessionId): Result<Unit>
} }
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
@@ -29,11 +30,11 @@ class DefaultRegisterUnifiedPushUseCase(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val endpointRegistrationHandler: EndpointRegistrationHandler, private val endpointRegistrationHandler: EndpointRegistrationHandler,
) : RegisterUnifiedPushUseCase { ) : RegisterUnifiedPushUseCase {
override suspend fun execute(distributor: Distributor, clientSecret: String): Result<Unit> { override suspend fun execute(distributor: Distributor, clientSecret: String, sessionId: SessionId): Result<Unit> {
UnifiedPush.saveDistributor(context, distributor.value) UnifiedPush.saveDistributor(context, distributor.value)
// This will trigger the callback // This will trigger the callback
// VectorUnifiedPushMessagingReceiver.onNewEndpoint // VectorUnifiedPushMessagingReceiver.onNewEndpoint
UnifiedPush.register(context = context, instance = clientSecret) UnifiedPush.register(context = context, instance = clientSecret, messageForDistributor = sessionId.value)
// Wait for VectorUnifiedPushMessagingReceiver.onNewEndpoint to proceed // Wait for VectorUnifiedPushMessagingReceiver.onNewEndpoint to proceed
@Suppress("RunCatchingNotAllowed") @Suppress("RunCatchingNotAllowed")
return runCatching { return runCatching {
@@ -36,7 +36,7 @@ class UnifiedPushProvider(
override suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor): Result<Unit> { override suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor): Result<Unit> {
val clientSecret = pushClientSecret.getSecretForUser(matrixClient.sessionId) val clientSecret = pushClientSecret.getSecretForUser(matrixClient.sessionId)
return registerUnifiedPushUseCase.execute(distributor, clientSecret) return registerUnifiedPushUseCase.execute(distributor, clientSecret, matrixClient.sessionId)
.onSuccess { .onSuccess {
unifiedPushStore.setDistributorValue(matrixClient.sessionId, distributor.value) unifiedPushStore.setDistributorValue(matrixClient.sessionId, distributor.value)
} }
@@ -12,6 +12,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.test.AN_EXCEPTION 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_SECRET
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler
import io.element.android.libraries.pushproviders.unifiedpush.registration.RegistrationResult import io.element.android.libraries.pushproviders.unifiedpush.registration.RegistrationResult
@@ -41,7 +42,7 @@ class DefaultRegisterUnifiedPushUseCaseTest : RobolectricTest() {
delay(100) delay(100)
endpointRegistrationHandler.registrationDone(RegistrationResult(A_SECRET, Result.success(Unit))) endpointRegistrationHandler.registrationDone(RegistrationResult(A_SECRET, Result.success(Unit)))
} }
val result = useCase.execute(aDistributor, A_SECRET) val result = useCase.execute(aDistributor, A_SECRET, A_SESSION_ID)
assertThat(result.isSuccess).isTrue() assertThat(result.isSuccess).isTrue()
} }
@@ -56,7 +57,7 @@ class DefaultRegisterUnifiedPushUseCaseTest : RobolectricTest() {
delay(100) delay(100)
endpointRegistrationHandler.registrationDone(RegistrationResult(A_SECRET, Result.failure(AN_EXCEPTION))) endpointRegistrationHandler.registrationDone(RegistrationResult(A_SECRET, Result.failure(AN_EXCEPTION)))
} }
val result = useCase.execute(aDistributor, A_SECRET) val result = useCase.execute(aDistributor, A_SECRET, A_SESSION_ID)
assertThat(result.isSuccess).isFalse() assertThat(result.isSuccess).isFalse()
} }
@@ -67,7 +68,7 @@ class DefaultRegisterUnifiedPushUseCaseTest : RobolectricTest() {
endpointRegistrationHandler = endpointRegistrationHandler endpointRegistrationHandler = endpointRegistrationHandler
) )
val aDistributor = Distributor("aValue", "aName") val aDistributor = Distributor("aValue", "aName")
val result = useCase.execute(aDistributor, A_SECRET) val result = useCase.execute(aDistributor, A_SECRET, A_SESSION_ID)
assertThat(result.isSuccess).isFalse() assertThat(result.isSuccess).isFalse()
} }
@@ -8,13 +8,14 @@
package io.element.android.libraries.pushproviders.unifiedpush package io.element.android.libraries.pushproviders.unifiedpush
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaError
class FakeRegisterUnifiedPushUseCase( class FakeRegisterUnifiedPushUseCase(
private val result: (Distributor, String) -> Result<Unit> = { _, _ -> lambdaError() } private val result: (Distributor, String, SessionId) -> Result<Unit> = { _, _, _ -> lambdaError() }
) : RegisterUnifiedPushUseCase { ) : RegisterUnifiedPushUseCase {
override suspend fun execute(distributor: Distributor, clientSecret: String): Result<Unit> { override suspend fun execute(distributor: Distributor, clientSecret: String, sessionId: SessionId): Result<Unit> {
return result(distributor, clientSecret) return result(distributor, clientSecret, sessionId)
} }
} }
@@ -62,7 +62,7 @@ class UnifiedPushProviderTest {
@Test @Test
fun `register ok`() = runTest { fun `register ok`() = runTest {
val getSecretForUserResultLambda = lambdaRecorder<SessionId, String> { A_SECRET } val getSecretForUserResultLambda = lambdaRecorder<SessionId, String> { A_SECRET }
val executeLambda = lambdaRecorder<Distributor, String, Result<Unit>> { _, _ -> Result.success(Unit) } val executeLambda = lambdaRecorder<Distributor, String, SessionId, Result<Unit>> { _, _, _ -> Result.success(Unit) }
val setDistributorValueResultLambda = lambdaRecorder<UserId, String, Unit> { _, _ -> } val setDistributorValueResultLambda = lambdaRecorder<UserId, String, Unit> { _, _ -> }
val unifiedPushProvider = createUnifiedPushProvider( val unifiedPushProvider = createUnifiedPushProvider(
pushClientSecret = FakePushClientSecret( pushClientSecret = FakePushClientSecret(
@@ -82,7 +82,7 @@ class UnifiedPushProviderTest {
.with(value(A_SESSION_ID)) .with(value(A_SESSION_ID))
executeLambda.assertions() executeLambda.assertions()
.isCalledOnce() .isCalledOnce()
.with(value(Distributor("value", "Name")), value(A_SECRET)) .with(value(Distributor("value", "Name")), value(A_SECRET), value(A_SESSION_ID))
setDistributorValueResultLambda.assertions() setDistributorValueResultLambda.assertions()
.isCalledOnce() .isCalledOnce()
.with(value(A_SESSION_ID), value("value")) .with(value(A_SESSION_ID), value("value"))
@@ -91,7 +91,7 @@ class UnifiedPushProviderTest {
@Test @Test
fun `register ko`() = runTest { fun `register ko`() = runTest {
val getSecretForUserResultLambda = lambdaRecorder<SessionId, String> { A_SECRET } val getSecretForUserResultLambda = lambdaRecorder<SessionId, String> { A_SECRET }
val executeLambda = lambdaRecorder<Distributor, String, Result<Unit>> { _, _ -> Result.failure(AN_EXCEPTION) } val executeLambda = lambdaRecorder<Distributor, String, SessionId, Result<Unit>> { _, _, _ -> Result.failure(AN_EXCEPTION) }
val setDistributorValueResultLambda = lambdaRecorder<UserId, String, Unit>(ensureNeverCalled = true) { _, _ -> } val setDistributorValueResultLambda = lambdaRecorder<UserId, String, Unit>(ensureNeverCalled = true) { _, _ -> }
val unifiedPushProvider = createUnifiedPushProvider( val unifiedPushProvider = createUnifiedPushProvider(
pushClientSecret = FakePushClientSecret( pushClientSecret = FakePushClientSecret(
@@ -111,7 +111,7 @@ class UnifiedPushProviderTest {
.with(value(A_SESSION_ID)) .with(value(A_SESSION_ID))
executeLambda.assertions() executeLambda.assertions()
.isCalledOnce() .isCalledOnce()
.with(value(Distributor("value", "Name")), value(A_SECRET)) .with(value(Distributor("value", "Name")), value(A_SECRET), value(A_SESSION_ID))
} }
@Test @Test