Updated on 2026-08-14
This commit is contained in:
parent
fc223990a4
commit
9fd13fdc46
11 changed files with 149 additions and 176 deletions
|
|
@ -73,7 +73,7 @@ class AppsFlyerDeepLinkListener @Inject constructor(
|
|||
private fun storeConversionData(refcode: String, campaign: String?) {
|
||||
coroutineScope.launch {
|
||||
mutex.withLock {
|
||||
appsFlyerConversionStore.store(
|
||||
appsFlyerConversionStore.storeIfAbsent(
|
||||
value = AppsFlyerConversionData(refcode = refcode, campaign = campaign),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ class AppsFlyerClient @AssistedInject constructor(
|
|||
setAppId(context.packageName)
|
||||
setDebugLog(true)
|
||||
|
||||
init(apiKey, ConversionListener, context)
|
||||
|
||||
subscribeForDeepLink(appsFlyerDeepLinkListener)
|
||||
|
||||
init(apiKey, ConversionListener, context)
|
||||
|
||||
Timber.i("Starting AppsFlyer SDK")
|
||||
start(context, apiKey, InitializationListener)
|
||||
Timber.i("AppsFlyer SDK started")
|
||||
|
|
|
|||
|
|
@ -39,57 +39,57 @@ class AppsFlyerDeepLinkListenerTest {
|
|||
fun onDeepLinking(model: OnDeepLinkingModel) = runTest {
|
||||
listener.onDeepLinking(p0 = model.deepLinkResult)
|
||||
|
||||
if (model.shouldStore) {
|
||||
val value = AppsFlyerConversionData(refcode = SUCCESS_REFCODE, campaign = SUCCESS_CAMPAIGN)
|
||||
coVerify { appsFlyerConversionStore.store(value = value) }
|
||||
} else {
|
||||
coVerify(inverse = true) { appsFlyerConversionStore.store(value = any()) }
|
||||
}
|
||||
if (model.shouldStore) {
|
||||
val value = AppsFlyerConversionData(refcode = SUCCESS_REFCODE, campaign = SUCCESS_CAMPAIGN)
|
||||
coVerify { appsFlyerConversionStore.storeIfAbsent(value = value) }
|
||||
} else {
|
||||
coVerify(inverse = true) { appsFlyerConversionStore.storeIfAbsent(value = any()) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun provideTestModels(): List<OnDeepLinkingModel> {
|
||||
return listOf(
|
||||
// DeepLinkResult.Status.NOT_FOUND
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = DeepLinkResult(null, null),
|
||||
shouldStore = false,
|
||||
return listOf(
|
||||
// DeepLinkResult.Status.NOT_FOUND
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = DeepLinkResult(null, null),
|
||||
shouldStore = false,
|
||||
),
|
||||
// DeepLinkResult.Status.ERROR
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = DeepLinkResult(null, DeepLinkResult.Error.NETWORK),
|
||||
shouldStore = false,
|
||||
),
|
||||
// DeepLinkResult.Status.FOUND
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(
|
||||
deepLinkValue = AppsFlyerDeepLinkListener.REFERRAL_DEEP_LINK_VALUE,
|
||||
refcode = SUCCESS_REFCODE,
|
||||
campaign = SUCCESS_CAMPAIGN,
|
||||
),
|
||||
// DeepLinkResult.Status.ERROR
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = DeepLinkResult(null, DeepLinkResult.Error.NETWORK),
|
||||
shouldStore = false,
|
||||
shouldStore = true,
|
||||
),
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(
|
||||
deepLinkValue = AppsFlyerDeepLinkListener.REFERRAL_DEEP_LINK_VALUE,
|
||||
refcode = "",
|
||||
campaign = SUCCESS_CAMPAIGN,
|
||||
),
|
||||
// DeepLinkResult.Status.FOUND
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(
|
||||
deepLinkValue = AppsFlyerDeepLinkListener.REFERRAL_DEEP_LINK_VALUE,
|
||||
refcode = SUCCESS_REFCODE,
|
||||
campaign = SUCCESS_CAMPAIGN,
|
||||
),
|
||||
shouldStore = true,
|
||||
shouldStore = false,
|
||||
),
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(
|
||||
deepLinkValue = AppsFlyerDeepLinkListener.REFERRAL_DEEP_LINK_VALUE,
|
||||
refcode = null,
|
||||
campaign = SUCCESS_CAMPAIGN,
|
||||
),
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(
|
||||
deepLinkValue = AppsFlyerDeepLinkListener.REFERRAL_DEEP_LINK_VALUE,
|
||||
refcode = "",
|
||||
campaign = SUCCESS_CAMPAIGN,
|
||||
),
|
||||
shouldStore = false,
|
||||
),
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(
|
||||
deepLinkValue = AppsFlyerDeepLinkListener.REFERRAL_DEEP_LINK_VALUE,
|
||||
refcode = null,
|
||||
campaign = SUCCESS_CAMPAIGN,
|
||||
),
|
||||
shouldStore = false,
|
||||
),
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(deepLinkValue = "some_other_deep_link_value"),
|
||||
shouldStore = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
shouldStore = false,
|
||||
),
|
||||
OnDeepLinkingModel(
|
||||
deepLinkResult = createFoundDeepLink(deepLinkValue = "some_other_deep_link_value"),
|
||||
shouldStore = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
data class OnDeepLinkingModel(
|
||||
val deepLinkResult: DeepLinkResult,
|
||||
|
|
|
|||
|
|
@ -7,4 +7,6 @@ interface AppsFlyerConversionStore {
|
|||
suspend fun get(): AppsFlyerConversionData?
|
||||
|
||||
suspend fun store(value: AppsFlyerConversionData)
|
||||
|
||||
suspend fun storeIfAbsent(value: AppsFlyerConversionData)
|
||||
}
|
||||
|
|
@ -29,6 +29,17 @@ internal class DefaultAppsFlyerConversionStore(
|
|||
appPreferencesStore.storeObject(KEY, dto)
|
||||
}
|
||||
|
||||
override suspend fun storeIfAbsent(value: AppsFlyerConversionData) {
|
||||
Timber.i("Storing conversion data to store if absent: $value")
|
||||
|
||||
val dto = appPreferencesStore.getObjectSyncOrNull<ConversionDataDTO>(KEY)
|
||||
|
||||
if (dto == null) {
|
||||
Timber.i("Conversion data is absent, storing $value")
|
||||
appPreferencesStore.storeObject(KEY, ConversionDataConverter.convert(value))
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
val KEY = stringPreferencesKey("APPS_FLYER_CONVERSION_DATA")
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
package com.tangem.data.wallets
|
||||
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import arrow.core.Option
|
||||
import arrow.core.toOption
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.BindWalletsByReferralCodeBody
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
|
|
@ -17,7 +13,6 @@ import com.tangem.datasource.local.userwallet.UserWalletsStore
|
|||
import com.tangem.domain.wallets.models.AppsFlyerConversionData
|
||||
import com.tangem.domain.wallets.repository.WalletsPromoRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
@ -25,69 +20,57 @@ internal class DefaultWalletsPromoRepository(
|
|||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : WalletsPromoRepository {
|
||||
|
||||
override suspend fun getConversionData(): Option<AppsFlyerConversionData> {
|
||||
return runSuspendCatching { appsFlyerConversionStore.get() }.getOrNull().toOption()
|
||||
override suspend fun bindRefcodeWithWallets(conversionData: AppsFlyerConversionData) = withContext(dispatchers.io) {
|
||||
val savedBindingData = getSavedBindingData()
|
||||
|
||||
when {
|
||||
savedBindingData == null -> {
|
||||
// first time binding
|
||||
saveBindingData(refcode = conversionData.refcode, campaign = conversionData.campaign)
|
||||
bind(refcode = conversionData.refcode, campaign = conversionData.campaign)
|
||||
}
|
||||
!savedBindingData.isDone -> {
|
||||
// try again
|
||||
bind(refcode = savedBindingData.refcode, campaign = savedBindingData.campaign)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun saveConversionData(refcode: String, campaign: String?) {
|
||||
val data = AppsFlyerConversionData(refcode = refcode, campaign = campaign)
|
||||
override suspend fun retryBindRefcodeWithWallets() {
|
||||
val savedBindingData = getSavedBindingData()
|
||||
|
||||
appsFlyerConversionStore.store(data)
|
||||
if (savedBindingData != null) {
|
||||
bind(refcode = savedBindingData.refcode, campaign = savedBindingData.campaign)
|
||||
} else {
|
||||
Timber.i("retryBindRefcodeWithWallets: Binding data isn't required")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun bindRefcodeWithWallets(refcode: String, campaign: String?) = withContext(dispatchers.io) {
|
||||
private suspend fun getSavedBindingData(): ReferralWalletsBindingData? {
|
||||
return appPreferencesStore.getObjectSyncOrNull(key = REFERRAL_WALLETS_BINDING_DATA_KEY)
|
||||
}
|
||||
|
||||
private suspend fun saveBindingData(refcode: String, campaign: String?) {
|
||||
val bindingData = ReferralWalletsBindingData(refcode = refcode, campaign = campaign, isDone = false)
|
||||
|
||||
appPreferencesStore.storeObject(key = REFERRAL_WALLETS_BINDING_DATA_KEY, value = bindingData)
|
||||
}
|
||||
|
||||
private suspend fun bind(refcode: String, campaign: String?) {
|
||||
val walletIds = userWalletsStore.userWalletsSync.map { it.walletId.stringValue }
|
||||
|
||||
val result = tangemTechApi.bindWalletsByReferralCode(
|
||||
body = BindWalletsByReferralCodeBody(
|
||||
walletIds = walletIds,
|
||||
refcode = refcode,
|
||||
campaign = campaign,
|
||||
),
|
||||
body = BindWalletsByReferralCodeBody(walletIds = walletIds, refcode = refcode, campaign = campaign),
|
||||
)
|
||||
|
||||
val bindingData = ReferralWalletsBindingData(
|
||||
refcode = refcode,
|
||||
campaign = campaign,
|
||||
isDone = result is ApiResponse.Success,
|
||||
)
|
||||
if (result is ApiResponse.Success) {
|
||||
val successData = ReferralWalletsBindingData(refcode = refcode, campaign = campaign, isDone = true)
|
||||
|
||||
appPreferencesStore.storeObject(key = REFERRAL_WALLETS_BINDING_DATA_KEY, value = bindingData)
|
||||
|
||||
result.getOrThrow()
|
||||
}
|
||||
|
||||
override suspend fun bindSavedRefcodeWithWallets(): AppsFlyerConversionData {
|
||||
val bindingData = appPreferencesStore.getObjectSyncOrNull<ReferralWalletsBindingData>(
|
||||
key = REFERRAL_WALLETS_BINDING_DATA_KEY,
|
||||
)
|
||||
|
||||
if (bindingData == null) {
|
||||
val exception = IllegalStateException("No saved referral wallets binding data found")
|
||||
Timber.e(exception)
|
||||
throw exception
|
||||
appPreferencesStore.storeObject(key = REFERRAL_WALLETS_BINDING_DATA_KEY, value = successData)
|
||||
}
|
||||
|
||||
val conversionData = AppsFlyerConversionData(
|
||||
refcode = bindingData.refcode,
|
||||
campaign = bindingData.campaign,
|
||||
)
|
||||
|
||||
if (bindingData.isDone) {
|
||||
Timber.i("Referral code ${bindingData.refcode} already bound with wallets")
|
||||
return conversionData
|
||||
}
|
||||
|
||||
bindRefcodeWithWallets(
|
||||
refcode = bindingData.refcode,
|
||||
campaign = bindingData.campaign,
|
||||
)
|
||||
|
||||
return conversionData
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
|
|
|||
|
|
@ -75,14 +75,12 @@ internal object WalletsDataModule {
|
|||
appPreferencesStore: AppPreferencesStore,
|
||||
tangemTechApi: TangemTechApi,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): WalletsPromoRepository {
|
||||
return DefaultWalletsPromoRepository(
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
tangemTechApi = tangemTechApi,
|
||||
userWalletsStore = userWalletsStore,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
package com.tangem.domain.wallets.repository
|
||||
|
||||
import arrow.core.Option
|
||||
import com.tangem.domain.wallets.models.AppsFlyerConversionData
|
||||
|
||||
interface WalletsPromoRepository {
|
||||
|
||||
suspend fun getConversionData(): Option<AppsFlyerConversionData>
|
||||
suspend fun bindRefcodeWithWallets(conversionData: AppsFlyerConversionData)
|
||||
|
||||
suspend fun saveConversionData(refcode: String, campaign: String?)
|
||||
|
||||
suspend fun bindRefcodeWithWallets(refcode: String, campaign: String?)
|
||||
|
||||
suspend fun bindSavedRefcodeWithWallets(): AppsFlyerConversionData
|
||||
suspend fun retryBindRefcodeWithWallets()
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import arrow.core.raise.ensure
|
||||
import com.tangem.domain.wallets.models.AppsFlyerConversionData
|
||||
import com.tangem.domain.wallets.repository.WalletsPromoRepository
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
|
|
@ -17,59 +15,21 @@ class BindRefcodeWithWalletUseCase @Inject constructor(
|
|||
|
||||
private val mutex = Mutex()
|
||||
|
||||
suspend operator fun invoke(refcode: String, campaign: String?): Either<Error, Unit> = either {
|
||||
ensure(refcode.isNotBlank()) { Error.InvalidRefcode }
|
||||
|
||||
suspend operator fun invoke(conversionData: AppsFlyerConversionData): Either<Throwable, Unit> = either {
|
||||
mutex.withLock {
|
||||
checkSavedRefcode()
|
||||
|
||||
bindRefcode(refcode = refcode, campaign = campaign)
|
||||
|
||||
saveConversionData(refcode = refcode, campaign = campaign)
|
||||
catch(
|
||||
block = { walletsPromoRepository.bindRefcodeWithWallets(conversionData) },
|
||||
catch = ::raise,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun retry(): Either<Error, Unit> = either {
|
||||
suspend fun retry(): Either<Throwable, Unit> = either {
|
||||
mutex.withLock {
|
||||
val conversionData = tryBindRefcodeAgain()
|
||||
|
||||
saveConversionData(refcode = conversionData.refcode, campaign = conversionData.campaign)
|
||||
catch(
|
||||
block = { walletsPromoRepository.retryBindRefcodeWithWallets() },
|
||||
catch = ::raise,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Raise<Error>.checkSavedRefcode() {
|
||||
walletsPromoRepository.getConversionData().onSome {
|
||||
raise(Error.RefcodeAlreadySaved)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Raise<Error>.bindRefcode(refcode: String, campaign: String?) {
|
||||
catch(
|
||||
block = { walletsPromoRepository.bindRefcodeWithWallets(refcode, campaign) },
|
||||
catch = { raise(Error.DataError(it)) },
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun Raise<Error>.tryBindRefcodeAgain(): AppsFlyerConversionData {
|
||||
return catch(
|
||||
block = { walletsPromoRepository.bindSavedRefcodeWithWallets() },
|
||||
catch = { raise(Error.DataError(it)) },
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun Raise<Error>.saveConversionData(refcode: String, campaign: String?) {
|
||||
catch(
|
||||
block = { walletsPromoRepository.saveConversionData(refcode, campaign) },
|
||||
catch = { raise(Error.DataError(it)) },
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface Error {
|
||||
|
||||
data object InvalidRefcode : Error
|
||||
|
||||
data object RefcodeAlreadySaved : Error
|
||||
|
||||
data class DataError(val throwable: Throwable) : Error
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import com.tangem.core.ui.extensions.mask
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.GlobalLoadingMessage
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||
|
|
@ -18,6 +19,7 @@ import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer
|
|||
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier
|
||||
import com.tangem.domain.wallets.PromoCodeActivationResult
|
||||
import com.tangem.domain.wallets.PromoCodeActivationResult.*
|
||||
import com.tangem.domain.wallets.models.AppsFlyerConversionData
|
||||
import com.tangem.domain.wallets.models.errors.ActivatePromoCodeError
|
||||
import com.tangem.domain.wallets.usecase.ActivateBitcoinPromocodeUseCase
|
||||
import com.tangem.domain.wallets.usecase.BindRefcodeWithWalletUseCase
|
||||
|
|
@ -46,6 +48,7 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
|
|||
private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier,
|
||||
private val activateBitcoinPromocodeUseCase: ActivateBitcoinPromocodeUseCase,
|
||||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||
private val appsFlyerConversionStore: AppsFlyerConversionStore,
|
||||
private val bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -62,6 +65,8 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
|
|||
} else {
|
||||
findSelectedWallet(promoCode)
|
||||
}
|
||||
|
||||
saveAndBindRefcode()
|
||||
}
|
||||
|
||||
private fun findSelectedWallet(promoCode: String) {
|
||||
|
|
@ -92,13 +97,9 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
|
|||
|
||||
Timber.tag(LOG_TAG).d("All user network statuses ${networkStatuses?.size}")
|
||||
|
||||
val cryptoCurrencies = multiWalletCryptoCurrenciesSupplier
|
||||
.getSyncOrNull(
|
||||
MultiWalletCryptoCurrenciesProducer.Params(
|
||||
userWallet
|
||||
.walletId,
|
||||
),
|
||||
)
|
||||
val cryptoCurrencies = multiWalletCryptoCurrenciesSupplier.getSyncOrNull(
|
||||
MultiWalletCryptoCurrenciesProducer.Params(userWallet.walletId),
|
||||
)
|
||||
|
||||
Timber.tag(LOG_TAG).d("All user cryptoCurrencies on main ${cryptoCurrencies?.size}")
|
||||
|
||||
|
|
@ -106,8 +107,7 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
|
|||
Timber.tag(LOG_TAG).d("BitcoinCurrency $bitcoinCurrency")
|
||||
|
||||
val bitcoinStatus = networkStatuses?.firstOrNull { status ->
|
||||
status.network.id == bitcoinCurrency
|
||||
?.network?.id
|
||||
status.network.id == bitcoinCurrency?.network?.id
|
||||
}
|
||||
Timber.tag(LOG_TAG).d("BitcoinStatus $bitcoinStatus")
|
||||
|
||||
|
|
@ -129,13 +129,6 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
|
|||
"Start activation promoCode ${promoCode.mask()} address ${bitcoinAddress.mask()}",
|
||||
)
|
||||
|
||||
if (refcode != null) {
|
||||
launch {
|
||||
bindRefcodeWithWalletUseCase(refcode = refcode, campaign = campaign)
|
||||
.onLeft { Timber.e("Failed to bind refcode with wallets: $it") }
|
||||
}
|
||||
}
|
||||
|
||||
activatePromoCode(bitcoinAddress = bitcoinAddress, promoCode = promoCode)
|
||||
} else {
|
||||
uiMessageSender.send(GlobalLoadingMessage(false))
|
||||
|
|
@ -196,6 +189,19 @@ internal class DefaultPromoDeeplinkHandler @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun saveAndBindRefcode() {
|
||||
scope.launch(dispatchers.default) {
|
||||
if (!refcode.isNullOrBlank()) {
|
||||
val conversionData = AppsFlyerConversionData(refcode = refcode, campaign = campaign)
|
||||
|
||||
appsFlyerConversionStore.storeIfAbsent(value = conversionData)
|
||||
|
||||
bindRefcodeWithWalletUseCase(conversionData)
|
||||
.onLeft { Timber.e("Failed to bind refcode with wallets: $it") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : PromoDeeplinkHandler.Factory {
|
||||
override fun create(
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerConversionStore
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
|
|
@ -70,6 +71,9 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
@MockK
|
||||
private lateinit var bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase
|
||||
|
||||
@MockK
|
||||
private lateinit var appsFlyerConversionStore: AppsFlyerConversionStore
|
||||
|
||||
private lateinit var messages: MutableList<UiMessage>
|
||||
|
||||
@Before
|
||||
|
|
@ -110,6 +114,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -143,6 +148,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
|
@ -175,6 +181,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
|
@ -213,6 +220,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -255,6 +263,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -372,6 +381,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -404,6 +414,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -445,6 +456,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -507,6 +519,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -560,6 +573,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -619,6 +633,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -677,6 +692,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -731,6 +747,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
@ -785,6 +802,7 @@ class DefaultPromoDeeplinkHandlerTest {
|
|||
activateBitcoinPromocodeUseCase = activateBitcoinPromocodeUseCase,
|
||||
getSelectedWalletSyncUseCase = getSelectedWalletSyncUseCase,
|
||||
bindRefcodeWithWalletUseCase = bindRefcodeWithWalletUseCase,
|
||||
appsFlyerConversionStore = appsFlyerConversionStore,
|
||||
analyticsEventsHandler = analyticsEventHandler,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue