diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 0a6ed669e7..557f69fdd0 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -245,7 +245,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { if (routingFeatureToggle.isDeepLinkNavigationEnabled.not() && intent != null && savedInstanceState == null) { // handle intent only on start, not on recreate - handleDeepLink(intent) + handleDeepLink(intent = intent, isFromOnNewIntent = false) } lifecycle.addObserver(WindowObscurationObserver) @@ -397,7 +397,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { } if (intent != null) { - handleDeepLink(intent) + handleDeepLink(intent = intent, isFromOnNewIntent = true) } } @@ -479,13 +479,13 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { } if (routingFeatureToggle.isDeepLinkNavigationEnabled && intent != null) { - handleDeepLink(intent) + handleDeepLink(intent = intent, isFromOnNewIntent = false) } viewModel.checkForUnfinishedBackup() } - private fun handleDeepLink(intent: Intent) { + private fun handleDeepLink(intent: Intent, isFromOnNewIntent: Boolean) { if (routingFeatureToggle.isDeepLinkNavigationEnabled) { val deepLinkExtras = intent.getStringExtra(DEEPLINK_KEY)?.toUri() val webLink = intent.getStringExtra(WEBLINK_KEY) @@ -494,7 +494,11 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { when { receivedDeepLink != null -> { - deeplinkFactory.handleDeeplink(deeplinkUri = receivedDeepLink, coroutineScope = lifecycleScope) + deeplinkFactory.handleDeeplink( + deeplinkUri = receivedDeepLink, + coroutineScope = lifecycleScope, + isFromOnNewIntent = isFromOnNewIntent, + ) } webLink?.uriValidate() == true -> { urlOpener.openUrl(webLink) diff --git a/app/src/main/java/com/tangem/tap/routing/utils/DeepLinkFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/DeepLinkFactory.kt index 1e05612cee..00e016b292 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/DeepLinkFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/DeepLinkFactory.kt @@ -42,7 +42,7 @@ internal class DeepLinkFactory @Inject constructor( private val deepLinkHandlerJobHolder = JobHolder() @OptIn(ExperimentalCoroutinesApi::class) - fun handleDeeplink(deeplinkUri: Uri, coroutineScope: CoroutineScope) { + fun handleDeeplink(deeplinkUri: Uri, coroutineScope: CoroutineScope, isFromOnNewIntent: Boolean) { lastDeepLink = deeplinkUri Timber.i( @@ -55,7 +55,7 @@ internal class DeepLinkFactory @Inject constructor( .transformLatest { isPermitted -> if (isPermitted) { lastDeepLink?.let { - launchDeepLink(it, coroutineScope) + launchDeepLink(it, coroutineScope, isFromOnNewIntent) } lastDeepLink = null } @@ -80,9 +80,9 @@ internal class DeepLinkFactory @Inject constructor( } } - private fun launchDeepLink(deeplinkUri: Uri, coroutineScope: CoroutineScope) { + private fun launchDeepLink(deeplinkUri: Uri, coroutineScope: CoroutineScope, isFromOnNewIntent: Boolean) { when (deeplinkUri.scheme) { - DeepLinkScheme.Tangem.scheme -> handleTangemDeepLinks(deeplinkUri, coroutineScope) + DeepLinkScheme.Tangem.scheme -> handleTangemDeepLinks(deeplinkUri, coroutineScope, isFromOnNewIntent) DeepLinkScheme.WalletConnect.scheme -> walletConnectDeepLink.create(deeplinkUri) else -> { Timber.i( @@ -95,7 +95,7 @@ internal class DeepLinkFactory @Inject constructor( } } - private fun handleTangemDeepLinks(deeplinkUri: Uri, coroutineScope: CoroutineScope) { + private fun handleTangemDeepLinks(deeplinkUri: Uri, coroutineScope: CoroutineScope, isFromOnNewIntent: Boolean) { val queryParams = getQueryParams(deeplinkUri) when (deeplinkUri.host) { DeepLinkRoute.Onramp.host -> onrampDeepLink.create(coroutineScope, queryParams) @@ -103,7 +103,11 @@ internal class DeepLinkFactory @Inject constructor( DeepLinkRoute.Buy.host -> buyDeepLink.create(coroutineScope) DeepLinkRoute.Referral.host -> referralDeepLink.create() DeepLinkRoute.Wallet.host -> walletDeepLink.create() - DeepLinkRoute.TokenDetails.host -> tokenDetailsDeepLink.create(coroutineScope, queryParams) + DeepLinkRoute.TokenDetails.host -> tokenDetailsDeepLink.create( + coroutineScope = coroutineScope, + queryParams = queryParams, + isFromOnNewIntent = isFromOnNewIntent, + ) DeepLinkRoute.Staking.host -> stakingDeepLink.create(coroutineScope, queryParams) else -> { Timber.i( diff --git a/app/src/test/kotlin/com/tangem/tap/routing/utils/DeepLinkFactoryTest.kt b/app/src/test/kotlin/com/tangem/tap/routing/utils/DeepLinkFactoryTest.kt index f13bfa3ad8..40a82fad7e 100644 --- a/app/src/test/kotlin/com/tangem/tap/routing/utils/DeepLinkFactoryTest.kt +++ b/app/src/test/kotlin/com/tangem/tap/routing/utils/DeepLinkFactoryTest.kt @@ -44,13 +44,14 @@ class DeepLinkFactoryTest { every { create() } returns mockk() } private val tokenDetailsDeepLinkFactory = mockk(relaxed = true) { - every { create(any(), any()) } returns mockk() + every { create(any(), any(), any()) } returns mockk() } private val stakingDeepLinkFactory = mockk(relaxed = true) { every { create(any(), any()) } returns mockk() } private val mockedUri = mockk(relaxed = true) + private val isFromOnNewIntent: Boolean = false private lateinit var testDispatcher: TestDispatcher private lateinit var testScope: TestScope @@ -101,7 +102,7 @@ class DeepLinkFactoryTest { every { mockedUri.getQueryParameter("param") } returns "value" // Set permittedAppRoute to true - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) deepLinkFactory.checkRoutingReadiness(AppRoute.Wallet) advanceUntilIdle() @@ -120,7 +121,7 @@ class DeepLinkFactoryTest { every { mockedUri.queryParameterNames } returns setOf("param") every { mockedUri.getQueryParameter("param") } returns "value" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) deepLinkFactory.checkRoutingReadiness(AppRoute.Initial) advanceUntilIdle() @@ -138,7 +139,7 @@ class DeepLinkFactoryTest { every { mockedUri.getQueryParameter("param") } returns "value" deepLinkFactory.checkRoutingReadiness(AppRoute.Wallet) - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() @@ -153,7 +154,7 @@ class DeepLinkFactoryTest { every { mockedUri.host } returns "" deepLinkFactory.checkRoutingReadiness(AppRoute.Wallet) - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() @@ -167,7 +168,7 @@ class DeepLinkFactoryTest { every { mockedUri.scheme } returns "https" every { mockedUri.host } returns "example.com" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() @@ -178,7 +179,7 @@ class DeepLinkFactoryTest { referralDeepLinkFactory.create() walletConnectDeepLinkFactory.create(any()) walletDeepLinkFactory.create() - tokenDetailsDeepLinkFactory.create(any(), any()) + tokenDetailsDeepLinkFactory.create(any(), any(), any()) } } @@ -193,27 +194,39 @@ class DeepLinkFactoryTest { // Test Onramp every { mockedUri.host } returns "onramp" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { onrampDeepLinkFactory.create(eq(testScope), eq(mapOf("param" to "value"))) } // Test Sell every { mockedUri.host } returns "redirect_sell" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { sellDeepLinkFactory.create(eq(testScope), eq(mapOf("param" to "value"))) } // Test Token Details every { mockedUri.host } returns "token" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() - verify { tokenDetailsDeepLinkFactory.create(eq(testScope), eq(mapOf("param" to "value"))) } + verify { + tokenDetailsDeepLinkFactory.create( + eq(testScope), + eq(mapOf("param" to "value")), + eq(isFromOnNewIntent), + ) + } // Test Staking every { mockedUri.host } returns "staking" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() - verify { tokenDetailsDeepLinkFactory.create(eq(testScope), eq(mapOf("param" to "value"))) } + verify { + tokenDetailsDeepLinkFactory.create( + eq(testScope), + eq(mapOf("param" to "value")), + eq(isFromOnNewIntent), + ) + } // Reset params every { mockedUri.queryParameterNames } returns emptySet() @@ -221,19 +234,19 @@ class DeepLinkFactoryTest { // Test Buy every { mockedUri.host } returns "redirect" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { buyDeepLinkFactory.create(eq(testScope)) } // Test Referral every { mockedUri.host } returns "referral" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { referralDeepLinkFactory.create() } // Test Wallet every { mockedUri.host } returns "main" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { walletDeepLinkFactory.create() } } @@ -244,7 +257,7 @@ class DeepLinkFactoryTest { every { mockedUri.host } returns "unknown" deepLinkFactory.checkRoutingReadiness(AppRoute.Wallet) - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() @@ -255,7 +268,7 @@ class DeepLinkFactoryTest { referralDeepLinkFactory.create() walletConnectDeepLinkFactory.create(any()) walletDeepLinkFactory.create() - tokenDetailsDeepLinkFactory.create(any(), any()) + tokenDetailsDeepLinkFactory.create(any(), any(), any()) } } @@ -270,7 +283,7 @@ class DeepLinkFactoryTest { every { mockedUri.getQueryParameter("quote") } returns "O'Brien" deepLinkFactory.checkRoutingReadiness(AppRoute.Wallet) - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { onrampDeepLinkFactory.create(eq(testScope), eq(mapOf("safe" to "ok"))) } @@ -286,49 +299,49 @@ class DeepLinkFactoryTest { every { mockedUri.query } returns "safe=ok" every { mockedUri.queryParameterNames } returns setOf("safe") every { mockedUri.getQueryParameter("safe") } returns "ok" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { onrampDeepLinkFactory.create(eq(testScope), eq(mapOf("safe" to "ok"))) } every { mockedUri.query } returns "param123=ok" every { mockedUri.queryParameterNames } returns setOf("param123") every { mockedUri.getQueryParameter("param123") } returns "ok" - deepLinkFactory.handleDeeplink(mockedUri, testScope) + deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent) advanceUntilIdle() verify { onrampDeepLinkFactory.create(eq(testScope), eq(mapOf("param123" to "ok"))) } every { mockedUri.query } returns "unsafe=