From cd092cbda5b600022897522ce27c37a6596f4bb0 Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Thu, 22 Aug 2024 21:51:59 +0300 Subject: [PATCH 1/3] feat: Ask User for Call quality feedback --- .../configuration/UserConfigRepository.kt | 9 + .../kalium/logic/feature/call/CallsScope.kt | 21 ++- .../EndCallOnConversationChangeUseCase.kt | 2 +- .../call/usecase/EndCallResultListener.kt | 23 ++- .../feature/call/usecase/EndCallUseCase.kt | 4 + .../usecase/ObserveAskCallFeedbackUseCase.kt | 42 +++++ ...CallDueToConversationDegradationUseCase.kt | 5 +- .../user/ShouldAskCallFeedbackUseCase.kt | 46 +++++ .../user/UpdateNextTimeCallFeedbackUseCase.kt | 52 ++++++ .../EndCallOnConversationChangeUseCaseTest.kt | 2 +- .../call/usecase/EndCallUseCaseTest.kt | 157 +++++++++++------- .../feature/mlsmigration/MLSMigratorTest.kt | 2 +- .../user/ShouldAskCallFeedbackUseCaseTest.kt | 89 ++++++++++ .../UpdateNextTimeCallFeedbackUseCaseTest.kt | 68 ++++++++ .../ProtocolUpdateEventHandlerTest.kt | 4 +- .../arrangement/CallRepositoryArrangement.kt | 70 -------- .../repository/CallManagerArrangement.kt | 40 +++++ .../repository/CallRepositoryArrangement.kt | 51 +++++- .../UserConfigRepositoryArrangement.kt | 10 ++ .../persistence/dao/unread/UserConfigDAO.kt | 9 + 20 files changed, 562 insertions(+), 144 deletions(-) create mode 100644 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveAskCallFeedbackUseCase.kt create mode 100644 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCase.kt create mode 100644 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCase.kt create mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCaseTest.kt create mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCaseTest.kt delete mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/CallRepositoryArrangement.kt create mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallManagerArrangement.kt diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt index 51b0d969358..b49ac5926b6 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt @@ -144,6 +144,8 @@ interface UserConfigRepository { suspend fun setPreviousTrackingIdentifier(identifier: String) suspend fun getPreviousTrackingIdentifier(): String? suspend fun deletePreviousTrackingIdentifier() + suspend fun updateNextTimeForCallFeedback(valueMs: Long) + suspend fun getNextTimeForCallFeedback(): Either } @Suppress("TooManyFunctions") @@ -538,4 +540,11 @@ internal class UserConfigDataSource internal constructor( userConfigDAO.deletePreviousTrackingIdentifier() } } + + override suspend fun updateNextTimeForCallFeedback(valueMs: Long) { + userConfigDAO.setNextTimeForCallFeedback(valueMs) + } + + override suspend fun getNextTimeForCallFeedback() = wrapStorageRequest { userConfigDAO.getNextTimeForCallFeedback() } + } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt index 05fc2c1d16d..0e66db2b0b9 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt @@ -50,6 +50,7 @@ import com.wire.kalium.logic.feature.call.usecase.IsLastCallClosedUseCase import com.wire.kalium.logic.feature.call.usecase.IsLastCallClosedUseCaseImpl import com.wire.kalium.logic.feature.call.usecase.MuteCallUseCase import com.wire.kalium.logic.feature.call.usecase.MuteCallUseCaseImpl +import com.wire.kalium.logic.feature.call.usecase.ObserveAskCallFeedbackUseCase import com.wire.kalium.logic.feature.call.usecase.ObserveEndCallDueToConversationDegradationUseCase import com.wire.kalium.logic.feature.call.usecase.ObserveEndCallDueToConversationDegradationUseCaseImpl import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase @@ -74,6 +75,8 @@ import com.wire.kalium.logic.feature.call.usecase.UpdateConversationClientsForCu import com.wire.kalium.logic.feature.call.usecase.UpdateConversationClientsForCurrentCallUseCaseImpl import com.wire.kalium.logic.feature.call.usecase.video.SetVideoSendStateUseCase import com.wire.kalium.logic.feature.call.usecase.video.UpdateVideoStateUseCase +import com.wire.kalium.logic.feature.user.ShouldAskCallFeedbackUseCase +import com.wire.kalium.logic.feature.user.UpdateNextTimeCallFeedbackUseCase import com.wire.kalium.logic.featureFlags.KaliumConfigs import com.wire.kalium.logic.sync.SyncManager import com.wire.kalium.util.KaliumDispatcher @@ -145,7 +148,13 @@ class CallsScope internal constructor( kaliumConfigs ) - val endCall: EndCallUseCase get() = EndCallUseCaseImpl(callManager, callRepository, KaliumDispatcherImpl) + val endCall: EndCallUseCase + get() = EndCallUseCaseImpl( + callManager = callManager, + callRepository = callRepository, + endCallListener = EndCallResultListenerImpl, + shouldAskCallFeedbackUseCase = shouldAskCallFeedbackUseCase + ) val endCallOnConversationChange: EndCallOnConversationChangeUseCase get() = EndCallOnConversationChangeUseCaseImpl( @@ -198,6 +207,14 @@ class CallsScope internal constructor( val isEligibleToStartCall: IsEligibleToStartCallUseCase get() = IsEligibleToStartCallUseCaseImpl(userConfigRepository, callRepository) - val observeEndCallDialog: ObserveEndCallDueToConversationDegradationUseCase + val observeEndCallDueToDegradationDialog: ObserveEndCallDueToConversationDegradationUseCase get() = ObserveEndCallDueToConversationDegradationUseCaseImpl(EndCallResultListenerImpl) + val observeAskCallFeedbackUseCase: ObserveAskCallFeedbackUseCase + get() = ObserveAskCallFeedbackUseCase(EndCallResultListenerImpl) + + private val shouldAskCallFeedbackUseCase: ShouldAskCallFeedbackUseCase by lazy { ShouldAskCallFeedbackUseCase(userConfigRepository) } + + val updateNextTimeCallFeedback: UpdateNextTimeCallFeedbackUseCase by lazy { + UpdateNextTimeCallFeedbackUseCase(userConfigRepository) + } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCase.kt index 909af1c8c93..70bf1cdf9d1 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCase.kt @@ -105,7 +105,7 @@ internal class EndCallOnConversationChangeUseCaseImpl( } .filter { it.shouldFinishCall() } .map { - endCallListener.onCallEndedBecauseOfVerificationDegraded(conversationId) + endCallListener.onCallEndedBecauseOfVerificationDegraded() conversationId } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallResultListener.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallResultListener.kt index 9a529940580..a376b3fc4bd 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallResultListener.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallResultListener.kt @@ -17,13 +17,13 @@ */ package com.wire.kalium.logic.feature.call.usecase -import com.wire.kalium.logic.data.id.ConversationId import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow interface EndCallResultListener { - suspend fun observeCallEndedBecauseOfVerificationDegraded(): Flow - suspend fun onCallEndedBecauseOfVerificationDegraded(conversationId: ConversationId) + suspend fun observeCallEndedResult(): Flow + suspend fun onCallEndedBecauseOfVerificationDegraded() + suspend fun onCallEndedAskForFeedback(shouldAsk: Boolean) } /** @@ -31,11 +31,20 @@ interface EndCallResultListener { */ object EndCallResultListenerImpl : EndCallResultListener { - private val conversationCallEnded = MutableSharedFlow() + private val conversationCallEnded = MutableSharedFlow() - override suspend fun observeCallEndedBecauseOfVerificationDegraded(): Flow = conversationCallEnded + override suspend fun observeCallEndedResult(): Flow = conversationCallEnded - override suspend fun onCallEndedBecauseOfVerificationDegraded(conversationId: ConversationId) { - conversationCallEnded.emit(conversationId) + override suspend fun onCallEndedBecauseOfVerificationDegraded() { + conversationCallEnded.emit(EndCallResult.VerificationDegraded) } + + override suspend fun onCallEndedAskForFeedback(shouldAsk: Boolean) { + conversationCallEnded.emit(EndCallResult.AskForFeedback(shouldAsk)) + } +} + +sealed class EndCallResult { + data object VerificationDegraded : EndCallResult() + data class AskForFeedback(val shouldAsk: Boolean) : EndCallResult() } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt index e8e7541a317..f387575d590 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt @@ -24,6 +24,7 @@ import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.feature.call.CallManager import com.wire.kalium.logic.data.call.CallStatus +import com.wire.kalium.logic.feature.user.ShouldAskCallFeedbackUseCase import com.wire.kalium.util.KaliumDispatcher import com.wire.kalium.util.KaliumDispatcherImpl import kotlinx.coroutines.flow.first @@ -46,6 +47,8 @@ interface EndCallUseCase { internal class EndCallUseCaseImpl( private val callManager: Lazy, private val callRepository: CallRepository, + private val endCallListener: EndCallResultListener, + private val shouldAskCallFeedbackUseCase: ShouldAskCallFeedbackUseCase, private val dispatchers: KaliumDispatcher = KaliumDispatcherImpl ) : EndCallUseCase { @@ -73,5 +76,6 @@ internal class EndCallUseCaseImpl( callManager.value.endCall(conversationId) callRepository.updateIsCameraOnById(conversationId, false) + endCallListener.onCallEndedAskForFeedback(shouldAskCallFeedbackUseCase()) } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveAskCallFeedbackUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveAskCallFeedbackUseCase.kt new file mode 100644 index 00000000000..5c3e6915043 --- /dev/null +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveAskCallFeedbackUseCase.kt @@ -0,0 +1,42 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.call.usecase + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.map + +/** + * The useCase for observing when the ongoing call was ended because of degradation of conversation verification status (Proteus or MLS) + */ +interface ObserveAskCallFeedbackUseCase { + /** + * @return [Flow] that emits only when the call was ended because of degradation of conversation verification status (Proteus or MLS) + */ + suspend operator fun invoke(): Flow +} + +@Suppress("FunctionNaming") +internal fun ObserveAskCallFeedbackUseCase( + endCallListener: EndCallResultListener +) = object : ObserveAskCallFeedbackUseCase { + override suspend fun invoke(): Flow = + endCallListener.observeCallEndedResult() + .filterIsInstance(EndCallResult.AskForFeedback::class) + .map { it.shouldAsk } +} diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveEndCallDueToConversationDegradationUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveEndCallDueToConversationDegradationUseCase.kt index 830fbc562e2..80f83311945 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveEndCallDueToConversationDegradationUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/ObserveEndCallDueToConversationDegradationUseCase.kt @@ -18,6 +18,7 @@ package com.wire.kalium.logic.feature.call.usecase import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.map /** @@ -34,5 +35,7 @@ internal class ObserveEndCallDueToConversationDegradationUseCaseImpl( private val endCallListener: EndCallResultListener ) : ObserveEndCallDueToConversationDegradationUseCase { override suspend fun invoke(): Flow = - endCallListener.observeCallEndedBecauseOfVerificationDegraded().map { Unit } + endCallListener.observeCallEndedResult() + .filterIsInstance(EndCallResult.VerificationDegraded::class) + .map { Unit } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCase.kt new file mode 100644 index 00000000000..1e2538afe4d --- /dev/null +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCase.kt @@ -0,0 +1,46 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.user + +import com.wire.kalium.logic.configuration.UserConfigRepository +import com.wire.kalium.logic.functional.getOrElse +import com.wire.kalium.logic.functional.map +import com.wire.kalium.util.DateTimeUtil +import kotlinx.datetime.Instant + +/** + * Use case that returns [Boolean] if user should be asked for a feedback about call quality or not. + */ +interface ShouldAskCallFeedbackUseCase { + /** + * @return [Boolean] if user should be asked for a feedback about call quality or not. + */ + suspend operator fun invoke(): Boolean +} + +@Suppress("FunctionNaming") +internal fun ShouldAskCallFeedbackUseCase( + userConfigRepository: UserConfigRepository +) = object : ShouldAskCallFeedbackUseCase { + + override suspend fun invoke(): Boolean = + userConfigRepository.getNextTimeForCallFeedback().map { + it > 0L && DateTimeUtil.currentInstant() > Instant.fromEpochMilliseconds(it) + }.getOrElse(true) + +} diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCase.kt new file mode 100644 index 00000000000..e364ad5f49d --- /dev/null +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCase.kt @@ -0,0 +1,52 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.user + +import com.wire.kalium.logic.configuration.UserConfigRepository +import com.wire.kalium.logic.feature.user.UpdateNextTimeCallFeedbackUseCase.Companion.askingForFeedbackPeriod +import com.wire.kalium.util.DateTimeUtil +import kotlin.time.Duration.Companion.days + +/** + * Use case that updates next time when user should be asked for a feedback about call quality. + */ +interface UpdateNextTimeCallFeedbackUseCase { + /** + * Update next time when user should be asked for a feedback about call quality. + * @param neverAskAgain [Boolean] if user checked "never ask me again" + */ + suspend operator fun invoke(neverAskAgain: Boolean) + + companion object { + val askingForFeedbackPeriod = 3.days + } +} + +@Suppress("FunctionNaming") +internal fun UpdateNextTimeCallFeedbackUseCase( + userConfigRepository: UserConfigRepository +) = object : UpdateNextTimeCallFeedbackUseCase { + + override suspend fun invoke(neverAskAgain: Boolean) { + val nextTimestamp = if (neverAskAgain) -1L + else DateTimeUtil.currentInstant().plus(askingForFeedbackPeriod).toEpochMilliseconds() + + userConfigRepository.updateNextTimeForCallFeedback(nextTimestamp) + } + +} diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt index c059b7f02a1..d858391e5b2 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt @@ -176,7 +176,7 @@ class EndCallOnConversationChangeUseCaseTest { endCall.invoke(eq(conversationId)) }.returns(Unit) coEvery { - endCallDialogManager.onCallEndedBecauseOfVerificationDegraded(eq(conversationId)) + endCallDialogManager.onCallEndedBecauseOfVerificationDegraded() }.returns(Unit) withEstablishedCallsFlow(listOf(call)) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCaseTest.kt index 3e3d10c7c28..5e0c182068e 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCaseTest.kt @@ -19,68 +19,56 @@ package com.wire.kalium.logic.feature.call.usecase import com.wire.kalium.logic.data.call.Call -import com.wire.kalium.logic.data.call.CallRepository import com.wire.kalium.logic.data.call.CallStatus import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId -import com.wire.kalium.logic.feature.call.CallManager +import com.wire.kalium.logic.feature.user.ShouldAskCallFeedbackUseCase import com.wire.kalium.logic.test_util.TestKaliumDispatcher +import com.wire.kalium.logic.util.arrangement.repository.CallManagerArrangement +import com.wire.kalium.logic.util.arrangement.repository.CallManagerArrangementImpl +import com.wire.kalium.logic.util.arrangement.repository.CallRepositoryArrangement +import com.wire.kalium.logic.util.arrangement.repository.CallRepositoryArrangementImpl import io.mockative.Mock import io.mockative.any import io.mockative.coEvery import io.mockative.coVerify import io.mockative.doesNothing import io.mockative.eq -import io.mockative.every import io.mockative.mock import io.mockative.once import io.mockative.verify import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest -import kotlin.test.BeforeTest import kotlin.test.Test class EndCallUseCaseTest { - @Mock - private val callManager = mock(CallManager::class) - - @Mock - private val callRepository = mock(CallRepository::class) - - private lateinit var endCall: EndCallUseCase - - @BeforeTest - fun setup() = runBlocking { - endCall = EndCallUseCaseImpl(lazy { callManager }, callRepository, TestKaliumDispatcher) - - coEvery { - callManager.endCall(eq(conversationId)) - }.returns(Unit) - - every { callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) } - .doesNothing() - } - @Test fun givenAnEstablishedCall_whenEndCallIsInvoked_thenUpdateStatusAndInvokeEndCallOnce() = runTest(TestKaliumDispatcher.main) { - coEvery { - callRepository.callsFlow() - }.returns(flowOf(listOf(call))) + + val (arrangement, endCall) = Arrangement().arrange { + withEndCall() + withCallsFlow(flowOf(listOf(call))) + withUpdateIsCameraOnById() + } endCall.invoke(conversationId) coVerify { - callManager.endCall(eq(conversationId)) + arrangement.callManager.endCall(eq(conversationId)) }.wasInvoked(once) verify { - callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + arrangement.callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) }.wasInvoked(once) coVerify { - callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED)) + arrangement.callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED)) + }.wasInvoked(once) + + coVerify { + arrangement.endCallResultListener.onCallEndedAskForFeedback(eq(false)) }.wasInvoked(once) } @@ -90,23 +78,28 @@ class EndCallUseCaseTest { status = CallStatus.STILL_ONGOING, conversationType = Conversation.Type.GROUP ) - - coEvery { - callRepository.callsFlow() - }.returns(flowOf(listOf(stillOngoingCall))) + val (arrangement, endCall) = Arrangement().arrange { + withEndCall() + withCallsFlow(flowOf(listOf(stillOngoingCall))) + withUpdateIsCameraOnById() + } endCall.invoke(conversationId) coVerify { - callManager.endCall(eq(conversationId)) + arrangement.callManager.endCall(eq(conversationId)) }.wasInvoked(once) verify { - callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + arrangement.callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + }.wasInvoked(once) + + coVerify { + arrangement.callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED_INTERNALLY)) }.wasInvoked(once) coVerify { - callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED_INTERNALLY)) + arrangement.endCallResultListener.onCallEndedAskForFeedback(eq(false)) }.wasInvoked(once) } @@ -116,23 +109,28 @@ class EndCallUseCaseTest { status = CallStatus.STARTED, conversationType = Conversation.Type.GROUP ) - - coEvery { - callRepository.callsFlow() - }.returns(flowOf(listOf(stillOngoingCall))) + val (arrangement, endCall) = Arrangement().arrange { + withEndCall() + withCallsFlow(flowOf(listOf(stillOngoingCall))) + withUpdateIsCameraOnById() + } endCall.invoke(conversationId) coVerify { - callManager.endCall(eq(conversationId)) + arrangement.callManager.endCall(eq(conversationId)) }.wasInvoked(once) verify { - callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + arrangement.callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + }.wasInvoked(once) + + coVerify { + arrangement.callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED_INTERNALLY)) }.wasInvoked(once) coVerify { - callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED_INTERNALLY)) + arrangement.endCallResultListener.onCallEndedAskForFeedback(eq(false)) }.wasInvoked(once) } @@ -142,23 +140,28 @@ class EndCallUseCaseTest { status = CallStatus.INCOMING, conversationType = Conversation.Type.GROUP ) - - coEvery { - callRepository.callsFlow() - }.returns(flowOf(listOf(stillOngoingCall))) + val (arrangement, endCall) = Arrangement().arrange { + withEndCall() + withCallsFlow(flowOf(listOf(stillOngoingCall))) + withUpdateIsCameraOnById() + } endCall.invoke(conversationId) coVerify { - callManager.endCall(eq(conversationId)) + arrangement.callManager.endCall(eq(conversationId)) }.wasInvoked(once) verify { - callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + arrangement.callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + }.wasInvoked(once) + + coVerify { + arrangement.callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED_INTERNALLY)) }.wasInvoked(once) coVerify { - callRepository.updateCallStatusById(eq(conversationId), eq(CallStatus.CLOSED_INTERNALLY)) + arrangement.endCallResultListener.onCallEndedAskForFeedback(eq(false)) }.wasInvoked(once) } @@ -167,24 +170,62 @@ class EndCallUseCaseTest { val closedCall = call.copy( status = CallStatus.CLOSED ) - - coEvery { - callRepository.callsFlow() - }.returns(flowOf(listOf(closedCall))) + val (arrangement, endCall) = Arrangement().arrange { + withEndCall() + withCallsFlow(flowOf(listOf(closedCall))) + withUpdateIsCameraOnById() + } endCall.invoke(conversationId) coVerify { - callManager.endCall(eq(conversationId)) + arrangement.callManager.endCall(eq(conversationId)) }.wasInvoked(once) verify { - callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) + arrangement.callRepository.updateIsCameraOnById(eq(conversationId), eq(false)) }.wasInvoked(once) coVerify { - callRepository.updateCallStatusById(any(), any()) + arrangement.callRepository.updateCallStatusById(any(), any()) }.wasNotInvoked() + + coVerify { + arrangement.endCallResultListener.onCallEndedAskForFeedback(eq(false)) + }.wasInvoked(once) + } + + private class Arrangement : CallRepositoryArrangement by CallRepositoryArrangementImpl(), + CallManagerArrangement by CallManagerArrangementImpl() { + + @Mock + val endCallResultListener = mock(EndCallResultListener::class) + + @Mock + val shouldAskCallFeedback = mock(ShouldAskCallFeedbackUseCase::class) + + fun arrange(block: suspend Arrangement.() -> Unit): Pair { + runBlocking { + withShouldAskCallFeedback() + withOnCallEndedAskForFeedback() + } + runBlocking { block() } + return this to EndCallUseCaseImpl( + lazy { callManager }, + callRepository, + endCallResultListener, + shouldAskCallFeedback, + TestKaliumDispatcher + ) + } + + suspend fun withShouldAskCallFeedback(should: Boolean = false) { + coEvery { shouldAskCallFeedback.invoke() }.returns(should) + } + + suspend fun withOnCallEndedAskForFeedback() { + coEvery { endCallResultListener.onCallEndedAskForFeedback(any()) }.doesNothing() + } } companion object { diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt index a60f24f0ced..7e6e84139a4 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt @@ -39,7 +39,7 @@ import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.functional.left import com.wire.kalium.logic.functional.right import com.wire.kalium.logic.test_util.TestNetworkResponseError -import com.wire.kalium.logic.util.arrangement.CallRepositoryArrangementImpl +import com.wire.kalium.logic.util.arrangement.repository.CallRepositoryArrangementImpl import com.wire.kalium.logic.util.shouldSucceed import com.wire.kalium.network.api.model.ErrorResponse import com.wire.kalium.network.exceptions.KaliumException diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCaseTest.kt new file mode 100644 index 00000000000..a52b866fd48 --- /dev/null +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/ShouldAskCallFeedbackUseCaseTest.kt @@ -0,0 +1,89 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.user + +import com.wire.kalium.logic.StorageFailure +import com.wire.kalium.logic.functional.left +import com.wire.kalium.logic.functional.right +import com.wire.kalium.logic.util.arrangement.repository.UserConfigRepositoryArrangement +import com.wire.kalium.logic.util.arrangement.repository.UserConfigRepositoryArrangementImpl +import com.wire.kalium.util.DateTimeUtil +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.days + +class ShouldAskCallFeedbackUseCaseTest { + + @Test + fun givenNoNextTimeForCallFeedbackSaved_whenInvoked_thenTrueIsReturned() = runTest { + val (_, useCase) = Arrangement().arrange { + withGetNextTimeForCallFeedback(StorageFailure.DataNotFound.left()) + } + + val result = useCase() + + assertTrue(result) + } + + @Test + fun givenNextTimeForCallFeedbackInPast_whenInvoked_thenTrueIsReturned() = runTest { + val nextTimeToAsk = DateTimeUtil.currentInstant().minus(1.days).toEpochMilliseconds() + val (_, useCase) = Arrangement().arrange { + withGetNextTimeForCallFeedback(nextTimeToAsk.right()) + } + + val result = useCase() + + assertTrue(result) + } + + @Test + fun givenNextTimeForCallFeedbackInFuture_whenInvoked_thenFalseIsReturned() = runTest { + val nextTimeToAsk = DateTimeUtil.currentInstant().plus(1.days).toEpochMilliseconds() + val (_, useCase) = Arrangement().arrange { + withGetNextTimeForCallFeedback(nextTimeToAsk.right()) + } + + val result = useCase() + + assertFalse(result) + } + + @Test + fun givenNextTimeForCallFeedbackIsNegative_whenInvoked_thenFalseIsReturned() = runTest { + val nextTimeToAsk = -1L + val (_, useCase) = Arrangement().arrange { + withGetNextTimeForCallFeedback(nextTimeToAsk.right()) + } + + val result = useCase() + + assertFalse(result) + } + + private class Arrangement : UserConfigRepositoryArrangement by UserConfigRepositoryArrangementImpl() { + + fun arrange(block: suspend Arrangement.() -> Unit): Pair { + runBlocking { block() } + return this to ShouldAskCallFeedbackUseCase(userConfigRepository) + } + } +} diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCaseTest.kt new file mode 100644 index 00000000000..d1333725108 --- /dev/null +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UpdateNextTimeCallFeedbackUseCaseTest.kt @@ -0,0 +1,68 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.user + +import com.wire.kalium.logic.util.arrangement.repository.UserConfigRepositoryArrangement +import com.wire.kalium.logic.util.arrangement.repository.UserConfigRepositoryArrangementImpl +import com.wire.kalium.util.DateTimeUtil +import io.mockative.coVerify +import io.mockative.eq +import io.mockative.matches +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.minutes + +class UpdateNextTimeCallFeedbackUseCaseTest { + + @Test + fun givenNeverAskAgainIsTrue_whenInvoked_thenNextTimeSetToNegative() = runTest { + val (arrangement, useCase) = Arrangement().arrange { + withUpdateNextTimeForCallFeedback() + } + + useCase(true) + + coVerify { arrangement.userConfigRepository.updateNextTimeForCallFeedback(eq(-1L)) } + .wasInvoked() + } + + @Test + fun givenNeverAskAgainIsFalse_whenInvoked_thenNextTimeSetToNegative() = runTest { + val (arrangement, useCase) = Arrangement().arrange { + withUpdateNextTimeForCallFeedback() + } + val expectedMin = DateTimeUtil.currentInstant().plus(3.days).toEpochMilliseconds() + val expectedMax = DateTimeUtil.currentInstant().plus(3.days).plus(10.minutes).toEpochMilliseconds() + + useCase(false) + + coVerify { arrangement.userConfigRepository.updateNextTimeForCallFeedback(matches { it in expectedMin.. Unit): Pair { + runBlocking { block() } + return this to UpdateNextTimeCallFeedbackUseCase(userConfigRepository) + } + } +} diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/ProtocolUpdateEventHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/ProtocolUpdateEventHandlerTest.kt index 6ceeaaafe16..3fcee9b1637 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/ProtocolUpdateEventHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/ProtocolUpdateEventHandlerTest.kt @@ -22,8 +22,8 @@ import com.wire.kalium.logic.framework.TestEvent import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.sync.receiver.conversation.ProtocolUpdateEventHandler import com.wire.kalium.logic.sync.receiver.conversation.ProtocolUpdateEventHandlerImpl -import com.wire.kalium.logic.util.arrangement.CallRepositoryArrangement -import com.wire.kalium.logic.util.arrangement.CallRepositoryArrangementImpl +import com.wire.kalium.logic.util.arrangement.repository.CallRepositoryArrangement +import com.wire.kalium.logic.util.arrangement.repository.CallRepositoryArrangementImpl import com.wire.kalium.logic.util.arrangement.SystemMessageInserterArrangement import com.wire.kalium.logic.util.arrangement.SystemMessageInserterArrangementImpl import com.wire.kalium.logic.util.arrangement.repository.ConversationRepositoryArrangement diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/CallRepositoryArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/CallRepositoryArrangement.kt deleted file mode 100644 index a16ca78289d..00000000000 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/CallRepositoryArrangement.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Wire - * Copyright (C) 2024 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package com.wire.kalium.logic.util.arrangement - -import com.wire.kalium.logic.data.call.Call -import com.wire.kalium.logic.data.call.CallRepository -import com.wire.kalium.logic.data.call.CallStatus -import com.wire.kalium.logic.data.conversation.Conversation -import com.wire.kalium.logic.data.id.ConversationId -import com.wire.kalium.logic.data.user.UserId -import io.mockative.Mock -import io.mockative.coEvery -import io.mockative.mock -import kotlinx.coroutines.flow.flowOf - -interface CallRepositoryArrangement { - val callRepository: CallRepository - suspend fun withEstablishedCall() - suspend fun withoutAnyEstablishedCall() -} - -internal class CallRepositoryArrangementImpl : CallRepositoryArrangement { - - @Mock - override val callRepository = mock(CallRepository::class) - - override suspend fun withEstablishedCall() { - coEvery { - callRepository.establishedCallsFlow() - }.returns(flowOf(listOf(call))) - } - - override suspend fun withoutAnyEstablishedCall() { - coEvery { - callRepository.establishedCallsFlow() - }.returns(flowOf(listOf())) - } - - companion object { - val call = Call( - conversationId = ConversationId("conversationId", "domain"), - status = CallStatus.ESTABLISHED, - callerId = UserId("caller", "domain").toString(), - participants = listOf(), - isMuted = true, - isCameraOn = false, - isCbrEnabled = false, - maxParticipants = 0, - conversationName = "ONE_ON_ONE Name", - conversationType = Conversation.Type.ONE_ON_ONE, - callerName = "otherUsername", - callerTeamName = "team_1" - ) - } -} diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallManagerArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallManagerArrangement.kt new file mode 100644 index 00000000000..8c2e10386a2 --- /dev/null +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallManagerArrangement.kt @@ -0,0 +1,40 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.util.arrangement.repository + +import com.wire.kalium.logic.feature.call.CallManager +import io.mockative.Mock +import io.mockative.any +import io.mockative.coEvery +import io.mockative.mock + +interface CallManagerArrangement { + + val callManager: CallManager + + suspend fun withEndCall() +} + +internal class CallManagerArrangementImpl : CallManagerArrangement { + @Mock + override val callManager = mock(CallManager::class) + + override suspend fun withEndCall() { + coEvery { callManager.endCall(any()) }.returns(Unit) + } +} diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallRepositoryArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallRepositoryArrangement.kt index a57e0d95533..e275e2a851c 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallRepositoryArrangement.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/CallRepositoryArrangement.kt @@ -17,17 +17,29 @@ */ package com.wire.kalium.logic.util.arrangement.repository -import com.wire.kalium.logic.data.call.CallRepository import com.wire.kalium.logic.data.call.Call +import com.wire.kalium.logic.data.call.CallRepository +import com.wire.kalium.logic.data.call.CallStatus +import com.wire.kalium.logic.data.conversation.Conversation +import com.wire.kalium.logic.data.id.ConversationId +import com.wire.kalium.logic.data.user.UserId import io.mockative.Mock +import io.mockative.any import io.mockative.coEvery +import io.mockative.doesNothing +import io.mockative.every import io.mockative.mock +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf internal interface CallRepositoryArrangement { val callRepository: CallRepository suspend fun withEstablishedCallsFlow(calls: List) + suspend fun withEstablishedCall() + suspend fun withoutAnyEstablishedCall() + suspend fun withCallsFlow(flow: Flow>) + suspend fun withUpdateIsCameraOnById(conversationId: ConversationId = any(), isCameraOn: Boolean = any()) } internal open class CallRepositoryArrangementImpl : CallRepositoryArrangement { @@ -40,4 +52,41 @@ internal open class CallRepositoryArrangementImpl : CallRepositoryArrangement { callRepository.establishedCallsFlow() }.returns(flowOf(calls)) } + + override suspend fun withEstablishedCall() { + coEvery { + callRepository.establishedCallsFlow() + }.returns(flowOf(listOf(CallRepositoryArrangementImpl.call))) + } + + override suspend fun withoutAnyEstablishedCall() { + coEvery { + callRepository.establishedCallsFlow() + }.returns(flowOf(listOf())) + } + + override suspend fun withCallsFlow(flow: Flow>) { + coEvery { callRepository.callsFlow() }.returns(flow) + } + + override suspend fun withUpdateIsCameraOnById(conversationId: ConversationId, isCameraOn: Boolean) { + every { callRepository.updateIsCameraOnById(conversationId, isCameraOn) }.doesNothing() + } + + companion object { + val call = Call( + conversationId = ConversationId("conversationId", "domain"), + status = CallStatus.ESTABLISHED, + callerId = UserId("caller", "domain").toString(), + participants = listOf(), + isMuted = true, + isCameraOn = false, + isCbrEnabled = false, + maxParticipants = 0, + conversationName = "ONE_ON_ONE Name", + conversationType = Conversation.Type.ONE_ON_ONE, + callerName = "otherUsername", + callerTeamName = "team_1" + ) + } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt index 3a5258a0adb..501f9521a5c 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt @@ -48,6 +48,8 @@ internal interface UserConfigRepositoryArrangement { suspend fun withGetPreviousTrackingIdentifier(result: String?) suspend fun withObserveTrackingIdentifier(result: Either) suspend fun withDeletePreviousTrackingIdentifier() + suspend fun withUpdateNextTimeForCallFeedback() + suspend fun withGetNextTimeForCallFeedback(result: Either) } internal class UserConfigRepositoryArrangementImpl : UserConfigRepositoryArrangement { @@ -125,4 +127,12 @@ internal class UserConfigRepositoryArrangementImpl : UserConfigRepositoryArrange override suspend fun withDeletePreviousTrackingIdentifier() { coEvery { userConfigRepository.deletePreviousTrackingIdentifier() }.returns(Unit) } + + override suspend fun withGetNextTimeForCallFeedback(result: Either) { + coEvery { userConfigRepository.getNextTimeForCallFeedback() }.returns(result) + } + + override suspend fun withUpdateNextTimeForCallFeedback() { + coEvery { userConfigRepository.updateNextTimeForCallFeedback(any()) }.returns(Unit) + } } diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt index 77456973dd9..4b736f5e23d 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt @@ -66,6 +66,8 @@ interface UserConfigDAO { suspend fun setPreviousTrackingIdentifier(identifier: String) suspend fun getPreviousTrackingIdentifier(): String? suspend fun deletePreviousTrackingIdentifier() + suspend fun getNextTimeForCallFeedback(): Long? + suspend fun setNextTimeForCallFeedback(timestamp: Long) } @Suppress("TooManyFunctions") @@ -219,12 +221,19 @@ internal class UserConfigDAOImpl internal constructor( metadataDAO.deleteValue(key = ANALYTICS_TRACKING_IDENTIFIER_PREVIOUS_KEY) } + override suspend fun getNextTimeForCallFeedback(): Long? = metadataDAO.valueByKey(NEXT_TIME_TO_ASK_CALL_FEEDBACK)?.toLong() + + override suspend fun setNextTimeForCallFeedback(timestamp: Long) = + metadataDAO.insertValue(timestamp.toString(), NEXT_TIME_TO_ASK_CALL_FEEDBACK) + + private companion object { private const val DEFAULT_CIPHER_SUITE_KEY = "DEFAULT_CIPHER_SUITE" private const val SELF_DELETING_MESSAGES_KEY = "SELF_DELETING_MESSAGES" private const val SHOULD_NOTIFY_FOR_REVOKED_CERTIFICATE = "should_notify_for_revoked_certificate" private const val MLS_MIGRATION_KEY = "MLS_MIGRATION" private const val SUPPORTED_PROTOCOLS_KEY = "SUPPORTED_PROTOCOLS" + private const val NEXT_TIME_TO_ASK_CALL_FEEDBACK = "next_time_to_ask_for_feedback_about_call" const val LEGAL_HOLD_REQUEST = "legal_hold_request" const val LEGAL_HOLD_CHANGE_NOTIFIED = "legal_hold_change_notified" const val SHOULD_UPDATE_CLIENT_LEGAL_HOLD_CAPABILITY = From 4e760dbccc390617a2eac69dbc764b5ce3988166 Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Thu, 22 Aug 2024 22:05:19 +0300 Subject: [PATCH 2/3] Code-style fix --- .../kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt | 4 +++- .../com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt index 0e66db2b0b9..0529a040cd7 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt @@ -212,7 +212,9 @@ class CallsScope internal constructor( val observeAskCallFeedbackUseCase: ObserveAskCallFeedbackUseCase get() = ObserveAskCallFeedbackUseCase(EndCallResultListenerImpl) - private val shouldAskCallFeedbackUseCase: ShouldAskCallFeedbackUseCase by lazy { ShouldAskCallFeedbackUseCase(userConfigRepository) } + private val shouldAskCallFeedbackUseCase: ShouldAskCallFeedbackUseCase by lazy { + ShouldAskCallFeedbackUseCase(userConfigRepository) + } val updateNextTimeCallFeedback: UpdateNextTimeCallFeedbackUseCase by lazy { UpdateNextTimeCallFeedbackUseCase(userConfigRepository) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt index 4b736f5e23d..ab36fd9b728 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt @@ -226,7 +226,6 @@ internal class UserConfigDAOImpl internal constructor( override suspend fun setNextTimeForCallFeedback(timestamp: Long) = metadataDAO.insertValue(timestamp.toString(), NEXT_TIME_TO_ASK_CALL_FEEDBACK) - private companion object { private const val DEFAULT_CIPHER_SUITE_KEY = "DEFAULT_CIPHER_SUITE" private const val SELF_DELETING_MESSAGES_KEY = "SELF_DELETING_MESSAGES" From b17f8446630ac45e8d3de109d517093dcea667c9 Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Mon, 26 Aug 2024 12:16:42 +0300 Subject: [PATCH 3/3] Review fixes --- .../kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt | 4 ++-- .../wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt index 0529a040cd7..178b25f070a 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt @@ -153,7 +153,7 @@ class CallsScope internal constructor( callManager = callManager, callRepository = callRepository, endCallListener = EndCallResultListenerImpl, - shouldAskCallFeedbackUseCase = shouldAskCallFeedbackUseCase + shouldAskCallFeedback = shouldAskCallFeedback ) val endCallOnConversationChange: EndCallOnConversationChangeUseCase @@ -212,7 +212,7 @@ class CallsScope internal constructor( val observeAskCallFeedbackUseCase: ObserveAskCallFeedbackUseCase get() = ObserveAskCallFeedbackUseCase(EndCallResultListenerImpl) - private val shouldAskCallFeedbackUseCase: ShouldAskCallFeedbackUseCase by lazy { + private val shouldAskCallFeedback: ShouldAskCallFeedbackUseCase by lazy { ShouldAskCallFeedbackUseCase(userConfigRepository) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt index f387575d590..f9a5a674918 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallUseCase.kt @@ -48,7 +48,7 @@ internal class EndCallUseCaseImpl( private val callManager: Lazy, private val callRepository: CallRepository, private val endCallListener: EndCallResultListener, - private val shouldAskCallFeedbackUseCase: ShouldAskCallFeedbackUseCase, + private val shouldAskCallFeedback: ShouldAskCallFeedbackUseCase, private val dispatchers: KaliumDispatcher = KaliumDispatcherImpl ) : EndCallUseCase { @@ -76,6 +76,6 @@ internal class EndCallUseCaseImpl( callManager.value.endCall(conversationId) callRepository.updateIsCameraOnById(conversationId, false) - endCallListener.onCallEndedAskForFeedback(shouldAskCallFeedbackUseCase()) + endCallListener.onCallEndedAskForFeedback(shouldAskCallFeedback()) } }