diff --git a/app/src/main/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepository.kt b/app/src/main/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepository.kt index 44504b032e..112c9f7968 100644 --- a/app/src/main/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepository.kt +++ b/app/src/main/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepository.kt @@ -34,8 +34,13 @@ interface IncomingRequestRepository { fun getAmountOfRequests(): Int suspend fun requestDeferred(requestId: String) + + fun consumeBufferedRequest(): IncomingRequest? + + fun setBufferedRequest(request: IncomingRequest) } +@Suppress("TooManyFunctions") class IncomingRequestRepositoryImpl @Inject constructor( private val appEventBus: AppEventBus ) : IncomingRequestRepository { @@ -56,6 +61,19 @@ class IncomingRequestRepositoryImpl @Inject constructor( private val mutex = Mutex() + /** + * Request that can come in via deep link before wallet is setup. + */ + private var bufferedRequest: IncomingRequest? = null + + override fun setBufferedRequest(request: IncomingRequest) { + bufferedRequest = request + } + + override fun consumeBufferedRequest(): IncomingRequest? { + return bufferedRequest?.also { bufferedRequest = null } + } + override suspend fun add(incomingRequest: IncomingRequest) { mutex.withLock { val requestItem = QueueItem.RequestItem(incomingRequest) diff --git a/app/src/main/java/com/babylon/wallet/android/data/repository/BufferedMobileConnectRequestRepository.kt b/app/src/main/java/com/babylon/wallet/android/data/repository/BufferedMobileConnectRequestRepository.kt deleted file mode 100644 index 72d66ea79e..0000000000 --- a/app/src/main/java/com/babylon/wallet/android/data/repository/BufferedMobileConnectRequestRepository.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.babylon.wallet.android.data.repository - -import com.babylon.wallet.android.domain.model.IncomingMessage -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class BufferedMobileConnectRequestRepository @Inject constructor() { - - private var bufferedRequest: IncomingMessage.IncomingRequest? = null - - fun setBufferedRequest(request: IncomingMessage.IncomingRequest) { - bufferedRequest = request - } - - fun getBufferedRequest(): IncomingMessage.IncomingRequest? { - return bufferedRequest?.also { bufferedRequest = null } - } -} diff --git a/app/src/main/java/com/babylon/wallet/android/domain/usecases/deeplink/ProcessDeepLinkUseCase.kt b/app/src/main/java/com/babylon/wallet/android/domain/usecases/deeplink/ProcessDeepLinkUseCase.kt index 3ddddf96a7..af601bb1fd 100644 --- a/app/src/main/java/com/babylon/wallet/android/domain/usecases/deeplink/ProcessDeepLinkUseCase.kt +++ b/app/src/main/java/com/babylon/wallet/android/domain/usecases/deeplink/ProcessDeepLinkUseCase.kt @@ -1,7 +1,7 @@ package com.babylon.wallet.android.domain.usecases.deeplink +import com.babylon.wallet.android.data.dapp.IncomingRequestRepository import com.babylon.wallet.android.data.dapp.model.toDomainModel -import com.babylon.wallet.android.data.repository.BufferedMobileConnectRequestRepository import com.babylon.wallet.android.domain.model.IncomingMessage import com.radixdlt.sargon.RadixConnectMobile import rdx.works.profile.domain.GetProfileUseCase @@ -11,7 +11,7 @@ import javax.inject.Inject class ProcessDeepLinkUseCase @Inject constructor( private val radixConnectMobile: RadixConnectMobile, private val getProfileUseCase: GetProfileUseCase, - private val bufferedMobileConnectRequestRepository: BufferedMobileConnectRequestRepository + private val incomingRequestRepository: IncomingRequestRepository ) { suspend operator fun invoke(deepLink: String): Result { @@ -25,7 +25,7 @@ class ProcessDeepLinkUseCase @Inject constructor( ) ).getOrThrow() if (!profileInitialized) { - bufferedMobileConnectRequestRepository.setBufferedRequest(request) + incomingRequestRepository.setBufferedRequest(request) return Result.success(DeepLinkProcessingResult.Buffered) } DeepLinkProcessingResult.Processed(request) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/main/MainViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/main/MainViewModel.kt index b239c9a245..1ef3083078 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/main/MainViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/main/MainViewModel.kt @@ -4,7 +4,6 @@ import android.net.Uri import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.data.dapp.IncomingRequestRepository import com.babylon.wallet.android.data.dapp.PeerdroidClient -import com.babylon.wallet.android.data.repository.BufferedMobileConnectRequestRepository import com.babylon.wallet.android.data.repository.p2plink.P2PLinksRepository import com.babylon.wallet.android.domain.RadixWalletException import com.babylon.wallet.android.domain.model.IncomingMessage.IncomingRequest @@ -72,8 +71,7 @@ class MainViewModel @Inject constructor( private val checkEntitiesCreatedWithOlympiaUseCase: CheckEntitiesCreatedWithOlympiaUseCase, private val observeAccountsAndSyncWithConnectorExtensionUseCase: ObserveAccountsAndSyncWithConnectorExtensionUseCase, private val cloudBackupErrorStream: CloudBackupErrorStream, - private val processDeepLinkUseCase: ProcessDeepLinkUseCase, - private val bufferedMobileConnectRequestRepository: BufferedMobileConnectRequestRepository + private val processDeepLinkUseCase: ProcessDeepLinkUseCase ) : StateViewModel(), OneOffEventHandler by OneOffEventHandlerImpl() { private var verifyingDappRequestJob: Job? = null @@ -160,7 +158,7 @@ class MainViewModel @Inject constructor( private fun processBufferedDeepLinkRequest() { viewModelScope.launch { appEventBus.events.filterIsInstance().collect { - bufferedMobileConnectRequestRepository.getBufferedRequest()?.let { request -> + incomingRequestRepository.consumeBufferedRequest()?.let { request -> verifyIncomingRequest(request) } } diff --git a/app/src/test/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepositoryTest.kt b/app/src/test/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepositoryTest.kt index 8da46ca29d..264c2b61ee 100644 --- a/app/src/test/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepositoryTest.kt +++ b/app/src/test/java/com/babylon/wallet/android/data/dapp/IncomingRequestRepositoryTest.kt @@ -5,6 +5,7 @@ import com.babylon.wallet.android.utils.AppEvent import com.babylon.wallet.android.utils.AppEventBusImpl import com.radixdlt.sargon.NetworkId import io.mockk.coVerify +import io.mockk.mockk import io.mockk.spyk import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi @@ -98,24 +99,25 @@ class IncomingRequestRepositoryTest { } @Test - fun `adding mobile connect request and deferring current makes mobile request new current, while deferred event stays in queue`() = runTest { - var currentRequest: IncomingMessage.IncomingRequest? = null - val interactionId1 = UUID.randomUUID().toString() - val interactionId2 = UUID.randomUUID().toString() - incomingRequestRepository.currentRequestToHandle - .onEach { currentRequest = it } - .launchIn(CoroutineScope(UnconfinedTestDispatcher(testScheduler))) - incomingRequestRepository.add(incomingRequest = sampleIncomingRequest.copy(interactionId = interactionId1)) - advanceUntilIdle() - assertTrue(incomingRequestRepository.getAmountOfRequests() == 1) - assert(currentRequest?.interactionId == interactionId1) - incomingRequestRepository.addPriorityRequest(sampleIncomingRequest.copy(interactionId = interactionId2)) - incomingRequestRepository.requestDeferred(interactionId1) - advanceUntilIdle() - assert(currentRequest?.interactionId == interactionId2) - assertTrue(incomingRequestRepository.getAmountOfRequests() == 2) - coVerify(exactly = 1) { eventBus.sendEvent(AppEvent.DeferRequestHandling(interactionId1)) } - } + fun `adding mobile connect request and deferring current makes mobile request new current, while deferred event stays in queue`() = + runTest { + var currentRequest: IncomingMessage.IncomingRequest? = null + val interactionId1 = UUID.randomUUID().toString() + val interactionId2 = UUID.randomUUID().toString() + incomingRequestRepository.currentRequestToHandle + .onEach { currentRequest = it } + .launchIn(CoroutineScope(UnconfinedTestDispatcher(testScheduler))) + incomingRequestRepository.add(incomingRequest = sampleIncomingRequest.copy(interactionId = interactionId1)) + advanceUntilIdle() + assertTrue(incomingRequestRepository.getAmountOfRequests() == 1) + assert(currentRequest?.interactionId == interactionId1) + incomingRequestRepository.addPriorityRequest(sampleIncomingRequest.copy(interactionId = interactionId2)) + incomingRequestRepository.requestDeferred(interactionId1) + advanceUntilIdle() + assert(currentRequest?.interactionId == interactionId2) + assertTrue(incomingRequestRepository.getAmountOfRequests() == 2) + coVerify(exactly = 1) { eventBus.sendEvent(AppEvent.DeferRequestHandling(interactionId1)) } + } @Test fun `addFirst inserts item at 2nd position when there is high priority screen`() = runTest { @@ -137,4 +139,12 @@ class IncomingRequestRepositoryTest { assert(currentRequest?.interactionId == interactionId2) assertTrue(incomingRequestRepository.getAmountOfRequests() == 2) } + + @Test + fun `reading buffered request clears it`() = runTest { + val request = mockk() + incomingRequestRepository.setBufferedRequest(request) + assert(incomingRequestRepository.consumeBufferedRequest() != null) + assert(incomingRequestRepository.consumeBufferedRequest() == null) + } } diff --git a/app/src/test/java/com/babylon/wallet/android/data/repository/BufferedMobileConnectRequestRepositoryTest.kt b/app/src/test/java/com/babylon/wallet/android/data/repository/BufferedMobileConnectRequestRepositoryTest.kt deleted file mode 100644 index 3ea2513b76..0000000000 --- a/app/src/test/java/com/babylon/wallet/android/data/repository/BufferedMobileConnectRequestRepositoryTest.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.babylon.wallet.android.data.repository - -import com.babylon.wallet.android.domain.model.IncomingMessage -import io.mockk.mockk -import kotlinx.coroutines.test.runTest -import org.junit.Before -import org.junit.Test - -class BufferedMobileConnectRequestRepositoryTest { - - private lateinit var bufferedMobileConnectRequestRepository: BufferedMobileConnectRequestRepository - - @Before - fun setup() { - bufferedMobileConnectRequestRepository = BufferedMobileConnectRequestRepository() - } - - @Test - fun `reading buffered request clears it`() = runTest { - val request = mockk() - bufferedMobileConnectRequestRepository.setBufferedRequest(request) - bufferedMobileConnectRequestRepository.getBufferedRequest() - assert(bufferedMobileConnectRequestRepository.getBufferedRequest() == null) - } - -} \ No newline at end of file diff --git a/app/src/test/java/com/babylon/wallet/android/presentation/WalletViewModelTest.kt b/app/src/test/java/com/babylon/wallet/android/presentation/WalletViewModelTest.kt index e3cdd2de2b..a8b684fad5 100644 --- a/app/src/test/java/com/babylon/wallet/android/presentation/WalletViewModelTest.kt +++ b/app/src/test/java/com/babylon/wallet/android/presentation/WalletViewModelTest.kt @@ -3,7 +3,7 @@ package com.babylon.wallet.android.presentation import app.cash.turbine.test import com.babylon.wallet.android.NPSSurveyState import com.babylon.wallet.android.NPSSurveyStateObserver -import com.babylon.wallet.android.data.repository.BufferedMobileConnectRequestRepository +import com.babylon.wallet.android.data.dapp.IncomingRequestRepository import com.babylon.wallet.android.data.repository.p2plink.P2PLinksRepository import com.babylon.wallet.android.domain.model.assets.AccountWithAssets import com.babylon.wallet.android.domain.usecases.GetEntitiesWithSecurityPromptUseCase @@ -61,7 +61,7 @@ class WalletViewModelTest : StateViewModelTest() { private val preferencesManager = mockk() private val appEventBus = mockk() private val testDispatcher = StandardTestDispatcher() - private val bufferedMobileConnectRequestRepository = mockk() + private val incomingRequestRepository = mockk() private val p2PLinksRepository = mockk() private val sampleProfile = Profile.sample() @@ -90,7 +90,7 @@ class WalletViewModelTest : StateViewModelTest() { override fun setUp() { super.setUp() - coEvery { bufferedMobileConnectRequestRepository.getBufferedRequest() } returns null + coEvery { incomingRequestRepository.consumeBufferedRequest() } returns null coEvery { ensureBabylonFactorSourceExistUseCase.babylonFactorSourceExist() } returns true every { getAccountsForSecurityPromptUseCase() } returns flow { emit(emptyList()) } every { getBackupStateUseCase() } returns flowOf(