Add fallback notifications from UTDs to the push history (#5047)
This commit is contained in:
parent
d53457ec66
commit
7c982a30cb
7 changed files with 93 additions and 9 deletions
|
|
@ -236,7 +236,12 @@ class DefaultNotifiableEventResolver @Inject constructor(
|
|||
}
|
||||
NotificationContent.MessageLike.RoomEncrypted -> {
|
||||
Timber.tag(loggerTag.value).w("Notification with encrypted content -> fallback")
|
||||
val fallbackNotifiableEvent = fallbackNotificationFactory.create(userId, roomId, eventId)
|
||||
val fallbackNotifiableEvent = fallbackNotificationFactory.create(
|
||||
sessionId = userId,
|
||||
roomId = roomId,
|
||||
eventId = eventId,
|
||||
cause = "Unable to decrypt event content",
|
||||
)
|
||||
ResolvedPushEvent.Event(fallbackNotifiableEvent)
|
||||
}
|
||||
is NotificationContent.MessageLike.RoomRedaction -> {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class FallbackNotificationFactory @Inject constructor(
|
|||
sessionId: SessionId,
|
||||
roomId: RoomId,
|
||||
eventId: EventId,
|
||||
cause: String?,
|
||||
): FallbackNotifiableEvent = FallbackNotifiableEvent(
|
||||
sessionId = sessionId,
|
||||
roomId = roomId,
|
||||
|
|
@ -34,5 +35,6 @@ class FallbackNotificationFactory @Inject constructor(
|
|||
isUpdated = false,
|
||||
timestamp = clock.epochMillis(),
|
||||
description = stringProvider.getString(R.string.notification_fallback_content),
|
||||
cause = cause,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,4 +25,5 @@ data class FallbackNotifiableEvent(
|
|||
override val isRedacted: Boolean,
|
||||
override val isUpdated: Boolean,
|
||||
val timestamp: Long,
|
||||
val cause: String?,
|
||||
) : NotifiableEvent
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import io.element.android.libraries.push.impl.notifications.FallbackNotification
|
|||
import io.element.android.libraries.push.impl.notifications.NotificationEventRequest
|
||||
import io.element.android.libraries.push.impl.notifications.NotificationResolverQueue
|
||||
import io.element.android.libraries.push.impl.notifications.channels.NotificationChannels
|
||||
import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent
|
||||
|
|
@ -90,13 +91,23 @@ class DefaultPushHandler @Inject constructor(
|
|||
} else {
|
||||
result.fold(
|
||||
onSuccess = {
|
||||
pushHistoryService.onSuccess(
|
||||
providerInfo = request.providerInfo,
|
||||
eventId = request.eventId,
|
||||
roomId = request.roomId,
|
||||
sessionId = request.sessionId,
|
||||
comment = "Push handled successfully",
|
||||
)
|
||||
if (it is ResolvedPushEvent.Event && it.notifiableEvent is FallbackNotifiableEvent) {
|
||||
pushHistoryService.onUnableToResolveEvent(
|
||||
providerInfo = request.providerInfo,
|
||||
eventId = request.eventId,
|
||||
roomId = request.roomId,
|
||||
sessionId = request.sessionId,
|
||||
reason = it.notifiableEvent.cause.orEmpty(),
|
||||
)
|
||||
} else {
|
||||
pushHistoryService.onSuccess(
|
||||
providerInfo = request.providerInfo,
|
||||
eventId = request.eventId,
|
||||
roomId = request.roomId,
|
||||
sessionId = request.sessionId,
|
||||
comment = "Push handled successfully",
|
||||
)
|
||||
}
|
||||
},
|
||||
onFailure = { exception ->
|
||||
if (exception is NotificationResolverException.EventFilteredOut) {
|
||||
|
|
@ -140,7 +151,14 @@ class DefaultPushHandler @Inject constructor(
|
|||
}
|
||||
else -> {
|
||||
Timber.tag(loggerTag.value).e(exception, "Failed to resolve push event")
|
||||
ResolvedPushEvent.Event(fallbackNotificationFactory.create(request.sessionId, request.roomId, request.eventId))
|
||||
ResolvedPushEvent.Event(
|
||||
fallbackNotificationFactory.create(
|
||||
sessionId = request.sessionId,
|
||||
roomId = request.roomId,
|
||||
eventId = request.eventId,
|
||||
cause = exception.message,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}.getOrNull() ?: continue
|
||||
|
|
|
|||
|
|
@ -625,6 +625,7 @@ class DefaultNotifiableEventResolverTest {
|
|||
isRedacted = false,
|
||||
isUpdated = false,
|
||||
timestamp = A_FAKE_TIMESTAMP,
|
||||
cause = "Unable to decrypt event content",
|
||||
)
|
||||
)
|
||||
assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult))
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class DefaultNotificationCreatorTest {
|
|||
isRedacted = false,
|
||||
isUpdated = false,
|
||||
timestamp = A_FAKE_TIMESTAMP,
|
||||
cause = null,
|
||||
)
|
||||
)
|
||||
result.commonAssertions(
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
package io.element.android.libraries.push.impl.push
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.call.api.CallType
|
||||
import io.element.android.features.call.test.FakeElementCallEntryPoint
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
|
|
@ -38,6 +39,7 @@ import io.element.android.libraries.push.impl.notifications.NotificationResolver
|
|||
import io.element.android.libraries.push.impl.notifications.channels.FakeNotificationChannels
|
||||
import io.element.android.libraries.push.impl.notifications.fixtures.aNotifiableCallEvent
|
||||
import io.element.android.libraries.push.impl.notifications.fixtures.aNotifiableMessageEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent
|
||||
import io.element.android.libraries.push.impl.test.DefaultTestPush
|
||||
|
|
@ -65,6 +67,7 @@ import kotlin.time.Duration.Companion.milliseconds
|
|||
|
||||
private const val A_PUSHER_INFO = "info"
|
||||
|
||||
@Suppress("LargeClass")
|
||||
class DefaultPushHandlerTest {
|
||||
@Test
|
||||
fun `check handleInvalid behavior`() = runTest {
|
||||
|
|
@ -628,6 +631,59 @@ class DefaultPushHandlerTest {
|
|||
.isCalledExactly(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when receiving a fallback event, we notify the push history service about it not being resolved`() = runTest {
|
||||
val aNotifiableFallbackEvent = FallbackNotifiableEvent(
|
||||
sessionId = A_SESSION_ID,
|
||||
roomId = A_ROOM_ID,
|
||||
eventId = AN_EVENT_ID,
|
||||
editedEventId = null,
|
||||
description = "A fallback notification",
|
||||
canBeReplaced = false,
|
||||
isRedacted = false,
|
||||
isUpdated = false,
|
||||
timestamp = 0L,
|
||||
cause = "Unable to decrypt event",
|
||||
)
|
||||
val notifiableEventResult =
|
||||
lambdaRecorder<SessionId, List<NotificationEventRequest>, Result<Map<NotificationEventRequest, Result<ResolvedPushEvent>>>> { _, _ ->
|
||||
val request = NotificationEventRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, A_PUSHER_INFO)
|
||||
Result.success(mapOf(request to Result.success(ResolvedPushEvent.Event(aNotifiableFallbackEvent))))
|
||||
}
|
||||
val onNotifiableEventsReceived = lambdaRecorder<List<NotifiableEvent>, Unit> {}
|
||||
val incrementPushCounterResult = lambdaRecorder<Unit> {}
|
||||
var receivedFallbackEvent = false
|
||||
val onPushReceivedResult =
|
||||
lambdaRecorder<String, EventId?, RoomId?, SessionId?, Boolean, Boolean, String?, Unit> { _, _, _, _, isResolved, _, comment ->
|
||||
receivedFallbackEvent = !isResolved && comment == "Unable to resolve event: ${aNotifiableFallbackEvent.cause}"
|
||||
}
|
||||
val pushHistoryService = FakePushHistoryService(
|
||||
onPushReceivedResult = onPushReceivedResult,
|
||||
)
|
||||
val aPushData = PushData(
|
||||
eventId = AN_EVENT_ID,
|
||||
roomId = A_ROOM_ID,
|
||||
unread = 0,
|
||||
clientSecret = A_SECRET,
|
||||
)
|
||||
val defaultPushHandler = createDefaultPushHandler(
|
||||
onNotifiableEventsReceived = onNotifiableEventsReceived,
|
||||
notifiableEventsResult = notifiableEventResult,
|
||||
pushClientSecret = FakePushClientSecret(
|
||||
getUserIdFromSecretResult = { A_USER_ID }
|
||||
),
|
||||
incrementPushCounterResult = incrementPushCounterResult,
|
||||
pushHistoryService = pushHistoryService,
|
||||
)
|
||||
defaultPushHandler.handle(aPushData, A_PUSHER_INFO)
|
||||
|
||||
advanceTimeBy(300.milliseconds)
|
||||
|
||||
onNotifiableEventsReceived.assertions().isCalledOnce()
|
||||
|
||||
assertThat(receivedFallbackEvent).isTrue()
|
||||
}
|
||||
|
||||
private fun TestScope.createDefaultPushHandler(
|
||||
onNotifiableEventsReceived: (List<NotifiableEvent>) -> Unit = { lambdaError() },
|
||||
onRedactedEventsReceived: (List<ResolvedPushEvent.Redaction>) -> Unit = { lambdaError() },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue