Skip to content

Commit

Permalink
fix: read receipts are not sent when the app is in background
Browse files Browse the repository at this point in the history
  • Loading branch information
ohassine committed Oct 8, 2024
1 parent 752c124 commit 257d19b
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,18 @@ class UpdateConversationReadDateUseCase internal constructor(
* @param conversationId The conversation id to update the last read date.
* @param time The last read date to update.
*/
operator fun invoke(conversationId: QualifiedID, time: Instant) {
workQueue.enqueue(ConversationTimeEventInput(conversationId, time), worker)
operator fun invoke(
conversationId: QualifiedID,
time: Instant,
shouldWaitUntilLive: Boolean = true
) {
workQueue.enqueue(
ConversationTimeEventInput(conversationId, time, shouldWaitUntilLive),
worker
)
}

private val worker = ConversationTimeEventWorker { (conversationId, time) ->
private val worker = ConversationTimeEventWorker { (conversationId, time, shouldWaitUntilLive) ->
coroutineScope {
conversationRepository.observeConversationById(conversationId).first().onFailure {
logger.w("Failed to update conversation read date; StorageFailure $it")
Expand All @@ -82,7 +89,7 @@ class UpdateConversationReadDateUseCase internal constructor(
return@onSuccess
}
launch {
sendConfirmation(conversationId, conversation.lastReadDate, time)
sendConfirmation(conversationId, conversation.lastReadDate, time, shouldWaitUntilLive)
}
launch {
conversationRepository.updateConversationReadDate(conversationId, time)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import kotlinx.datetime.Instant
*/
internal data class ConversationTimeEventInput(
val conversationId: ConversationId,
val eventTime: Instant
val eventTime: Instant,
val shouldWaitUntilLive: Boolean
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ internal interface SendConfirmationUseCase {
suspend operator fun invoke(
conversationId: ConversationId,
afterDateTime: Instant,
untilDateTime: Instant
untilDateTime: Instant,
shouldWaitUntilLive: Boolean = true
): Either<CoreFailure, Unit>
}

Expand All @@ -81,9 +82,12 @@ internal fun SendConfirmationUseCase(
override suspend operator fun invoke(
conversationId: ConversationId,
afterDateTime: Instant,
untilDateTime: Instant
untilDateTime: Instant,
shouldWaitUntilLive: Boolean
): Either<CoreFailure, Unit> {
syncManager.waitUntilLive()
if (shouldWaitUntilLive) {
syncManager.waitUntilLive()
}

val messageIds = getPendingUnreadMessagesIds(
conversationId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,6 @@ class ParallelConversationWorkQueueTest {
private fun workInput(
convIdValue: String = "abc",
time: Instant = Instant.DISTANT_PAST
) = ConversationTimeEventInput(ConversationId(convIdValue, "domain"), time)
) = ConversationTimeEventInput(ConversationId(convIdValue, "domain"), time, true)

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,37 @@ class SendConfirmationUseCaseTest {
val result = sendConfirmation(TestConversation.ID, after, until)

result.shouldSucceed()

coVerify {
arrangement.syncManager.waitUntilLive()
}.wasInvoked(exactly = once)

coVerify {
arrangement.messageSender.sendMessage(any(), any())
}.wasInvoked(exactly = once)
}

@Test
fun givenAShouldNotWaitUntilLive_whenSendingReadReceipts_theDoNotWaitForSyncAndSendConfirmation() = runTest {
val (arrangement, sendConfirmation) = Arrangement()
.withCurrentClientIdProvider()
.withGetConversationByIdSuccessful()
.withToggleReadReceiptsStatus(true)
.withPendingMessagesResponse()
.withSendMessageSuccess()
.arrange()

val after = Instant.DISTANT_PAST
val until = after + 10.seconds

val result = sendConfirmation(TestConversation.ID, after, until, false)

result.shouldSucceed()

coVerify {
arrangement.syncManager.waitUntilLive()
}.wasNotInvoked()

coVerify {
arrangement.messageSender.sendMessage(any(), any())
}.wasInvoked(exactly = once)
Expand Down Expand Up @@ -101,7 +132,7 @@ class SendConfirmationUseCaseTest {
private val currentClientIdProvider = mock(CurrentClientIdProvider::class)

@Mock
private val syncManager = mock(SyncManager::class)
val syncManager = mock(SyncManager::class)

@Mock
val messageSender = mock(MessageSender::class)
Expand Down

0 comments on commit 257d19b

Please sign in to comment.