diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/UpdateConversationReadDateUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/UpdateConversationReadDateUseCase.kt index 504caab6eb0..d2a9ceb5442 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/UpdateConversationReadDateUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/UpdateConversationReadDateUseCase.kt @@ -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") @@ -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) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/ConversationTimeEventWork.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/ConversationTimeEventWork.kt index 23e620e9e7b..ad2271fd4a3 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/ConversationTimeEventWork.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/ConversationTimeEventWork.kt @@ -27,7 +27,8 @@ import kotlinx.datetime.Instant */ internal data class ConversationTimeEventInput( val conversationId: ConversationId, - val eventTime: Instant + val eventTime: Instant, + val shouldWaitUntilLive: Boolean ) /** diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCase.kt index 87826d27049..be4ff16dd2c 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCase.kt @@ -57,7 +57,8 @@ internal interface SendConfirmationUseCase { suspend operator fun invoke( conversationId: ConversationId, afterDateTime: Instant, - untilDateTime: Instant + untilDateTime: Instant, + shouldWaitUntilLive: Boolean = true ): Either } @@ -81,9 +82,12 @@ internal fun SendConfirmationUseCase( override suspend operator fun invoke( conversationId: ConversationId, afterDateTime: Instant, - untilDateTime: Instant + untilDateTime: Instant, + shouldWaitUntilLive: Boolean ): Either { - syncManager.waitUntilLive() + if (shouldWaitUntilLive) { + syncManager.waitUntilLive() + } val messageIds = getPendingUnreadMessagesIds( conversationId, diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/ParallelConversationWorkQueueTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/ParallelConversationWorkQueueTest.kt index 3914065aadc..24bc6eae648 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/ParallelConversationWorkQueueTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/ParallelConversationWorkQueueTest.kt @@ -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) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCaseTest.kt index 2553d1ce58d..ac6ec74da19 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/receipt/SendConfirmationUseCaseTest.kt @@ -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) @@ -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)