diff --git a/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkAddressConverter.kt b/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkAddressConverter.kt index f3e2e962e2..d0919d7d75 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkAddressConverter.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkAddressConverter.kt @@ -6,43 +6,49 @@ import com.tangem.utils.converter.TwoWayConverter import timber.log.Timber /** - * Converter from [Set] to [NetworkAddress] and vice versa + * Converter from [NetworkAddressConverter.Value] to [NetworkAddress] and vice versa * [REDACTED_AUTHOR] */ -internal class NetworkAddressConverter( - private val selectedAddress: String, -) : TwoWayConverter, NetworkAddress> { +internal object NetworkAddressConverter : TwoWayConverter { - override fun convert(value: Set): NetworkAddress { - val defaultAddress = value - .firstOrNull { it.value == selectedAddress } + data class Value( + val selectedAddress: String, + val addresses: Set, + ) + + override fun convert(value: Value): NetworkAddress { + val defaultAddress = value.addresses + .firstOrNull { it.value == value.selectedAddress } ?.let(::toNetworkAddress) requireNotNull(defaultAddress) { "Selected address must not be null" } - return if (value.size != 1) { + return if (value.addresses.size != 1) { NetworkAddress.Selectable( defaultAddress = defaultAddress, - availableAddresses = value.mapTo(destination = hashSetOf(), transform = ::toNetworkAddress), + availableAddresses = value.addresses.mapTo(destination = hashSetOf(), transform = ::toNetworkAddress), ) } else { NetworkAddress.Single(defaultAddress = defaultAddress) } } - override fun convertBack(value: NetworkAddress): Set { - return value.availableAddresses - .map { address -> - NetworkStatusDM.Address( - value = address.value, - type = when (address.type) { - NetworkAddress.Address.Type.Primary -> NetworkStatusDM.Address.Type.Primary - NetworkAddress.Address.Type.Secondary -> NetworkStatusDM.Address.Type.Secondary - }, - ) - } - .toSet() + override fun convertBack(value: NetworkAddress): Value { + return Value( + selectedAddress = value.defaultAddress.value, + addresses = value.availableAddresses + .map { address -> + NetworkStatusDM.Address( + value = address.value, + type = when (address.type) { + NetworkAddress.Address.Type.Primary -> NetworkStatusDM.Address.Type.Primary + NetworkAddress.Address.Type.Secondary -> NetworkStatusDM.Address.Type.Secondary + }, + ) + } + .toSet(), + ) } private fun toNetworkAddress(address: NetworkStatusDM.Address): NetworkAddress.Address { diff --git a/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverter.kt b/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverter.kt index f0c3cfb572..2e2d2e966c 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverter.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverter.kt @@ -14,22 +14,24 @@ internal object NetworkStatusDataModelConverter : Converter { + val address = NetworkAddressConverter.convertBack(value = status.address) + NetworkStatusDM.Verified( networkId = value.network.id, derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath), - selectedAddress = status.address.defaultAddress.value, - availableAddresses = NetworkAddressConverter(selectedAddress = status.address.defaultAddress.value) - .convertBack(value = status.address), + selectedAddress = address.selectedAddress, + availableAddresses = address.addresses, amounts = NetworkAmountsConverter.convertBack(value = status.amounts), ) } is NetworkStatus.NoAccount -> { + val address = NetworkAddressConverter.convertBack(value = status.address) + NetworkStatusDM.NoAccount( networkId = value.network.id, derivationPath = NetworkDerivationPathConverter.convertBack(value = value.network.derivationPath), - selectedAddress = status.address.defaultAddress.value, - availableAddresses = NetworkAddressConverter(selectedAddress = status.address.defaultAddress.value) - .convertBack(value = status.address), + selectedAddress = address.selectedAddress, + availableAddresses = address.addresses, amountToCreateAccount = status.amountToCreateAccount, errorMessage = status.errorMessage, ) diff --git a/data/networks/src/main/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverter.kt b/data/networks/src/main/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverter.kt index 314a02853a..c9e794c53d 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverter.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverter.kt @@ -14,15 +14,19 @@ import com.tangem.utils.converter.Converter internal object SimpleNetworkStatusConverter : Converter { override fun convert(value: NetworkStatusDM): SimpleNetworkStatus { - val address = NetworkAddressConverter(selectedAddress = value.selectedAddress) - .convert(value = value.availableAddresses) + val address = NetworkAddressConverter.convert( + value = NetworkAddressConverter.Value( + selectedAddress = value.selectedAddress, + addresses = value.availableAddresses, + ), + ) val status = when (value) { is NetworkStatusDM.Verified -> { NetworkStatus.Verified( address = address, amounts = NetworkAmountsConverter.convert(value = value.amounts), - pendingTransactions = mapOf(), + pendingTransactions = emptyMap(), source = StatusSource.CACHE, ) } diff --git a/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkAddressConverterTest.kt b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkAddressConverterTest.kt new file mode 100644 index 0000000000..19b6a2730a --- /dev/null +++ b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkAddressConverterTest.kt @@ -0,0 +1,291 @@ +package com.tangem.data.networks.converters + +import com.google.common.truth.Truth +import com.tangem.datasource.local.network.entity.NetworkStatusDM +import com.tangem.domain.tokens.model.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] + */ +internal class NetworkAddressConverterTest { + + @Nested + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + inner class Convert { + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convert(model: ConvertModel) { + // Act + val actual = runCatching { NetworkAddressConverter.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 = listOf( + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + ), + expected = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + ).let(Result.Companion::success), + ), + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + expected = NetworkAddress.Selectable( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + availableAddresses = setOf( + NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + NetworkAddress.Address( + value = "0x2", + type = NetworkAddress.Address.Type.Secondary, + ), + ), + ).let(Result.Companion::success), + ), + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + expected = IllegalArgumentException("Selected address must not be null").let(Result.Companion::failure), + ), + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "", + type = NetworkStatusDM.Address.Type.Primary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + expected = IllegalArgumentException("Selected address must not be null").let(Result.Companion::failure), + ), + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "", + addresses = setOf( + NetworkStatusDM.Address( + value = "", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + ), + expected = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "", + type = NetworkAddress.Address.Type.Primary, + ), + ).let(Result.Companion::success), + ), + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + expected = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Secondary, + ), + ).let(Result.Companion::success), + ), + ConvertModel( + value = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Secondary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + expected = NetworkAddress.Selectable( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Secondary, + ), + availableAddresses = setOf( + NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Secondary, + ), + NetworkAddress.Address( + value = "0x2", + type = NetworkAddress.Address.Type.Secondary, + ), + ), + ).let(Result.Companion::success), + ), + ) + } + + @Nested + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + inner class ConvertBack { + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convertBack(model: ConvertBackModel) { + // Act + val actual = NetworkAddressConverter.convertBack(value = model.value) + + // Assert + Truth.assertThat(actual).isEqualTo(model.expected) + } + + private fun provideTestModels(): Collection = listOf( + ConvertBackModel( + value = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + ), + expected = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + ), + ), + ConvertBackModel( + value = NetworkAddress.Selectable( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + availableAddresses = setOf( + NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + NetworkAddress.Address( + value = "0x2", + type = NetworkAddress.Address.Type.Secondary, + ), + ), + ), + expected = NetworkAddressConverter.Value( + selectedAddress = "0x1", + addresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + ), + ConvertBackModel( + value = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "", + type = NetworkAddress.Address.Type.Primary, + ), + ), + expected = NetworkAddressConverter.Value( + selectedAddress = "", + addresses = setOf( + NetworkStatusDM.Address( + value = "", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + ), + ), + ConvertBackModel( + value = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "", + type = NetworkAddress.Address.Type.Secondary, + ), + ), + expected = NetworkAddressConverter.Value( + selectedAddress = "", + addresses = setOf( + NetworkStatusDM.Address( + value = "", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + ), + ), + ) + } + + data class ConvertModel(val value: NetworkAddressConverter.Value, val expected: Result) + + data class ConvertBackModel(val value: NetworkAddress, val expected: NetworkAddressConverter.Value) +} \ No newline at end of file diff --git a/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkAmountsConverterTest.kt b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkAmountsConverterTest.kt new file mode 100644 index 0000000000..bb02d4f48d --- /dev/null +++ b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkAmountsConverterTest.kt @@ -0,0 +1,76 @@ +package com.tangem.data.networks.converters + +import com.google.common.truth.Truth +import com.tangem.domain.tokens.model.CryptoCurrency.ID +import com.tangem.domain.tokens.model.CryptoCurrency.ID.Body +import com.tangem.domain.tokens.model.CryptoCurrency.ID.Prefix +import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus +import org.junit.jupiter.api.Test +import java.math.BigDecimal + +/** +[REDACTED_AUTHOR] + */ +internal class NetworkAmountsConverterTest { + + @Test + fun convert() { + // Arrange + val value = mapOf( + "coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO, + "coin⟨ETH→12367123⟩ethereum" to BigDecimal.ONE, + ) + + // Act + val actual = NetworkAmountsConverter.convert(value) + + // Assert + val expected = mapOf( + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkId(rawId = "BCH"), + suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ZERO), + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123), + suffix = ID.Suffix.RawID(rawId = "ethereum"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ONE), + ) + + Truth.assertThat(actual).isEqualTo(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"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ZERO), + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123), + suffix = ID.Suffix.RawID(rawId = "ethereum"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ONE), + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkId(rawId = "BTC"), + suffix = ID.Suffix.RawID(rawId = "bitcoin"), + ) to CryptoCurrencyAmountStatus.NotFound, + ) + + // Act + val actual = NetworkAmountsConverter.convertBack(value) + + // Assert + val expected = mapOf( + "coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO, + "coin⟨ETH→12367123⟩ethereum" to BigDecimal.ONE, + ) + + Truth.assertThat(actual).isEqualTo(expected) + } +} \ No newline at end of file diff --git a/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkDerivationPathConverterTest.kt b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkDerivationPathConverterTest.kt new file mode 100644 index 0000000000..e069087f9a --- /dev/null +++ b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkDerivationPathConverterTest.kt @@ -0,0 +1,103 @@ +package com.tangem.data.networks.converters + +import com.google.common.truth.Truth +import com.tangem.datasource.local.network.entity.NetworkStatusDM +import com.tangem.domain.tokens.model.Network +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] + */ +class NetworkDerivationPathConverterTest { + + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @Nested + inner class Convert { + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convert(model: ConvertModel) { + // Act + val actual = NetworkDerivationPathConverter.convert(value = model.value) + + // Assert + Truth.assertThat(actual).isEqualTo(model.expected) + } + + private fun provideTestModels(): Collection = listOf( + ConvertModel( + value = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + expected = Network.DerivationPath.Card("card"), + ), + ConvertModel( + value = NetworkStatusDM.DerivationPath( + value = "custom", + type = NetworkStatusDM.DerivationPath.Type.CUSTOM, + ), + expected = Network.DerivationPath.Custom("custom"), + ), + ConvertModel( + value = NetworkStatusDM.DerivationPath( + value = "", + type = NetworkStatusDM.DerivationPath.Type.NONE, + ), + expected = Network.DerivationPath.None, + ), + ) + } + + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @Nested + inner class ConvertBack { + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convertBack(model: ConvertBackModel) { + // Act + val actual = NetworkDerivationPathConverter.convertBack(value = model.value) + + // Assert + Truth.assertThat(actual).isEqualTo(model.expected) + } + + private fun provideTestModels(): Collection = listOf( + ConvertBackModel( + value = Network.DerivationPath.Card("card"), + expected = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + ), + ConvertBackModel( + value = Network.DerivationPath.Custom("custom"), + expected = NetworkStatusDM.DerivationPath( + value = "custom", + type = NetworkStatusDM.DerivationPath.Type.CUSTOM, + ), + ), + ConvertBackModel( + value = Network.DerivationPath.None, + expected = NetworkStatusDM.DerivationPath( + value = "", + type = NetworkStatusDM.DerivationPath.Type.NONE, + ), + ), + ) + } + + data class ConvertModel( + val value: NetworkStatusDM.DerivationPath, + val expected: Network.DerivationPath, + ) + + data class ConvertBackModel( + val value: Network.DerivationPath, + val expected: NetworkStatusDM.DerivationPath, + ) +} \ No newline at end of file diff --git a/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverterTest.kt b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverterTest.kt new file mode 100644 index 0000000000..8f00a9b734 --- /dev/null +++ b/data/networks/src/test/java/com/tangem/data/networks/converters/NetworkStatusDataModelConverterTest.kt @@ -0,0 +1,145 @@ +package com.tangem.data.networks.converters + +import com.google.common.truth.Truth +import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory +import com.tangem.datasource.local.network.entity.NetworkStatusDM +import com.tangem.domain.models.StatusSource +import com.tangem.domain.tokens.model.CryptoCurrency.ID +import com.tangem.domain.tokens.model.CryptoCurrency.ID.Body +import com.tangem.domain.tokens.model.CryptoCurrency.ID.Prefix +import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.NetworkAddress +import com.tangem.domain.tokens.model.NetworkStatus +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import java.math.BigDecimal + +/** +[REDACTED_AUTHOR] + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +internal class NetworkStatusDataModelConverterTest { + + private val network: Network = MockCryptoCurrencyFactory().ethereum.network + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convert(model: ConvertModel) { + // Act + val actual = NetworkStatusDataModelConverter.convert(value = model.value) + + // Assert + Truth.assertThat(actual).isEqualTo(model.expected) + } + + private fun provideTestModels() = listOf( + // region Verified + ConvertModel( + value = NetworkStatus( + network = network, + value = NetworkStatus.Verified( + address = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "0x123", + type = NetworkAddress.Address.Type.Primary, + ), + ), + amounts = mapOf( + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkId(rawId = "BCH"), + suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ZERO), + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkId(rawId = "BTC"), + suffix = ID.Suffix.RawID(rawId = "bitcoin"), + ) to CryptoCurrencyAmountStatus.NotFound, + ), + pendingTransactions = mapOf(), // doesn't matter + source = StatusSource.ACTUAL, // doesn't matter + ), + ), + expected = NetworkStatusDM.Verified( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "", + type = NetworkStatusDM.DerivationPath.Type.NONE, + ), + selectedAddress = "0x123", + availableAddresses = setOf( + NetworkStatusDM.Address( + value = "0x123", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + amounts = mapOf("coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO), + ), + ), + // endregion + + // region NoAccount + ConvertModel( + value = NetworkStatus( + network = network, + value = NetworkStatus.NoAccount( + address = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "0x123", + type = NetworkAddress.Address.Type.Primary, + ), + ), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + source = StatusSource.ACTUAL, // doesn't matter + ), + ), + expected = NetworkStatusDM.NoAccount( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "", + type = NetworkStatusDM.DerivationPath.Type.NONE, + ), + selectedAddress = "0x123", + availableAddresses = setOf( + NetworkStatusDM.Address( + value = "0x123", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + ), + ), + // endregion + + // region Other NetworkStatus + ConvertModel( + value = NetworkStatus(network = network, value = NetworkStatus.Unreachable(address = null)), + expected = null, + ), + ConvertModel( + value = NetworkStatus( + network = network, + value = NetworkStatus.Unreachable( + address = NetworkAddress.Single( + defaultAddress = NetworkAddress.Address( + value = "0x123", + type = NetworkAddress.Address.Type.Primary, + ), + ), + ), + ), + expected = null, + ), + ConvertModel( + value = NetworkStatus(network = network, value = NetworkStatus.MissedDerivation), + expected = null, + ), + // endregion + ) + + data class ConvertModel(val value: NetworkStatus, val expected: NetworkStatusDM?) +} \ No newline at end of file diff --git a/data/networks/src/test/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverterTest.kt b/data/networks/src/test/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverterTest.kt new file mode 100644 index 0000000000..98838ae290 --- /dev/null +++ b/data/networks/src/test/java/com/tangem/data/networks/converters/SimpleNetworkStatusConverterTest.kt @@ -0,0 +1,291 @@ +package com.tangem.data.networks.converters + +import com.google.common.truth.Truth +import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory +import com.tangem.data.networks.models.SimpleNetworkStatus +import com.tangem.datasource.local.network.entity.NetworkStatusDM +import com.tangem.domain.models.StatusSource +import com.tangem.domain.tokens.model.CryptoCurrency.ID +import com.tangem.domain.tokens.model.CryptoCurrency.ID.Body +import com.tangem.domain.tokens.model.CryptoCurrency.ID.Prefix +import com.tangem.domain.tokens.model.CryptoCurrencyAmountStatus +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.NetworkAddress +import com.tangem.domain.tokens.model.NetworkStatus +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import java.math.BigDecimal + +/** +[REDACTED_AUTHOR] + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +internal class SimpleNetworkStatusConverterTest { + + private val network: Network = MockCryptoCurrencyFactory().ethereum.network + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convert(model: ConvertModel) { + // Act + val actual = runCatching { SimpleNetworkStatusConverter.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() = listOf( + // region Verified + ConvertModel( + value = NetworkStatusDM.Verified( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.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, + ), + ), + amounts = mapOf( + "coin⟨BCH⟩bitcoin-cash" to BigDecimal.ZERO, + "coin⟨ETH→12367123⟩ethereum" to BigDecimal.ONE, + ), + ), + expected = SimpleNetworkStatus( + id = SimpleNetworkStatus.Id( + networkId = network.id, + derivationPath = Network.DerivationPath.Card(value = "card"), + ), + value = NetworkStatus.Verified( + address = NetworkAddress.Selectable( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + availableAddresses = setOf( + NetworkAddress.Address( + value = "0x2", + type = NetworkAddress.Address.Type.Secondary, + ), + NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + ), + ), + amounts = mapOf( + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkId(rawId = "BCH"), + suffix = ID.Suffix.RawID(rawId = "bitcoin-cash"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ZERO), + ID( + prefix = Prefix.COIN_PREFIX, + body = Body.NetworkIdWithDerivationPath(rawId = "ETH", derivationPathHashCode = 12367123), + suffix = ID.Suffix.RawID(rawId = "ethereum"), + ) to CryptoCurrencyAmountStatus.Loaded(value = BigDecimal.ONE), + ), + pendingTransactions = emptyMap(), + source = StatusSource.CACHE, + ), + ).let(Result.Companion::success), + ), + // endregion + + // region NoAccount + ConvertModel( + value = NetworkStatusDM.NoAccount( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.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, + ), + ), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + ), + expected = SimpleNetworkStatus( + id = SimpleNetworkStatus.Id( + networkId = network.id, + derivationPath = Network.DerivationPath.Card(value = "card"), + ), + value = NetworkStatus.NoAccount( + address = NetworkAddress.Selectable( + defaultAddress = NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + availableAddresses = setOf( + NetworkAddress.Address( + value = "0x2", + type = NetworkAddress.Address.Type.Secondary, + ), + NetworkAddress.Address( + value = "0x1", + type = NetworkAddress.Address.Type.Primary, + ), + ), + ), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + source = StatusSource.CACHE, + ), + ).let(Result.Companion::success), + ), + // endregion + + // region Error + ConvertModel( + value = NetworkStatusDM.Verified( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + selectedAddress = "0x1", + availableAddresses = setOf( + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + amounts = emptyMap(), + ), + expected = Result.failure( + exception = IllegalArgumentException("Selected address must not be null"), + ), + ), + ConvertModel( + value = NetworkStatusDM.Verified( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + selectedAddress = "0x1", + availableAddresses = setOf(), + amounts = emptyMap(), + ), + expected = Result.failure( + exception = IllegalArgumentException("Selected address must not be null"), + ), + ), + ConvertModel( + value = NetworkStatusDM.Verified( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + selectedAddress = "", + availableAddresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + amounts = emptyMap(), + ), + expected = Result.failure( + exception = IllegalArgumentException("Selected address must not be null"), + ), + ), + ConvertModel( + value = NetworkStatusDM.NoAccount( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + selectedAddress = "", + availableAddresses = setOf( + NetworkStatusDM.Address( + value = "0x1", + type = NetworkStatusDM.Address.Type.Primary, + ), + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Secondary, + ), + ), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + ), + expected = Result.failure( + exception = IllegalArgumentException("Selected address must not be null"), + ), + ), + ConvertModel( + value = NetworkStatusDM.NoAccount( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + selectedAddress = "0x1", + availableAddresses = setOf( + NetworkStatusDM.Address( + value = "0x2", + type = NetworkStatusDM.Address.Type.Primary, + ), + ), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + ), + expected = Result.failure( + exception = IllegalArgumentException("Selected address must not be null"), + ), + ), + ConvertModel( + value = NetworkStatusDM.NoAccount( + networkId = network.id, + derivationPath = NetworkStatusDM.DerivationPath( + value = "card", + type = NetworkStatusDM.DerivationPath.Type.CARD, + ), + selectedAddress = "0x1", + availableAddresses = setOf(), + amountToCreateAccount = BigDecimal.ONE, + errorMessage = "errorMessage", + ), + expected = Result.failure( + exception = IllegalArgumentException("Selected address must not be null"), + ), + ), + // endregion + ) + + data class ConvertModel(val value: NetworkStatusDM, val expected: Result) +} \ No newline at end of file diff --git a/tangem-android-tools b/tangem-android-tools index 0ed07b85e6..764c490ca8 160000 --- a/tangem-android-tools +++ b/tangem-android-tools @@ -1 +1 @@ -Subproject commit 0ed07b85e64805707b2ef6a92f42bc2c4e8b7753 +Subproject commit 764c490ca845d9b8a4be76ff834b827b45ce9ed2