Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-24 14:16:45 +05:00
parent db08399066
commit ae809ece30
28 changed files with 939 additions and 10 deletions

View file

@ -248,6 +248,17 @@
android:host="swap"
android:scheme="tangem" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="promo"
android:scheme="tangem" />
</intent-filter>
</activity>
<!-- Disable android.startup completely. Used for Worker according doc -->

View file

@ -15,6 +15,7 @@ import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
import com.tangem.features.send.v2.api.deeplink.SellRedirectDeepLinkHandler
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
import com.tangem.features.tokendetails.deeplink.TokenDetailsDeepLinkHandler
import com.tangem.features.wallet.deeplink.PromoDeeplinkHandler
import com.tangem.features.wallet.deeplink.WalletDeepLinkHandler
import com.tangem.features.walletconnect.components.deeplink.WalletConnectDeepLinkHandler
import com.tangem.utils.coroutines.JobHolder
@ -46,6 +47,7 @@ internal class DeepLinkFactory @Inject constructor(
private val buyDeepLink: BuyDeepLinkHandler.Factory,
private val sellDeepLink: SellDeepLinkHandler.Factory,
private val swapDeepLink: SwapDeepLinkHandler.Factory,
private val promoDeepLink: PromoDeeplinkHandler.Factory,
) {
private val permittedAppRoute = MutableStateFlow(false)
@ -131,6 +133,7 @@ internal class DeepLinkFactory @Inject constructor(
DeepLinkRoute.Sell.host -> sellDeepLink.create()
DeepLinkRoute.Swap.host -> swapDeepLink.create()
DeepLinkRoute.WalletConnect.host -> walletConnectDeepLink.create(deeplinkUri)
DeepLinkRoute.Promo.host -> promoDeepLink.create(coroutineScope, queryParams)
else -> {
Timber.i(
"""

View file

@ -13,6 +13,7 @@ import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
import com.tangem.features.send.v2.api.deeplink.SellRedirectDeepLinkHandler
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
import com.tangem.features.tokendetails.deeplink.TokenDetailsDeepLinkHandler
import com.tangem.features.wallet.deeplink.PromoDeeplinkHandler
import com.tangem.features.wallet.deeplink.WalletDeepLinkHandler
import com.tangem.features.walletconnect.components.deeplink.WalletConnectDeepLinkHandler
import io.mockk.every
@ -68,6 +69,10 @@ class DeepLinkFactoryTest {
every { create() } returns mockk()
}
private val promoDeepLinkFactory = mockk<PromoDeeplinkHandler.Factory>(relaxed = true) {
every { create(any(), any()) } returns mockk()
}
private val cardSdkProvider = mockk<CardSdkProvider>(relaxed = true) {
every { sdk.uiVisibility() } returns MutableStateFlow(false)
}
@ -91,6 +96,7 @@ class DeepLinkFactoryTest {
buyDeepLink = buyDeepLinkFactory,
sellDeepLink = sellDeepLinkFactory,
swapDeepLink = swapDeepLinkFactory,
promoDeepLink = promoDeepLinkFactory,
)
@OptIn(ExperimentalCoroutinesApi::class)
@ -303,13 +309,19 @@ class DeepLinkFactoryTest {
every { mockedUri.host } returns "swap"
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
advanceUntilIdle()
verify { sellDeepLinkFactory.create() }
verify { swapDeepLinkFactory.create() }
// Test Buy
every { mockedUri.host } returns "buy"
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
advanceUntilIdle()
verify { buyDeepLinkFactory.create() }
// Test Promo
every { mockedUri.host } returns "promo"
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
advanceUntilIdle()
verify { promoDeepLinkFactory.create(eq(testScope), eq(emptyMap())) }
}
@Test
@ -332,6 +344,7 @@ class DeepLinkFactoryTest {
buyDeepLinkFactory.create()
sellDeepLinkFactory.create()
swapDeepLinkFactory.create()
promoDeepLinkFactory.create(any(), any())
}
}
@ -400,4 +413,22 @@ class DeepLinkFactoryTest {
advanceUntilIdle()
verify { onrampDeepLinkFactory.create(eq(testScope), eq(emptyMap())) }
}
@Test
fun `handleTangemDeepLinks routes to promo handler`() = runTest {
every { mockedUri.scheme } returns "tangem"
every { mockedUri.host } returns "promo"
every { mockedUri.query } returns "promo_code=PROMO123"
every { mockedUri.queryParameterNames } returns setOf("promo_code")
every { mockedUri.getQueryParameter("promo_code") } returns "PROMO123"
deepLinkFactory.checkRoutingReadiness(AppRoute.Wallet)
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
advanceUntilIdle()
verify {
promoDeepLinkFactory.create(eq(testScope), eq(mapOf("promo_code" to "PROMO123")))
}
}
}