Updated on 2026-08-14
This commit is contained in:
parent
69deadf5fe
commit
23264bc7f0
29 changed files with 667 additions and 271 deletions
|
|
@ -9,7 +9,7 @@ import java.math.BigDecimal
|
|||
/**
|
||||
* Network status for storage in the local cache. Supports two types - the [Verified] and [NoAccount].
|
||||
*
|
||||
* @see [com.tangem.domain.tokens.model.NetworkStatus]
|
||||
* @see [com.tangem.domain.models.network.NetworkStatus]
|
||||
*/
|
||||
@JsonClass(generateAdapter = true, generator = PolymorphicAdapterType.NAME_POLYMORPHIC_ADAPTER)
|
||||
sealed interface NetworkStatusDM {
|
||||
|
|
@ -41,8 +41,8 @@ sealed interface NetworkStatusDM {
|
|||
@Json(name = "derivation_path") override val derivationPath: DerivationPath,
|
||||
@Json(name = "selected_address") override val selectedAddress: String,
|
||||
@Json(name = "available_addresses") override val availableAddresses: Set<Address>,
|
||||
@Json(name = "amounts") val amounts: Map<String, BigDecimal>,
|
||||
@Json(name = "yield_supply_statuses") val yieldSupplyStatuses: Map<String, YieldSupplyStatus?> = emptyMap(),
|
||||
@Json(name = "amounts") val amounts: List<CurrencyAmount>,
|
||||
@Json(name = "yield_supply_statuses") val yieldSupplyStatuses: List<YieldSupplyStatus>,
|
||||
) : NetworkStatusDM
|
||||
|
||||
/**
|
||||
|
|
@ -107,10 +107,44 @@ sealed interface NetworkStatusDM {
|
|||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CurrencyAmount(
|
||||
@Json(name = "id") val id: CurrencyId,
|
||||
@Json(name = "amount") val amount: BigDecimal,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class YieldSupplyStatus(
|
||||
@Json(name = "id") val id: CurrencyId,
|
||||
@Json(name = "is_active") val isActive: Boolean,
|
||||
@Json(name = "is_initialized") val isInitialized: Boolean,
|
||||
@Json(name = "is_allowed_to_spend") val isAllowedToSpend: Boolean,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CurrencyId(
|
||||
@Json(name = "value") val value: String,
|
||||
) {
|
||||
|
||||
companion object Companion {
|
||||
|
||||
const val CONTRACT_ADDRESS_DELIMITER = '\u2693' // ⚓
|
||||
|
||||
fun createCoinId(coinId: String): CurrencyId {
|
||||
return CurrencyId(value = coinId)
|
||||
}
|
||||
|
||||
fun createTokenId(rawTokenId: String?, contractAddress: String): CurrencyId {
|
||||
return CurrencyId(
|
||||
value = buildString {
|
||||
if (rawTokenId != null) {
|
||||
append(rawTokenId)
|
||||
}
|
||||
append(CONTRACT_ADDRESS_DELIMITER)
|
||||
append(contractAddress)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,9 +64,15 @@ class NetworkStatusDMSerializationTest {
|
|||
NetworkStatusDM.Address("0x123456", NetworkStatusDM.Address.Type.Primary),
|
||||
NetworkStatusDM.Address("0xabcdef", NetworkStatusDM.Address.Type.Secondary),
|
||||
),
|
||||
amounts = mapOf("ETH" to BigDecimal("1.2345")),
|
||||
yieldSupplyStatuses = mapOf(
|
||||
"ETH" to NetworkStatusDM.YieldSupplyStatus(
|
||||
amounts = listOf(
|
||||
NetworkStatusDM.CurrencyAmount(
|
||||
id = NetworkStatusDM.CurrencyId.createCoinId("ethereum"),
|
||||
amount = BigDecimal("1.2345"),
|
||||
),
|
||||
),
|
||||
yieldSupplyStatuses = listOf(
|
||||
NetworkStatusDM.YieldSupplyStatus(
|
||||
id = NetworkStatusDM.CurrencyId.createCoinId("ethereum"),
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
|
|
@ -91,9 +97,15 @@ class NetworkStatusDMSerializationTest {
|
|||
NetworkStatusDM.Address("0x123456", NetworkStatusDM.Address.Type.Primary),
|
||||
NetworkStatusDM.Address("0xabcdef", NetworkStatusDM.Address.Type.Secondary),
|
||||
),
|
||||
amounts = mapOf("ETH" to BigDecimal("1.2345")),
|
||||
yieldSupplyStatuses = mapOf(
|
||||
"ETH" to NetworkStatusDM.YieldSupplyStatus(
|
||||
amounts = listOf(
|
||||
NetworkStatusDM.CurrencyAmount(
|
||||
id = NetworkStatusDM.CurrencyId.createCoinId("ethereum"),
|
||||
amount = BigDecimal("1.2345"),
|
||||
),
|
||||
),
|
||||
yieldSupplyStatuses = listOf(
|
||||
NetworkStatusDM.YieldSupplyStatus(
|
||||
id = NetworkStatusDM.CurrencyId.createCoinId("ethereum"),
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
|
|
|
|||
|
|
@ -81,7 +81,10 @@ private fun getCurrencyIdBody(network: Network): CurrencyIdBody {
|
|||
rawId = network.rawId,
|
||||
derivationPath = path.value,
|
||||
)
|
||||
is Network.DerivationPath.Card,
|
||||
is Network.DerivationPath.Card -> CurrencyIdBody.NetworkIdWithDerivationPath(
|
||||
rawId = network.rawId,
|
||||
derivationPath = path.value,
|
||||
)
|
||||
is Network.DerivationPath.None,
|
||||
-> CurrencyIdBody.NetworkId(network.rawId)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ dependencies {
|
|||
|
||||
// region Project - Libs
|
||||
implementation(projects.libs.blockchainSdk)
|
||||
implementation(tangemDeps.blockchain) { exclude(module = "joda-time") }
|
||||
// endregion
|
||||
|
||||
// region DI
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toCoinId
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.CurrencyId
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.CurrencyId.Companion.CONTRACT_ADDRESS_DELIMITER
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.utils.converter.TwoWayConverter
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Suffix as CurrencyIdSuffix
|
||||
|
||||
/**
|
||||
* Converts between [CurrencyId] and [CryptoCurrency.ID].
|
||||
*
|
||||
* @property rawNetworkId the raw network ID associated with the currency
|
||||
* @property derivationPath the derivation path used for the network
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class CurrencyIdConverter(
|
||||
private val rawNetworkId: String,
|
||||
private val derivationPath: Network.DerivationPath,
|
||||
) : TwoWayConverter<CurrencyId, CryptoCurrency.ID> {
|
||||
|
||||
override fun convert(value: CurrencyId): CryptoCurrency.ID {
|
||||
val suffixParts = value.value.split(CONTRACT_ADDRESS_DELIMITER)
|
||||
|
||||
val rawId = suffixParts.getOrNull(0)
|
||||
val contractAddress = suffixParts.getOrNull(1)
|
||||
|
||||
return if (contractAddress.isNullOrBlank()) {
|
||||
getCoinId(
|
||||
coinId = rawId.takeUnless { it.isNullOrBlank() }
|
||||
?: error("Coin id is null for $rawNetworkId with $derivationPath"),
|
||||
)
|
||||
} else {
|
||||
getTokenId(
|
||||
rawTokenId = rawId?.ifBlank { null },
|
||||
contractAddress = contractAddress,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertBack(value: CryptoCurrency.ID): CurrencyId {
|
||||
return if (value.isCoin) {
|
||||
CurrencyId.createCoinId(
|
||||
coinId = Blockchain.fromId(value.rawNetworkId).toCoinId(),
|
||||
)
|
||||
} else {
|
||||
CurrencyId.createTokenId(
|
||||
rawTokenId = value.rawCurrencyId?.value,
|
||||
contractAddress = requireNotNull(value.contractAddress) {
|
||||
"Token contractAddress is null for token id: $this"
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCoinId(coinId: String): CryptoCurrency.ID {
|
||||
return CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.COIN_PREFIX,
|
||||
body = getCurrencyIdBody(),
|
||||
suffix = CurrencyIdSuffix.RawID(rawId = coinId),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getTokenId(rawTokenId: String?, contractAddress: String): CryptoCurrency.ID {
|
||||
val suffix = if (rawTokenId == null) {
|
||||
CurrencyIdSuffix.ContractAddress(contractAddress)
|
||||
} else {
|
||||
CurrencyIdSuffix.RawID(rawTokenId, contractAddress)
|
||||
}
|
||||
|
||||
return CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = getCurrencyIdBody(),
|
||||
suffix = suffix,
|
||||
)
|
||||
}
|
||||
|
||||
private fun getCurrencyIdBody(): CryptoCurrency.ID.Body {
|
||||
return when (derivationPath) {
|
||||
is Network.DerivationPath.Card -> {
|
||||
CryptoCurrency.ID.Body.NetworkIdWithDerivationPath(
|
||||
rawId = rawNetworkId,
|
||||
derivationPath = derivationPath.value,
|
||||
)
|
||||
}
|
||||
is Network.DerivationPath.Custom -> {
|
||||
CryptoCurrency.ID.Body.NetworkIdWithDerivationPath(
|
||||
rawId = rawNetworkId,
|
||||
derivationPath = derivationPath.value,
|
||||
)
|
||||
}
|
||||
is Network.DerivationPath.None -> CryptoCurrency.ID.Body.NetworkId(rawNetworkId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +1,46 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.CurrencyAmount
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.utils.converter.TwoWayConverter
|
||||
import com.tangem.utils.extensions.mapNotNullValues
|
||||
import java.math.BigDecimal
|
||||
|
||||
private typealias AmountsDataModel = Map<String, BigDecimal>
|
||||
private typealias AmountsDataModel = List<CurrencyAmount>
|
||||
private typealias AmountsDomainModel = Map<CryptoCurrency.ID, NetworkStatus.Amount>
|
||||
|
||||
/**
|
||||
* Converter from [AmountsDataModel] to [AmountsDomainModel] and vice versa
|
||||
*
|
||||
* @param rawNetworkId the raw network ID associated with the currency
|
||||
* @param derivationPath the derivation path used for the network
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal object NetworkAmountsConverter : TwoWayConverter<AmountsDataModel, AmountsDomainModel> {
|
||||
internal class NetworkAmountsConverter(
|
||||
rawNetworkId: String,
|
||||
derivationPath: Network.DerivationPath,
|
||||
) : TwoWayConverter<AmountsDataModel, AmountsDomainModel> {
|
||||
|
||||
private val currencyIdConverter = CurrencyIdConverter(rawNetworkId, derivationPath)
|
||||
|
||||
override fun convert(value: AmountsDataModel): AmountsDomainModel {
|
||||
return value
|
||||
.mapKeys { CryptoCurrency.ID.fromValue(value = it.key) }
|
||||
.mapValues { (_, amount) -> NetworkStatus.Amount.Loaded(value = amount) }
|
||||
return value.associate {
|
||||
val currencyId = currencyIdConverter.convert(value = it.id)
|
||||
val amount = NetworkStatus.Amount.Loaded(value = it.amount)
|
||||
|
||||
currencyId to amount
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertBack(value: AmountsDomainModel): AmountsDataModel {
|
||||
return value
|
||||
.mapKeys { (id, _) -> id.value }
|
||||
.mapNotNullValues { (_, amount) ->
|
||||
when (amount) {
|
||||
is NetworkStatus.Amount.Loaded -> amount.value
|
||||
is NetworkStatus.Amount.NotFound -> null
|
||||
}
|
||||
}
|
||||
return value.mapNotNull {
|
||||
val amount = it.value as? NetworkStatus.Amount.Loaded ?: return@mapNotNull null
|
||||
|
||||
CurrencyAmount(
|
||||
id = currencyIdConverter.convertBack(value = it.key),
|
||||
amount = amount.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,14 +15,22 @@ internal object NetworkStatusDataModelConverter : Converter<NetworkStatus, Netwo
|
|||
return when (val status = value.value) {
|
||||
is NetworkStatus.Verified -> {
|
||||
val address = NetworkAddressConverter.convertBack(value = status.address)
|
||||
val amountsConverter = NetworkAmountsConverter(
|
||||
rawNetworkId = value.network.rawId,
|
||||
derivationPath = value.network.derivationPath,
|
||||
)
|
||||
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
||||
rawNetworkId = value.network.rawId,
|
||||
derivationPath = value.network.derivationPath,
|
||||
)
|
||||
|
||||
NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(value = value.network.rawId),
|
||||
derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath),
|
||||
selectedAddress = address.selectedAddress,
|
||||
availableAddresses = address.addresses,
|
||||
amounts = NetworkAmountsConverter.convertBack(value = status.amounts),
|
||||
yieldSupplyStatuses = NetworkYieldSupplyStatusConverter.convertBack(status.yieldSupplyStatuses),
|
||||
amounts = amountsConverter.convertBack(value = status.amounts),
|
||||
yieldSupplyStatuses = yieldSupplyStatusConverter.convertBack(status.yieldSupplyStatuses),
|
||||
)
|
||||
}
|
||||
is NetworkStatus.NoAccount -> {
|
||||
|
|
|
|||
|
|
@ -2,45 +2,43 @@ package com.tangem.data.networks.converters
|
|||
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
|
||||
import com.tangem.utils.converter.TwoWayConverter
|
||||
import com.tangem.utils.extensions.mapNotNullValues
|
||||
|
||||
private typealias YieldSupplyStatusDataModel = Map<String, NetworkStatusDM.YieldSupplyStatus?>
|
||||
private typealias YieldSupplyStatusDataModel = List<NetworkStatusDM.YieldSupplyStatus>
|
||||
private typealias YieldSupplyStatusDomainModel = Map<CryptoCurrency.ID, YieldSupplyStatus?>
|
||||
|
||||
internal object NetworkYieldSupplyStatusConverter :
|
||||
TwoWayConverter<YieldSupplyStatusDataModel, YieldSupplyStatusDomainModel> {
|
||||
internal class NetworkYieldSupplyStatusConverter(
|
||||
rawNetworkId: String,
|
||||
derivationPath: Network.DerivationPath,
|
||||
) : TwoWayConverter<YieldSupplyStatusDataModel, YieldSupplyStatusDomainModel> {
|
||||
|
||||
private val currencyIdConverter = CurrencyIdConverter(rawNetworkId, derivationPath)
|
||||
|
||||
override fun convert(value: YieldSupplyStatusDataModel): YieldSupplyStatusDomainModel {
|
||||
return value
|
||||
.mapKeys { CryptoCurrency.ID.fromValue(value = it.key) }
|
||||
.mapValues { (_, yieldSupplyStatus) ->
|
||||
if (yieldSupplyStatus != null) {
|
||||
YieldSupplyStatus(
|
||||
isActive = yieldSupplyStatus.isActive,
|
||||
isInitialized = yieldSupplyStatus.isInitialized,
|
||||
isAllowedToSpend = yieldSupplyStatus.isAllowedToSpend,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
return value.associate {
|
||||
val id = currencyIdConverter.convert(value = it.id)
|
||||
val status = YieldSupplyStatus(
|
||||
isActive = it.isActive,
|
||||
isInitialized = it.isInitialized,
|
||||
isAllowedToSpend = it.isAllowedToSpend,
|
||||
)
|
||||
|
||||
id to status
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertBack(value: YieldSupplyStatusDomainModel): YieldSupplyStatusDataModel {
|
||||
return value
|
||||
.mapKeys { (id, _) -> id.value }
|
||||
.mapNotNullValues { (_, yieldSupplyStatus) ->
|
||||
if (yieldSupplyStatus != null) {
|
||||
NetworkStatusDM.YieldSupplyStatus(
|
||||
isActive = yieldSupplyStatus.isActive,
|
||||
isInitialized = yieldSupplyStatus.isInitialized,
|
||||
isAllowedToSpend = yieldSupplyStatus.isAllowedToSpend,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
return value.mapNotNull { (currencyId, yieldSupplyStatus) ->
|
||||
if (yieldSupplyStatus == null) return@mapNotNull null
|
||||
|
||||
NetworkStatusDM.YieldSupplyStatus(
|
||||
id = currencyIdConverter.convertBack(value = currencyId),
|
||||
isActive = yieldSupplyStatus.isActive,
|
||||
isInitialized = yieldSupplyStatus.isInitialized,
|
||||
isAllowedToSpend = yieldSupplyStatus.isAllowedToSpend,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,14 +22,26 @@ internal object SimpleNetworkStatusConverter : Converter<NetworkStatusDM, Simple
|
|||
),
|
||||
)
|
||||
|
||||
val derivationPath = NetworkDerivationPathConverter.convert(value = value.derivationPath)
|
||||
|
||||
val amountsConverter = NetworkAmountsConverter(
|
||||
rawNetworkId = value.networkId.value,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
|
||||
val yieldSupplyStatusConverter = NetworkYieldSupplyStatusConverter(
|
||||
rawNetworkId = value.networkId.value,
|
||||
derivationPath = derivationPath,
|
||||
)
|
||||
|
||||
val status = when (value) {
|
||||
is NetworkStatusDM.Verified -> {
|
||||
NetworkStatus.Verified(
|
||||
address = address,
|
||||
amounts = NetworkAmountsConverter.convert(value = value.amounts),
|
||||
amounts = amountsConverter.convert(value = value.amounts),
|
||||
pendingTransactions = emptyMap(),
|
||||
source = StatusSource.CACHE,
|
||||
yieldSupplyStatuses = NetworkYieldSupplyStatusConverter.convert(value = value.yieldSupplyStatuses),
|
||||
yieldSupplyStatuses = yieldSupplyStatusConverter.convert(value = value.yieldSupplyStatuses),
|
||||
)
|
||||
}
|
||||
is NetworkStatusDM.NoAccount -> {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ internal object NetworkDataModule {
|
|||
dispatchers: CoroutineDispatcherProvider,
|
||||
): NetworksStatusesStore {
|
||||
return DefaultNetworksStatusesStore(
|
||||
context = context,
|
||||
runtimeStore = RuntimeSharedStore(),
|
||||
persistenceDataStore = DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
|
|
@ -47,7 +48,7 @@ internal object NetworkDataModule {
|
|||
types = mapWithStringKeyTypes(valueTypes = setTypes<NetworkStatusDM>()),
|
||||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "networks_statuses") },
|
||||
produceFile = { context.dataStoreFile(fileName = "networks_statuses_2") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
),
|
||||
dispatchers = dispatchers,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.data.networks.store
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.tangem.data.networks.converters.NetworkStatusDataModelConverter
|
||||
import com.tangem.data.networks.converters.SimpleNetworkStatusConverter
|
||||
|
|
@ -20,6 +21,7 @@ import kotlinx.coroutines.flow.firstOrNull
|
|||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
internal typealias WalletIdWithSimpleStatus = Map<String, Set<SimpleNetworkStatus>>
|
||||
internal typealias WalletIdWithStatusDM = Map<String, Set<NetworkStatusDM>>
|
||||
|
|
@ -27,11 +29,13 @@ internal typealias WalletIdWithStatusDM = Map<String, Set<NetworkStatusDM>>
|
|||
/**
|
||||
* Default implementation of [NetworksStatusesStore]
|
||||
*
|
||||
* @param context context
|
||||
* @property runtimeStore runtime store
|
||||
* @property persistenceDataStore persistence store
|
||||
* @param dispatchers dispatchers
|
||||
*/
|
||||
internal class DefaultNetworksStatusesStore(
|
||||
context: Context,
|
||||
private val runtimeStore: RuntimeSharedStore<WalletIdWithSimpleStatus>,
|
||||
private val persistenceDataStore: DataStore<WalletIdWithStatusDM>,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -41,6 +45,16 @@ internal class DefaultNetworksStatusesStore(
|
|||
|
||||
init {
|
||||
scope.launch {
|
||||
try {
|
||||
val oldFile = File(context.filesDir, "datastore/networks_statuses")
|
||||
|
||||
if (oldFile.exists()) {
|
||||
oldFile.delete()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while deleting old networks statuses datastore file")
|
||||
}
|
||||
|
||||
val cachedStatuses = persistenceDataStore.data.firstOrNull() ?: return@launch
|
||||
|
||||
runtimeStore.store(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,190 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.utils.ProvideTestModels
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.CurrencyId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class CurrencyIdConverterTest {
|
||||
|
||||
private val rawNetworkId = "ETH"
|
||||
private val derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0")
|
||||
private val derivationPathHashCode = "-1843072795"
|
||||
private val converter = CurrencyIdConverter(rawNetworkId = rawNetworkId, derivationPath = derivationPath)
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
inner class Convert {
|
||||
|
||||
@ParameterizedTest
|
||||
@ProvideTestModels
|
||||
fun convert(model: ConvertModel) {
|
||||
// Act
|
||||
val actual = runCatching { converter.convert(value = model.value) }
|
||||
|
||||
// Assert
|
||||
actual
|
||||
.onSuccess {
|
||||
Truth.assertThat(it).isEqualTo(model.expected.getOrNull())
|
||||
}
|
||||
.onFailure {
|
||||
val expected = model.expected.exceptionOrNull()!!
|
||||
|
||||
Truth.assertThat(it).isInstanceOf(expected::class.java)
|
||||
Truth.assertThat(it).hasMessageThat().isEqualTo(expected.message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun provideTestModels(): Collection<ConvertModel> = listOf(
|
||||
// create coin id
|
||||
ConvertModel(
|
||||
value = CurrencyId.createCoinId("ethereum"),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(value = "coin⟨ETH→$derivationPathHashCode⟩ethereum"),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createCoinId(""),
|
||||
expected = Result.failure(
|
||||
IllegalStateException("Coin id is null for $rawNetworkId with $derivationPath"),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createCoinId(" "),
|
||||
expected = Result.failure(
|
||||
IllegalStateException("Coin id is null for $rawNetworkId with $derivationPath"),
|
||||
),
|
||||
),
|
||||
// create token id
|
||||
ConvertModel(
|
||||
value = CurrencyId.createTokenId(
|
||||
rawTokenId = "usdt",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩usdt⚓0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createTokenId(
|
||||
rawTokenId = null,
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createTokenId(
|
||||
rawTokenId = "",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createTokenId(
|
||||
rawTokenId = " ",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createTokenId(
|
||||
rawTokenId = "usdt",
|
||||
contractAddress = "",
|
||||
),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(value = "coin⟨ETH→$derivationPathHashCode⟩usdt"),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = CurrencyId.createTokenId(
|
||||
rawTokenId = "usdt",
|
||||
contractAddress = " ",
|
||||
),
|
||||
expected = Result.success(
|
||||
CryptoCurrency.ID.fromValue(value = "coin⟨ETH→$derivationPathHashCode⟩usdt"),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
inner class ConvertBack {
|
||||
|
||||
@ParameterizedTest
|
||||
@ProvideTestModels
|
||||
fun convertBack(model: ConvertBackModel) {
|
||||
// Act
|
||||
val actual = runCatching { converter.convertBack(value = model.value) }
|
||||
|
||||
// Assert
|
||||
actual
|
||||
.onSuccess {
|
||||
Truth.assertThat(it).isEqualTo(model.expected.getOrNull())
|
||||
}
|
||||
.onFailure {
|
||||
val expected = model.expected.exceptionOrNull()!!
|
||||
|
||||
Truth.assertThat(it).isInstanceOf(expected::class.java)
|
||||
Truth.assertThat(it).hasMessageThat().isEqualTo(expected.message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun provideTestModels(): Collection<ConvertBackModel> = listOf(
|
||||
ConvertBackModel(
|
||||
value = CryptoCurrency.ID.fromValue("coin⟨ETH→$derivationPathHashCode⟩ethereum"),
|
||||
expected = Result.success(
|
||||
CurrencyId.createCoinId("ethereum"),
|
||||
),
|
||||
),
|
||||
ConvertBackModel(
|
||||
value = CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩usdt⚓0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
expected = Result.success(
|
||||
CurrencyId.createTokenId(
|
||||
rawTokenId = "usdt",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
),
|
||||
),
|
||||
ConvertBackModel(
|
||||
value = CryptoCurrency.ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
expected = Result.success(
|
||||
CurrencyId.createTokenId(
|
||||
rawTokenId = null,
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
data class ConvertModel(val value: CurrencyId, val expected: Result<CryptoCurrency.ID>)
|
||||
|
||||
data class ConvertBackModel(val value: CryptoCurrency.ID, val expected: Result<CurrencyId>)
|
||||
}
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.utils.ProvideTestModels
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class NetworkAddressConverterTest {
|
||||
|
||||
@Nested
|
||||
|
|
@ -18,7 +19,7 @@ internal class NetworkAddressConverterTest {
|
|||
inner class Convert {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestModels")
|
||||
@ProvideTestModels
|
||||
fun convert(model: ConvertModel) {
|
||||
// Act
|
||||
val actual = runCatching { NetworkAddressConverter.convert(value = model.value) }
|
||||
|
|
@ -190,7 +191,7 @@ internal class NetworkAddressConverterTest {
|
|||
inner class ConvertBack {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestModels")
|
||||
@ProvideTestModels
|
||||
fun convertBack(model: ConvertBackModel) {
|
||||
// Act
|
||||
val actual = NetworkAddressConverter.convertBack(value = model.value)
|
||||
|
|
|
|||
|
|
@ -1,77 +1,99 @@
|
|||
package com.tangem.data.networks.converters
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.CurrencyId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Body
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Prefix
|
||||
import com.tangem.domain.models.network.NetworkStatus.Amount
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkStatus.Amount.Loaded
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class NetworkAmountsConverterTest {
|
||||
|
||||
private val rawNetworkId = "ETH"
|
||||
private val derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0")
|
||||
private val derivationPathHashCode = "-1843072795"
|
||||
private val converter = NetworkAmountsConverter(rawNetworkId = rawNetworkId, derivationPath = derivationPath)
|
||||
|
||||
@Test
|
||||
fun convert() {
|
||||
// Arrange
|
||||
val value = mapOf(
|
||||
"coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO,
|
||||
"coin⟨ETH→12367123⟩ethereum" to BigDecimal.ONE,
|
||||
val value = listOf(
|
||||
NetworkStatusDM.CurrencyAmount(CurrencyId.createCoinId(coinId = "ethereum"), BigDecimal.ONE),
|
||||
NetworkStatusDM.CurrencyAmount(
|
||||
id = CurrencyId.createTokenId(
|
||||
rawTokenId = "usdt",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
amount = BigDecimal.ZERO,
|
||||
),
|
||||
NetworkStatusDM.CurrencyAmount(
|
||||
id = CurrencyId.createTokenId(
|
||||
rawTokenId = null,
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
amount = BigDecimal.TEN,
|
||||
),
|
||||
)
|
||||
|
||||
// Act
|
||||
val actual = NetworkAmountsConverter.convert(value)
|
||||
val actual = converter.convert(value)
|
||||
|
||||
// Assert
|
||||
val expected = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BCH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"),
|
||||
ID.fromValue("coin⟨ETH→$derivationPathHashCode⟩ethereum") to Loaded(value = BigDecimal.ONE),
|
||||
ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩usdt⚓0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
) to Loaded(value = BigDecimal.ZERO),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to Loaded(value = BigDecimal.ONE),
|
||||
ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
) to Loaded(value = BigDecimal.TEN),
|
||||
)
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
Truth.assertThat(actual).containsExactlyEntriesIn(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun convertBack() {
|
||||
// Arrange
|
||||
val value = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BCH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"),
|
||||
ID.fromValue("coin⟨ETH→$derivationPathHashCode⟩ethereum") to Loaded(value = BigDecimal.ONE),
|
||||
ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩usdt⚓0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
) to Loaded(value = BigDecimal.ZERO),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to Loaded(value = BigDecimal.ONE),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BTC"),
|
||||
suffix = ID.Suffix.RawID(rawId = "bitcoin"),
|
||||
) to Amount.NotFound,
|
||||
ID.fromValue(
|
||||
value = "token⟨ETH→$derivationPathHashCode⟩0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
) to Loaded(value = BigDecimal.TEN),
|
||||
)
|
||||
|
||||
// Act
|
||||
val actual = NetworkAmountsConverter.convertBack(value)
|
||||
val actual = converter.convertBack(value)
|
||||
|
||||
// Assert
|
||||
val expected = mapOf(
|
||||
"coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO,
|
||||
"coin⟨ETH→12367123⟩ethereum" to BigDecimal.ONE,
|
||||
val expected = listOf(
|
||||
NetworkStatusDM.CurrencyAmount(CurrencyId.createCoinId(coinId = "ethereum"), BigDecimal.ONE),
|
||||
NetworkStatusDM.CurrencyAmount(
|
||||
id = CurrencyId.createTokenId(
|
||||
rawTokenId = "usdt",
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
amount = BigDecimal.ZERO,
|
||||
),
|
||||
NetworkStatusDM.CurrencyAmount(
|
||||
id = CurrencyId.createTokenId(
|
||||
rawTokenId = null,
|
||||
contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
),
|
||||
amount = BigDecimal.TEN,
|
||||
),
|
||||
)
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
Truth.assertThat(actual).containsExactlyElementsIn(expected)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@ package com.tangem.data.networks.converters
|
|||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.utils.ProvideTestModels
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.*
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Body
|
||||
|
|
@ -14,7 +16,6 @@ import com.tangem.domain.models.network.NetworkStatus.Amount
|
|||
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
|
|
@ -26,7 +27,7 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
private val network: Network = MockCryptoCurrencyFactory().ethereum.network
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestModels")
|
||||
@ProvideTestModels
|
||||
fun convert(model: ConvertModel) {
|
||||
// Act
|
||||
val actual = NetworkStatusDataModelConverter.convert(value = model.value)
|
||||
|
|
@ -48,11 +49,7 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
),
|
||||
),
|
||||
amounts = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BCH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"),
|
||||
) to Amount.Loaded(value = BigDecimal.ZERO),
|
||||
ID.fromValue(value = "coin⟨ETH→0⟩ethereum") to Amount.Loaded(value = BigDecimal.ZERO),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BTC"),
|
||||
|
|
@ -61,11 +58,7 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
),
|
||||
pendingTransactions = mapOf(), // doesn't matter
|
||||
yieldSupplyStatuses = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BCH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"),
|
||||
) to YieldSupplyStatus(
|
||||
ID.fromValue(value = "token⟨ETH→0⟩usdt⚓0x1") to YieldSupplyStatus(
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
|
|
@ -79,22 +72,25 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
source = StatusSource.ACTUAL, // doesn't matter
|
||||
),
|
||||
),
|
||||
expected = NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
expected = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "",
|
||||
type = NetworkStatusDM.DerivationPath.Type.NONE,
|
||||
type = DerivationPath.Type.NONE,
|
||||
),
|
||||
selectedAddress = "0x123",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x123",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
),
|
||||
amounts = mapOf("coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO),
|
||||
yieldSupplyStatuses = mapOf(
|
||||
"coin⟨BCH⟩bitcoin-cash" to NetworkStatusDM.YieldSupplyStatus(
|
||||
amounts = listOf(
|
||||
CurrencyAmount(CurrencyId.createCoinId("ethereum"), BigDecimal.ZERO),
|
||||
),
|
||||
yieldSupplyStatuses = listOf(
|
||||
YieldSupplyStatus(
|
||||
id = CurrencyId.createTokenId("usdt", "0x1"),
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
|
|
@ -120,17 +116,17 @@ internal class NetworkStatusDataModelConverterTest {
|
|||
source = StatusSource.ACTUAL, // doesn't matter
|
||||
),
|
||||
),
|
||||
expected = NetworkStatusDM.NoAccount(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
expected = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "",
|
||||
type = NetworkStatusDM.DerivationPath.Type.NONE,
|
||||
type = DerivationPath.Type.NONE,
|
||||
),
|
||||
selectedAddress = "0x123",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x123",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
),
|
||||
amountToCreateAccount = BigDecimal.ONE,
|
||||
|
|
|
|||
|
|
@ -2,82 +2,74 @@ package com.tangem.data.networks.converters
|
|||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.CurrencyId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Body
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Prefix
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class NetworkYieldSupplyStatusConverterTest {
|
||||
|
||||
private val rawNetworkId = "ETH"
|
||||
private val derivationPath = Network.DerivationPath.Card(value = "m/44'/60'/0'/0/0")
|
||||
private val derivationPathHashCode = "-1843072795"
|
||||
private val converter = NetworkYieldSupplyStatusConverter(rawNetworkId, derivationPath)
|
||||
|
||||
private val domainStatus = YieldSupplyStatus(
|
||||
isActive = true,
|
||||
isInitialized = true,
|
||||
isAllowedToSpend = true,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun convert() {
|
||||
// Arrange
|
||||
val value = mapOf(
|
||||
"coin⟨ETH⟩ethereum" to NetworkStatusDM.YieldSupplyStatus(
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
),
|
||||
"coin⟨ETH→12367123⟩ethereum" to null,
|
||||
val value = listOf(
|
||||
createDataStatus(id = CurrencyId.createCoinId("ethereum")),
|
||||
createDataStatus(id = CurrencyId.createTokenId("usdt", "0x1")),
|
||||
)
|
||||
|
||||
// Act
|
||||
val actual = NetworkYieldSupplyStatusConverter.convert(value)
|
||||
val actual = converter.convert(value)
|
||||
|
||||
// Assert
|
||||
val expected = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "ETH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to YieldSupplyStatus(
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to null,
|
||||
ID.fromValue("coin⟨ETH→$derivationPathHashCode⟩ethereum") to domainStatus,
|
||||
ID.fromValue("token⟨ETH→$derivationPathHashCode⟩usdt⚓0x1") to domainStatus,
|
||||
)
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
Truth.assertThat(actual).containsExactlyEntriesIn(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun convertBack() {
|
||||
// Arrange
|
||||
val value = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "ETH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to YieldSupplyStatus(
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to null,
|
||||
ID.fromValue("coin⟨ETH→$derivationPathHashCode⟩ethereum") to domainStatus,
|
||||
ID.fromValue("token⟨ETH→$derivationPathHashCode⟩usdt⚓0x1") to domainStatus,
|
||||
ID.fromValue("token⟨ETH→$derivationPathHashCode⟩usdc⚓0x1") to null,
|
||||
)
|
||||
|
||||
// Act
|
||||
val actual = NetworkYieldSupplyStatusConverter.convertBack(value)
|
||||
val actual = converter.convertBack(value)
|
||||
|
||||
// Assert
|
||||
val expected = mapOf(
|
||||
"coin⟨ETH⟩ethereum" to NetworkStatusDM.YieldSupplyStatus(
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
),
|
||||
val expected = listOf(
|
||||
createDataStatus(id = CurrencyId.createCoinId("ethereum")),
|
||||
createDataStatus(id = CurrencyId.createTokenId("usdt", "0x1")),
|
||||
)
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
Truth.assertThat(actual).containsExactlyElementsIn(expected)
|
||||
}
|
||||
|
||||
private fun createDataStatus(id: CurrencyId): NetworkStatusDM.YieldSupplyStatus {
|
||||
return NetworkStatusDM.YieldSupplyStatus(
|
||||
id = id,
|
||||
isActive = true,
|
||||
isInitialized = true,
|
||||
isAllowedToSpend = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,12 @@ package com.tangem.data.networks.converters
|
|||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.utils.ProvideTestModels
|
||||
import com.tangem.data.networks.models.SimpleNetworkStatus
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM.*
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Body
|
||||
import com.tangem.domain.models.currency.CryptoCurrency.ID.Prefix
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
|
|
@ -15,7 +15,6 @@ import com.tangem.domain.models.network.NetworkStatus.Amount
|
|||
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
|
|
@ -27,7 +26,7 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
private val network: Network = MockCryptoCurrencyFactory().ethereum.network
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestModels")
|
||||
@ProvideTestModels
|
||||
fun convert(model: ConvertModel) {
|
||||
// Act
|
||||
val actual = runCatching { SimpleNetworkStatusConverter.convert(value = model.value) }
|
||||
|
|
@ -48,34 +47,28 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
private fun provideTestModels() = listOf(
|
||||
// region Verified
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "0x1",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
value = "0x1",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
),
|
||||
NetworkStatusDM.Address(
|
||||
value = "0x2",
|
||||
type = NetworkStatusDM.Address.Type.Secondary,
|
||||
),
|
||||
Address(value = "0x1", type = Address.Type.Primary),
|
||||
Address(value = "0x2", type = Address.Type.Secondary),
|
||||
),
|
||||
amounts = mapOf(
|
||||
"coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO,
|
||||
"coin⟨ETH→12367123⟩ethereum" to BigDecimal.ONE,
|
||||
amounts = listOf(
|
||||
CurrencyAmount(CurrencyId.createCoinId("ethereum"), BigDecimal.ZERO),
|
||||
CurrencyAmount(CurrencyId.createTokenId("usdt", "0x1"), BigDecimal.ZERO),
|
||||
),
|
||||
yieldSupplyStatuses = mapOf(
|
||||
"coin⟨ETH⟩ethereum" to NetworkStatusDM.YieldSupplyStatus(
|
||||
yieldSupplyStatuses = listOf(
|
||||
YieldSupplyStatus(
|
||||
id = CurrencyId.createCoinId("ethereum"),
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
),
|
||||
"coin⟨ETH⟩ethereum" to null,
|
||||
),
|
||||
),
|
||||
expected = SimpleNetworkStatus(
|
||||
|
|
@ -101,33 +94,16 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
),
|
||||
amounts = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "BCH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"),
|
||||
) to Amount.Loaded(value = BigDecimal.ZERO),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to Amount.Loaded(value = BigDecimal.ONE),
|
||||
ID.fromValue("coin⟨ETH→3046160⟩ethereum") to Amount.Loaded(value = BigDecimal.ZERO),
|
||||
ID.fromValue("token⟨ETH→3046160⟩usdt⚓0x1") to Amount.Loaded(value = BigDecimal.ZERO),
|
||||
),
|
||||
pendingTransactions = emptyMap(),
|
||||
yieldSupplyStatuses = mapOf(
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "ETH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to YieldSupplyStatus(
|
||||
ID.fromValue("coin⟨ETH→3046160⟩ethereum") to YieldSupplyStatus(
|
||||
isActive = false,
|
||||
isInitialized = false,
|
||||
isAllowedToSpend = false,
|
||||
),
|
||||
ID(
|
||||
prefix = Prefix.COIN_PREFIX,
|
||||
body = Body.NetworkId(rawId = "ETH"),
|
||||
suffix = ID.Suffix.RawID(rawId = "ethereum"),
|
||||
) to null,
|
||||
),
|
||||
source = StatusSource.CACHE,
|
||||
),
|
||||
|
|
@ -137,21 +113,21 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
|
||||
// region NoAccount
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.NoAccount(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "0x1",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x1",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x2",
|
||||
type = NetworkStatusDM.Address.Type.Secondary,
|
||||
type = Address.Type.Secondary,
|
||||
),
|
||||
),
|
||||
amountToCreateAccount = BigDecimal.ONE,
|
||||
|
|
@ -189,83 +165,83 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
|
||||
// region Error
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "0x1",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x2",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
),
|
||||
amounts = emptyMap(),
|
||||
yieldSupplyStatuses = emptyMap(),
|
||||
amounts = emptyList(),
|
||||
yieldSupplyStatuses = emptyList(),
|
||||
),
|
||||
expected = Result.failure(
|
||||
exception = IllegalArgumentException("Selected address must not be null"),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "0x1",
|
||||
availableAddresses = setOf(),
|
||||
amounts = emptyMap(),
|
||||
yieldSupplyStatuses = emptyMap(),
|
||||
amounts = emptyList(),
|
||||
yieldSupplyStatuses = emptyList(),
|
||||
),
|
||||
expected = Result.failure(
|
||||
exception = IllegalArgumentException("Selected address must not be null"),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.Verified(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = Verified(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x1",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x2",
|
||||
type = NetworkStatusDM.Address.Type.Secondary,
|
||||
type = Address.Type.Secondary,
|
||||
),
|
||||
),
|
||||
amounts = emptyMap(),
|
||||
yieldSupplyStatuses = emptyMap(),
|
||||
amounts = emptyList(),
|
||||
yieldSupplyStatuses = emptyList(),
|
||||
),
|
||||
expected = Result.failure(
|
||||
exception = IllegalArgumentException("Selected address must not be null"),
|
||||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.NoAccount(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x1",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x2",
|
||||
type = NetworkStatusDM.Address.Type.Secondary,
|
||||
type = Address.Type.Secondary,
|
||||
),
|
||||
),
|
||||
amountToCreateAccount = BigDecimal.ONE,
|
||||
|
|
@ -276,17 +252,17 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.NoAccount(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "0x1",
|
||||
availableAddresses = setOf(
|
||||
NetworkStatusDM.Address(
|
||||
Address(
|
||||
value = "0x2",
|
||||
type = NetworkStatusDM.Address.Type.Primary,
|
||||
type = Address.Type.Primary,
|
||||
),
|
||||
),
|
||||
amountToCreateAccount = BigDecimal.ONE,
|
||||
|
|
@ -297,11 +273,11 @@ internal class SimpleNetworkStatusConverterTest {
|
|||
),
|
||||
),
|
||||
ConvertModel(
|
||||
value = NetworkStatusDM.NoAccount(
|
||||
networkId = NetworkStatusDM.ID(network.rawId),
|
||||
derivationPath = NetworkStatusDM.DerivationPath(
|
||||
value = NoAccount(
|
||||
networkId = ID(network.rawId),
|
||||
derivationPath = DerivationPath(
|
||||
value = "card",
|
||||
type = NetworkStatusDM.DerivationPath.Type.CARD,
|
||||
type = DerivationPath.Type.CARD,
|
||||
),
|
||||
selectedAddress = "0x1",
|
||||
availableAddresses = setOf(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.data.networks.toSimple
|
|||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ internal class GetTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ internal class InitializationTest {
|
|||
every { persistenceStore.data } returns emptyFlow()
|
||||
|
||||
DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
@ -44,6 +45,7 @@ internal class InitializationTest {
|
|||
val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
@ -66,6 +68,7 @@ internal class InitializationTest {
|
|||
}
|
||||
|
||||
DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -27,6 +28,7 @@ internal class ParameterizedStoreStatusTest(private val model: Model) {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -27,6 +28,7 @@ internal class ParameterizedStoreSuccessTest(private val model: Model) {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
|||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -26,6 +27,7 @@ internal class ParameterizedStoreTest(private val model: Model) {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -24,6 +25,7 @@ internal class SetSourceAsCacheTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -24,6 +25,7 @@ internal class SetSourceAsOnlyCacheTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
|||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -24,6 +25,7 @@ internal class StoreStatusTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
|||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -23,6 +24,7 @@ internal class StoreSuccessTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
|||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -23,6 +24,7 @@ internal class StoreTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.domain.models.network.NetworkAddress
|
|||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -27,6 +28,7 @@ internal class UpdateStatusSourceTest {
|
|||
private val persistenceStore = MockStateDataStore<WalletIdWithStatusDM>(default = emptyMap())
|
||||
|
||||
private val store = DefaultNetworksStatusesStore(
|
||||
context = mockk(),
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
|
|
|
|||
|
|
@ -108,6 +108,10 @@ sealed class CryptoCurrency {
|
|||
is Body.NetworkIdWithDerivationPath -> body.rawId
|
||||
}
|
||||
|
||||
/** Flag indicating whether the cryptocurrency is a coin */
|
||||
val isCoin: Boolean
|
||||
get() = prefix == Prefix.COIN_PREFIX
|
||||
|
||||
/**
|
||||
* Represents the different types of prefixes that can be associated with a cryptocurrency ID.
|
||||
* These prefixes can help in quickly categorizing the type of cryptocurrency.
|
||||
|
|
@ -131,16 +135,16 @@ sealed class CryptoCurrency {
|
|||
/** The value of the body. */
|
||||
abstract val value: String
|
||||
|
||||
/**
|
||||
* Represents a raw network ID.
|
||||
* Should be used for cryptocurrencies that do not support a derivation path.
|
||||
*/
|
||||
@Serializable
|
||||
/** Represents a raw network ID. */
|
||||
data class NetworkId(val rawId: String) : Body() {
|
||||
override val value: String get() = rawId
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a raw network ID with a network derivation path.
|
||||
* Should be used for a cryptocurrencies with custom derivation path.
|
||||
*/
|
||||
/** Represents a raw network ID with a network derivation path */
|
||||
@Serializable
|
||||
data class NetworkIdWithDerivationPath(
|
||||
val rawId: String,
|
||||
|
|
@ -227,9 +231,9 @@ sealed class CryptoCurrency {
|
|||
* Example:
|
||||
* 1. coin⟨BCH⟩bitcoin-cash
|
||||
* 2. coin⟨ETH→12367123⟩ethereum
|
||||
* 3. token⟨ETH→12367123⟩usdt⚓0xdAC17F958D2ee523a2206206994597C13D831ec7
|
||||
*/
|
||||
fun fromValue(value: String): ID {
|
||||
// ID(value='coin⟨BCH⟩bitcoin-cash'
|
||||
val parts = value.split(PREFIX_DELIMITER, SUFFIX_DELIMITER)
|
||||
|
||||
require(value = parts.size == ID_PARTS_COUNT) { "Invalid ID format: $value" }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue