Merge pull request #4889 from element-hq/feature/bma/genericNotification

Show generic notification when Event cannot be resolved
This commit is contained in:
Benoit Marty
2025-06-19 08:56:37 +02:00
committed by GitHub
17 changed files with 197 additions and 12 deletions

View File

@@ -12,6 +12,7 @@ import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.notification.NotificationContent
import io.element.android.libraries.matrix.api.notification.NotificationData
import io.element.android.libraries.matrix.api.notification.NotificationService
import io.element.android.services.toolbox.api.systemclock.SystemClock
@@ -24,7 +25,7 @@ class RustNotificationService(
private val sessionId: SessionId,
private val notificationClient: NotificationClient,
private val dispatchers: CoroutineDispatchers,
clock: SystemClock,
private val clock: SystemClock,
) : NotificationService {
private val notificationMapper: NotificationMapper = NotificationMapper(clock)
@@ -43,11 +44,32 @@ class RustNotificationService(
val eventIds = requests.flatMap { it.eventIds }
for (eventId in eventIds) {
val item = items[eventId]
val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!)
if (item != null) {
val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!)
put(EventId(eventId), notificationMapper.map(sessionId, EventId(eventId), roomId, item))
} else {
Timber.e("Could not retrieve event for notification with $eventId")
put(
EventId(eventId),
NotificationData(
sessionId = sessionId,
eventId = EventId(eventId),
threadId = null,
roomId = roomId,
senderAvatarUrl = null,
senderDisplayName = null,
senderIsNameAmbiguous = false,
roomAvatarUrl = null,
roomDisplayName = null,
isDirect = false,
isDm = false,
isEncrypted = false,
isNoisy = false,
timestamp = clock.epochMillis(),
content = NotificationContent.MessageLike.UnableToResolve,
hasMention = false
)
)
}
}
}

View File

@@ -14,8 +14,11 @@ import org.matrix.rustcomponents.sdk.NotificationItemsRequest
class FakeFfiNotificationClient(
var notificationItemResult: Map<String, NotificationItem> = emptyMap(),
val closeResult: () -> Unit = { }
) : NotificationClient(NoPointer) {
override suspend fun getNotifications(requests: List<NotificationItemsRequest>): Map<String, NotificationItem> {
return notificationItemResult
}
override fun close() = closeResult()
}

View File

@@ -19,6 +19,7 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.services.toolbox.api.systemclock.SystemClock
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -47,6 +48,33 @@ class RustNotificationServiceTest {
)
}
@Test
fun `test unable to resolve event`() = runTest {
val notificationClient = FakeFfiNotificationClient(
notificationItemResult = emptyMap(),
)
val sut = createRustNotificationService(
notificationClient = notificationClient,
)
val result = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!!
assertThat(result.content).isEqualTo(
NotificationContent.MessageLike.UnableToResolve
)
}
@Test
fun `close should invoke the close method of the service`() = runTest {
val closeResult = lambdaRecorder<Unit> { }
val notificationClient = FakeFfiNotificationClient(
closeResult = closeResult,
)
val sut = createRustNotificationService(
notificationClient = notificationClient,
)
sut.close()
closeResult.assertions().isCalledOnce()
}
private fun TestScope.createRustNotificationService(
notificationClient: NotificationClient = FakeFfiNotificationClient(),
clock: SystemClock = FakeSystemClock(),