Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-13 15:42:15 +04:00
parent 69deadf5fe
commit 23264bc7f0
29 changed files with 667 additions and 271 deletions

View file

@ -33,6 +33,7 @@ dependencies {
// region Project - Libs
implementation(projects.libs.blockchainSdk)
implementation(tangemDeps.blockchain) { exclude(module = "joda-time") }
// endregion
// region DI

View file

@ -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)
}
}
}

View file

@ -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,
)
}
}
}

View file

@ -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 -> {

View file

@ -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,
)
}
}
}

View file

@ -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 -> {

View file

@ -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,

View file

@ -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(

View file

@ -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>)
}

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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,

View file

@ -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,
)
}
}

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),

View file

@ -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(),