Keep call notification ringing while a call is present in the room (#4634)
This commit is contained in:
parent
3391e7cc55
commit
c39b480f82
5 changed files with 217 additions and 99 deletions
|
|
@ -9,16 +9,22 @@ package io.element.android.libraries.push.impl.notifications
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
|
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.matrix.api.notification.CallNotifyType
|
||||||
import io.element.android.libraries.matrix.api.notification.NotificationContent
|
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.NotificationData
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventType
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventType
|
||||||
import io.element.android.libraries.push.impl.R
|
import io.element.android.libraries.push.impl.R
|
||||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
|
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.NotifiableRingingCallEvent
|
||||||
|
import io.element.android.services.appnavstate.api.AppForegroundStateService
|
||||||
import io.element.android.services.toolbox.api.strings.StringProvider
|
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||||
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to resolve a valid [NotifiableEvent] from a [NotificationData].
|
* Helper to resolve a valid [NotifiableEvent] from a [NotificationData].
|
||||||
|
|
@ -31,7 +37,7 @@ interface CallNotificationEventResolver {
|
||||||
* @param forceNotify `true` to force the notification to be non-ringing, `false` to use the default behaviour. Default is `false`.
|
* @param forceNotify `true` to force the notification to be non-ringing, `false` to use the default behaviour. Default is `false`.
|
||||||
* @return a [NotifiableEvent] if the notification data is a call notification, null otherwise
|
* @return a [NotifiableEvent] if the notification data is a call notification, null otherwise
|
||||||
*/
|
*/
|
||||||
fun resolveEvent(
|
suspend fun resolveEvent(
|
||||||
sessionId: SessionId,
|
sessionId: SessionId,
|
||||||
notificationData: NotificationData,
|
notificationData: NotificationData,
|
||||||
forceNotify: Boolean = false,
|
forceNotify: Boolean = false,
|
||||||
|
|
@ -41,8 +47,10 @@ interface CallNotificationEventResolver {
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultCallNotificationEventResolver @Inject constructor(
|
class DefaultCallNotificationEventResolver @Inject constructor(
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
|
private val appForegroundStateService: AppForegroundStateService,
|
||||||
|
private val clientProvider: MatrixClientProvider,
|
||||||
) : CallNotificationEventResolver {
|
) : CallNotificationEventResolver {
|
||||||
override fun resolveEvent(
|
override suspend fun resolveEvent(
|
||||||
sessionId: SessionId,
|
sessionId: SessionId,
|
||||||
notificationData: NotificationData,
|
notificationData: NotificationData,
|
||||||
forceNotify: Boolean
|
forceNotify: Boolean
|
||||||
|
|
@ -50,8 +58,32 @@ class DefaultCallNotificationEventResolver @Inject constructor(
|
||||||
val content = notificationData.content as? NotificationContent.MessageLike.CallNotify
|
val content = notificationData.content as? NotificationContent.MessageLike.CallNotify
|
||||||
?: throw ResolvingException("content is not a call notify")
|
?: throw ResolvingException("content is not a call notify")
|
||||||
|
|
||||||
|
val previousRingingCallStatus = appForegroundStateService.hasRingingCall.value
|
||||||
|
// We need the sync service working to get the updated room info
|
||||||
|
val isRoomCallActive = runCatching {
|
||||||
|
if (content.type == CallNotifyType.RING) {
|
||||||
|
appForegroundStateService.updateHasRingingCall(true)
|
||||||
|
|
||||||
|
val client = clientProvider.getOrRestore(sessionId).getOrNull() ?: throw ResolvingException("Session $sessionId not found")
|
||||||
|
val room = client.getRoom(notificationData.roomId) ?: throw ResolvingException("Room ${notificationData.roomId} not found")
|
||||||
|
// Give a few seconds for the room info flow to catch up with the sync, if needed - this is usually instant
|
||||||
|
val isActive = withTimeoutOrNull(3.seconds) { room.roomInfoFlow.firstOrNull { it.hasRoomCall } }?.hasRoomCall ?: false
|
||||||
|
|
||||||
|
// We no longer need the sync service to be active because of a call notification.
|
||||||
|
appForegroundStateService.updateHasRingingCall(previousRingingCallStatus)
|
||||||
|
|
||||||
|
isActive
|
||||||
|
} else {
|
||||||
|
// If the call notification is not of ringing type, we don't need to check if the call is active
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
// Make sure to reset the hasRingingCall state in case of failure
|
||||||
|
appForegroundStateService.updateHasRingingCall(previousRingingCallStatus)
|
||||||
|
}.getOrDefault(false)
|
||||||
|
|
||||||
notificationData.run {
|
notificationData.run {
|
||||||
if (NotifiableRingingCallEvent.shouldRing(content.type, timestamp) && !forceNotify) {
|
if (content.type == CallNotifyType.RING && isRoomCallActive && !forceNotify) {
|
||||||
NotifiableRingingCallEvent(
|
NotifiableRingingCallEvent(
|
||||||
sessionId = sessionId,
|
sessionId = sessionId,
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
|
|
@ -70,9 +102,7 @@ class DefaultCallNotificationEventResolver @Inject constructor(
|
||||||
senderAvatarUrl = senderAvatarUrl,
|
senderAvatarUrl = senderAvatarUrl,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val now = System.currentTimeMillis()
|
Timber.d("Event $eventId is call notify but should not ring: $isRoomCallActive, notify: ${content.type}")
|
||||||
val elapsed = now - timestamp
|
|
||||||
Timber.d("Event $eventId is call notify but should not ring: $timestamp vs $now ($elapsed ms elapsed), notify: ${content.type}")
|
|
||||||
// Create a simple message notification event
|
// Create a simple message notification event
|
||||||
buildNotifiableMessageEvent(
|
buildNotifiableMessageEvent(
|
||||||
sessionId = sessionId,
|
sessionId = sessionId,
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ 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.core.SessionId
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.notification.CallNotifyType
|
import io.element.android.libraries.matrix.api.notification.CallNotifyType
|
||||||
import java.time.Instant
|
|
||||||
import kotlin.time.Duration.Companion.seconds
|
|
||||||
|
|
||||||
data class NotifiableRingingCallEvent(
|
data class NotifiableRingingCallEvent(
|
||||||
override val sessionId: SessionId,
|
override val sessionId: SessionId,
|
||||||
|
|
@ -31,13 +29,4 @@ data class NotifiableRingingCallEvent(
|
||||||
val roomAvatarUrl: String? = null,
|
val roomAvatarUrl: String? = null,
|
||||||
val callNotifyType: CallNotifyType,
|
val callNotifyType: CallNotifyType,
|
||||||
val timestamp: Long,
|
val timestamp: Long,
|
||||||
) : NotifiableEvent {
|
) : NotifiableEvent
|
||||||
companion object {
|
|
||||||
fun shouldRing(callNotifyType: CallNotifyType, timestamp: Long): Boolean {
|
|
||||||
val timeout = 10.seconds.inWholeMilliseconds
|
|
||||||
val elapsed = Instant.now().toEpochMilli() - timestamp
|
|
||||||
// Only ring if the type is RING and the elapsed time is less than the timeout
|
|
||||||
return callNotifyType == CallNotifyType.RING && elapsed < timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.push.impl.notifications
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.matrix.api.notification.CallNotifyType
|
||||||
|
import io.element.android.libraries.matrix.api.notification.NotificationContent
|
||||||
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
|
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||||
|
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.libraries.matrix.test.A_USER_NAME_2
|
||||||
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
|
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
|
||||||
|
import io.element.android.libraries.matrix.test.notification.aNotificationData
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.room.aRoomInfo
|
||||||
|
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
|
||||||
|
import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent
|
||||||
|
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
|
||||||
|
import io.element.android.services.toolbox.test.strings.FakeStringProvider
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class DefaultCallNotificationEventResolverTest {
|
||||||
|
@Test
|
||||||
|
fun `resolve CallNotify - RING when call is still ongoing`() = runTest {
|
||||||
|
val room = FakeJoinedRoom(
|
||||||
|
baseRoom = FakeBaseRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
// The call is still ongoing
|
||||||
|
initialRoomInfo = aRoomInfo(hasRoomCall = true),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val client = FakeMatrixClient().apply {
|
||||||
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolver = createDefaultNotifiableEventResolver(
|
||||||
|
clientProvider = FakeMatrixClientProvider(getClient = { Result.success(client) }),
|
||||||
|
)
|
||||||
|
val expectedResult = NotifiableRingingCallEvent(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
eventId = AN_EVENT_ID,
|
||||||
|
senderId = A_USER_ID_2,
|
||||||
|
roomName = A_ROOM_NAME,
|
||||||
|
editedEventId = null,
|
||||||
|
description = "📹 Incoming call",
|
||||||
|
timestamp = 567L,
|
||||||
|
canBeReplaced = true,
|
||||||
|
isRedacted = false,
|
||||||
|
isUpdated = false,
|
||||||
|
senderDisambiguatedDisplayName = A_USER_NAME_2,
|
||||||
|
senderAvatarUrl = null,
|
||||||
|
callNotifyType = CallNotifyType.RING,
|
||||||
|
)
|
||||||
|
|
||||||
|
val notificationData = aNotificationData(
|
||||||
|
content = NotificationContent.MessageLike.CallNotify(A_USER_ID_2, CallNotifyType.RING)
|
||||||
|
)
|
||||||
|
val result = resolver.resolveEvent(A_SESSION_ID, notificationData)
|
||||||
|
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `resolve CallNotify - NOTIFY`() = runTest {
|
||||||
|
val room = FakeJoinedRoom(
|
||||||
|
baseRoom = FakeBaseRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
// The call already ended
|
||||||
|
initialRoomInfo = aRoomInfo(hasRoomCall = true),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val client = FakeMatrixClient().apply {
|
||||||
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolver = createDefaultNotifiableEventResolver(
|
||||||
|
clientProvider = FakeMatrixClientProvider(getClient = { Result.success(client) }),
|
||||||
|
)
|
||||||
|
val expectedResult = NotifiableMessageEvent(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
eventId = AN_EVENT_ID,
|
||||||
|
senderId = A_USER_ID_2,
|
||||||
|
roomName = A_ROOM_NAME,
|
||||||
|
editedEventId = null,
|
||||||
|
body = "📹 Incoming call",
|
||||||
|
timestamp = 567L,
|
||||||
|
canBeReplaced = false,
|
||||||
|
isRedacted = false,
|
||||||
|
isUpdated = false,
|
||||||
|
senderDisambiguatedDisplayName = A_USER_NAME_2,
|
||||||
|
noisy = true,
|
||||||
|
imageUriString = null,
|
||||||
|
imageMimeType = null,
|
||||||
|
threadId = null,
|
||||||
|
type = "m.call.notify",
|
||||||
|
)
|
||||||
|
|
||||||
|
val notificationData = aNotificationData(
|
||||||
|
content = NotificationContent.MessageLike.CallNotify(A_USER_ID_2, CallNotifyType.NOTIFY)
|
||||||
|
)
|
||||||
|
val result = resolver.resolveEvent(A_SESSION_ID, notificationData)
|
||||||
|
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `resolve CallNotify - RING but timed out displays the same as NOTIFY`() = runTest {
|
||||||
|
val room = FakeJoinedRoom(
|
||||||
|
baseRoom = FakeBaseRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
// The call already ended
|
||||||
|
initialRoomInfo = aRoomInfo(hasRoomCall = false),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val client = FakeMatrixClient().apply {
|
||||||
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolver = createDefaultNotifiableEventResolver(
|
||||||
|
clientProvider = FakeMatrixClientProvider(getClient = { Result.success(client) }),
|
||||||
|
)
|
||||||
|
val expectedResult = NotifiableMessageEvent(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
eventId = AN_EVENT_ID,
|
||||||
|
senderId = A_USER_ID_2,
|
||||||
|
roomName = A_ROOM_NAME,
|
||||||
|
editedEventId = null,
|
||||||
|
body = "📹 Incoming call",
|
||||||
|
timestamp = 567L,
|
||||||
|
canBeReplaced = false,
|
||||||
|
isRedacted = false,
|
||||||
|
isUpdated = false,
|
||||||
|
senderDisambiguatedDisplayName = A_USER_NAME_2,
|
||||||
|
noisy = true,
|
||||||
|
imageUriString = null,
|
||||||
|
imageMimeType = null,
|
||||||
|
threadId = null,
|
||||||
|
type = "m.call.notify",
|
||||||
|
)
|
||||||
|
|
||||||
|
val notificationData = aNotificationData(
|
||||||
|
content = NotificationContent.MessageLike.CallNotify(A_USER_ID_2, CallNotifyType.RING)
|
||||||
|
)
|
||||||
|
val result = resolver.resolveEvent(A_SESSION_ID, notificationData)
|
||||||
|
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDefaultNotifiableEventResolver(
|
||||||
|
stringProvider: FakeStringProvider = FakeStringProvider(defaultResult = "\uD83D\uDCF9 Incoming call"),
|
||||||
|
appForegroundStateService: FakeAppForegroundStateService = FakeAppForegroundStateService(),
|
||||||
|
clientProvider: FakeMatrixClientProvider = FakeMatrixClientProvider(),
|
||||||
|
) = DefaultCallNotificationEventResolver(
|
||||||
|
stringProvider = stringProvider,
|
||||||
|
appForegroundStateService = appForegroundStateService,
|
||||||
|
clientProvider = clientProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -49,10 +49,9 @@ import io.element.android.libraries.push.impl.notifications.fixtures.aNotifiable
|
||||||
import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
|
import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
|
||||||
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
||||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
|
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
|
||||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent
|
|
||||||
import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent
|
import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent
|
||||||
|
import io.element.android.libraries.push.test.notifications.FakeCallNotificationEventResolver
|
||||||
import io.element.android.services.toolbox.impl.strings.AndroidStringProvider
|
import io.element.android.services.toolbox.impl.strings.AndroidStringProvider
|
||||||
import io.element.android.services.toolbox.impl.systemclock.DefaultSystemClock
|
|
||||||
import io.element.android.services.toolbox.test.systemclock.A_FAKE_TIMESTAMP
|
import io.element.android.services.toolbox.test.systemclock.A_FAKE_TIMESTAMP
|
||||||
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
|
@ -606,80 +605,8 @@ class DefaultNotifiableEventResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `resolve CallNotify - ringing`() = runTest {
|
fun `resolve CallNotify - goes through CallNotificationEventResolver`() = runTest {
|
||||||
val timestamp = DefaultSystemClock().epochMillis()
|
val callNotificationEventResolver = FakeCallNotificationEventResolver()
|
||||||
val sut = createDefaultNotifiableEventResolver(
|
|
||||||
notificationResult = Result.success(
|
|
||||||
aNotificationData(
|
|
||||||
content = NotificationContent.MessageLike.CallNotify(
|
|
||||||
A_USER_ID_2,
|
|
||||||
CallNotifyType.RING
|
|
||||||
),
|
|
||||||
timestamp = timestamp,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
val expectedResult = ResolvedPushEvent.Event(
|
|
||||||
NotifiableRingingCallEvent(
|
|
||||||
sessionId = A_SESSION_ID,
|
|
||||||
roomId = A_ROOM_ID,
|
|
||||||
eventId = AN_EVENT_ID,
|
|
||||||
senderId = A_USER_ID_2,
|
|
||||||
roomName = A_ROOM_NAME,
|
|
||||||
editedEventId = null,
|
|
||||||
description = "📹 Incoming call",
|
|
||||||
timestamp = timestamp,
|
|
||||||
canBeReplaced = true,
|
|
||||||
isRedacted = false,
|
|
||||||
isUpdated = false,
|
|
||||||
senderDisambiguatedDisplayName = A_USER_NAME_2,
|
|
||||||
senderAvatarUrl = null,
|
|
||||||
callNotifyType = CallNotifyType.RING,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID)
|
|
||||||
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `resolve CallNotify - ring but timed out displays the same as notify`() = runTest {
|
|
||||||
val sut = createDefaultNotifiableEventResolver(
|
|
||||||
notificationResult = Result.success(
|
|
||||||
aNotificationData(
|
|
||||||
content = NotificationContent.MessageLike.CallNotify(
|
|
||||||
A_USER_ID_2,
|
|
||||||
CallNotifyType.RING
|
|
||||||
),
|
|
||||||
timestamp = 0L,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
val expectedResult = ResolvedPushEvent.Event(
|
|
||||||
NotifiableMessageEvent(
|
|
||||||
sessionId = A_SESSION_ID,
|
|
||||||
eventId = AN_EVENT_ID,
|
|
||||||
editedEventId = null,
|
|
||||||
noisy = true,
|
|
||||||
timestamp = 0L,
|
|
||||||
senderDisambiguatedDisplayName = A_USER_NAME_2,
|
|
||||||
senderId = A_USER_ID_2,
|
|
||||||
body = "📹 Incoming call",
|
|
||||||
roomId = A_ROOM_ID,
|
|
||||||
threadId = null,
|
|
||||||
roomName = A_ROOM_NAME,
|
|
||||||
canBeReplaced = false,
|
|
||||||
isRedacted = false,
|
|
||||||
imageUriString = null,
|
|
||||||
imageMimeType = null,
|
|
||||||
type = EventType.CALL_NOTIFY,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID)
|
|
||||||
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `resolve CallNotify - notify`() = runTest {
|
|
||||||
val sut = createDefaultNotifiableEventResolver(
|
val sut = createDefaultNotifiableEventResolver(
|
||||||
notificationResult = Result.success(
|
notificationResult = Result.success(
|
||||||
aNotificationData(
|
aNotificationData(
|
||||||
|
|
@ -688,7 +615,8 @@ class DefaultNotifiableEventResolverTest {
|
||||||
CallNotifyType.NOTIFY
|
CallNotifyType.NOTIFY
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
callNotificationEventResolver = callNotificationEventResolver,
|
||||||
)
|
)
|
||||||
val expectedResult = ResolvedPushEvent.Event(
|
val expectedResult = ResolvedPushEvent.Event(
|
||||||
NotifiableMessageEvent(
|
NotifiableMessageEvent(
|
||||||
|
|
@ -710,6 +638,7 @@ class DefaultNotifiableEventResolverTest {
|
||||||
type = EventType.CALL_NOTIFY,
|
type = EventType.CALL_NOTIFY,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
callNotificationEventResolver.resolveEventLambda = { _, _, _ -> Result.success(expectedResult.notifiableEvent) }
|
||||||
val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID)
|
val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID)
|
||||||
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
assertThat(result.getOrNull()).isEqualTo(expectedResult)
|
||||||
}
|
}
|
||||||
|
|
@ -804,6 +733,7 @@ class DefaultNotifiableEventResolverTest {
|
||||||
notificationService: FakeNotificationService? = FakeNotificationService(),
|
notificationService: FakeNotificationService? = FakeNotificationService(),
|
||||||
notificationResult: Result<NotificationData?> = Result.success(null),
|
notificationResult: Result<NotificationData?> = Result.success(null),
|
||||||
appPreferencesStore: AppPreferencesStore = InMemoryAppPreferencesStore(),
|
appPreferencesStore: AppPreferencesStore = InMemoryAppPreferencesStore(),
|
||||||
|
callNotificationEventResolver: FakeCallNotificationEventResolver = FakeCallNotificationEventResolver(),
|
||||||
): DefaultNotifiableEventResolver {
|
): DefaultNotifiableEventResolver {
|
||||||
val context = RuntimeEnvironment.getApplication() as Context
|
val context = RuntimeEnvironment.getApplication() as Context
|
||||||
notificationService?.givenGetNotificationResult(notificationResult)
|
notificationService?.givenGetNotificationResult(notificationResult)
|
||||||
|
|
@ -824,9 +754,7 @@ class DefaultNotifiableEventResolverTest {
|
||||||
notificationMediaRepoFactory = notificationMediaRepoFactory,
|
notificationMediaRepoFactory = notificationMediaRepoFactory,
|
||||||
context = context,
|
context = context,
|
||||||
permalinkParser = FakePermalinkParser(),
|
permalinkParser = FakePermalinkParser(),
|
||||||
callNotificationEventResolver = DefaultCallNotificationEventResolver(
|
callNotificationEventResolver = callNotificationEventResolver,
|
||||||
stringProvider = AndroidStringProvider(context.resources)
|
|
||||||
),
|
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class FakeCallNotificationEventResolver(
|
||||||
lambdaError()
|
lambdaError()
|
||||||
},
|
},
|
||||||
) : CallNotificationEventResolver {
|
) : CallNotificationEventResolver {
|
||||||
override fun resolveEvent(sessionId: SessionId, notificationData: NotificationData, forceNotify: Boolean): Result<NotifiableEvent> {
|
override suspend fun resolveEvent(sessionId: SessionId, notificationData: NotificationData, forceNotify: Boolean): Result<NotifiableEvent> {
|
||||||
return resolveEventLambda(sessionId, notificationData, forceNotify)
|
return resolveEventLambda(sessionId, notificationData, forceNotify)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue