Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-20 18:38:01 +04:00
parent ea3cbd0648
commit fbace5ed35
6 changed files with 233 additions and 19 deletions

View file

@ -4,7 +4,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.tangem.datasource.local.network.entity.NetworkStatusDM.NoAccount
import com.tangem.datasource.local.network.entity.NetworkStatusDM.Verified
import com.tangem.domain.models.network.Network
import dev.onenowy.moshipolymorphicadapter.PolymorphicAdapterType
import dev.onenowy.moshipolymorphicadapter.annotations.NameLabel
import java.math.BigDecimal
@ -13,10 +13,11 @@ import java.math.BigDecimal
*
* @see [com.tangem.domain.tokens.model.NetworkStatus]
*/
@JsonClass(generateAdapter = true, generator = PolymorphicAdapterType.NAME_POLYMORPHIC_ADAPTER)
sealed interface NetworkStatusDM {
/** Network id */
val networkId: Network.ID
val networkId: ID
/** Derivation path */
val derivationPath: DerivationPath
@ -38,7 +39,7 @@ sealed interface NetworkStatusDM {
*/
@NameLabel("amounts")
data class Verified(
@Json(name = "network_id") override val networkId: Network.ID,
@Json(name = "network_id") override val networkId: ID,
@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>,
@ -57,7 +58,7 @@ sealed interface NetworkStatusDM {
*/
@NameLabel("amount_to_create_account")
data class NoAccount(
@Json(name = "network_id") override val networkId: Network.ID,
@Json(name = "network_id") override val networkId: ID,
@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>,
@ -65,6 +66,11 @@ sealed interface NetworkStatusDM {
@Json(name = "error_message") val errorMessage: String,
) : NetworkStatusDM
@JsonClass(generateAdapter = true)
data class ID(
@Json(name = "value") val value: String,
)
@JsonClass(generateAdapter = true)
data class DerivationPath(
@Json(name = "value") val value: String,

View file

@ -0,0 +1,195 @@
package com.tangem.datasource.local.network.entity
import com.google.common.truth.Truth
import com.squareup.moshi.Moshi
import com.squareup.moshi.adapter
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.tangem.datasource.api.common.adapter.BigDecimalAdapter
import dev.onenowy.moshipolymorphicadapter.NamePolymorphicAdapterFactory
import org.junit.Test
import java.math.BigDecimal
/**
[REDACTED_AUTHOR]
*/
class NetworkStatusDMSerializationTest {
private val moshi = Moshi.Builder()
.add(
NamePolymorphicAdapterFactory.of(NetworkStatusDM::class.java)
.withSubtype(NetworkStatusDM.Verified::class.java, "amounts")
.withSubtype(NetworkStatusDM.NoAccount::class.java, "amount_to_create_account"),
)
.add(BigDecimalAdapter())
.addLast(KotlinJsonAdapterFactory())
.build()
@OptIn(ExperimentalStdlibApi::class)
private val adapter = moshi.adapter<NetworkStatusDM>()
@Test
fun `deserialize JSON to Verified`() {
// Arrange
val json = """
{
"network_id": { "value": "ETH" },
"derivation_path": {
"value": "m/44'/60'/0'/0/0",
"type": "card"
},
"selected_address": "0x123456",
"available_addresses": [
{ "value": "0x123456", "type": "primary" },
{ "value": "0xabcdef", "type": "secondary" }
],
"amounts": { "ETH": "1.2345" }
}
""".trimIndent()
// Act
val result = adapter.fromJson(json)
// Assert
val expected = NetworkStatusDM.Verified(
networkId = NetworkStatusDM.ID("ETH"),
derivationPath = NetworkStatusDM.DerivationPath(
value = "m/44'/60'/0'/0/0",
type = NetworkStatusDM.DerivationPath.Type.CARD,
),
selectedAddress = "0x123456",
availableAddresses = setOf(
NetworkStatusDM.Address("0x123456", NetworkStatusDM.Address.Type.Primary),
NetworkStatusDM.Address("0xabcdef", NetworkStatusDM.Address.Type.Secondary),
),
amounts = mapOf("ETH" to BigDecimal("1.2345")),
)
Truth.assertThat(result).isEqualTo(expected)
}
@Test
fun `serialize Verified to JSON`() {
// Arrange
val model = NetworkStatusDM.Verified(
networkId = NetworkStatusDM.ID("ETH"),
derivationPath = NetworkStatusDM.DerivationPath(
value = "m/44'/60'/0'/0/0",
type = NetworkStatusDM.DerivationPath.Type.CARD,
),
selectedAddress = "0x123456",
availableAddresses = setOf(
NetworkStatusDM.Address("0x123456", NetworkStatusDM.Address.Type.Primary),
NetworkStatusDM.Address("0xabcdef", NetworkStatusDM.Address.Type.Secondary),
),
amounts = mapOf("ETH" to BigDecimal("1.2345")),
)
// Act
val actual = adapter.toJson(model)
// Assert
val expected = """
{
"network_id": { "value": "ETH" },
"derivation_path": {
"value": "m/44'/60'/0'/0/0",
"type": "card"
},
"selected_address": "0x123456",
"available_addresses": [
{ "value": "0x123456", "type": "primary" },
{ "value": "0xabcdef", "type": "secondary" }
],
"amounts": { "ETH": "1.2345" }
}
""".stripJsonWhitespace()
Truth.assertThat(actual).isEqualTo(expected)
}
@Test
fun `deserialize JSON to NoAccount`() {
// Arrange
val json = """
{
"network_id": { "value": "ETH" },
"derivation_path": {
"value": "m/44'/60'/0'/0/0",
"type": "card"
},
"selected_address": "0x123456",
"available_addresses": [
{ "value": "0x123456", "type": "primary" },
{ "value": "0xabcdef", "type": "secondary" }
],
"amount_to_create_account": "0.05",
"error_message": "Account not found"
}
""".trimIndent()
// Act
val result = adapter.fromJson(json)
// Assert
val expected = NetworkStatusDM.NoAccount(
networkId = NetworkStatusDM.ID("ETH"),
derivationPath = NetworkStatusDM.DerivationPath(
value = "m/44'/60'/0'/0/0",
type = NetworkStatusDM.DerivationPath.Type.CARD,
),
selectedAddress = "0x123456",
availableAddresses = setOf(
NetworkStatusDM.Address("0x123456", NetworkStatusDM.Address.Type.Primary),
NetworkStatusDM.Address("0xabcdef", NetworkStatusDM.Address.Type.Secondary),
),
amountToCreateAccount = BigDecimal("0.05"),
errorMessage = "Account not found",
)
Truth.assertThat(result).isEqualTo(expected)
}
@Test
fun `serialize NoAccount to JSON`() {
// Arrange
val model = NetworkStatusDM.NoAccount(
networkId = NetworkStatusDM.ID("ETH"),
derivationPath = NetworkStatusDM.DerivationPath(
value = "m/44'/60'/0'/0/0",
type = NetworkStatusDM.DerivationPath.Type.CARD,
),
selectedAddress = "0x123456",
availableAddresses = setOf(
NetworkStatusDM.Address("0x123456", NetworkStatusDM.Address.Type.Primary),
NetworkStatusDM.Address("0xabcdef", NetworkStatusDM.Address.Type.Secondary),
),
amountToCreateAccount = BigDecimal("0.05"),
errorMessage = "error",
)
// Act
val actual = adapter.toJson(model)
// Assert
val expected = """
{
"network_id": { "value": "ETH" },
"derivation_path": {
"value": "m/44'/60'/0'/0/0",
"type": "card"
},
"selected_address": "0x123456",
"available_addresses": [
{ "value": "0x123456", "type": "primary" },
{ "value": "0xabcdef", "type": "secondary" }
],
"amount_to_create_account": "0.05",
"error_message": "error"
}
""".stripJsonWhitespace()
Truth.assertThat(actual).isEqualTo(expected)
}
private fun String.stripJsonWhitespace(): String = replace(regex = "\\s".toRegex(), replacement = "")
}