Updated on 2026-08-14
This commit is contained in:
parent
59117bf97c
commit
1b33e6b02e
5 changed files with 389 additions and 1 deletions
|
|
@ -9,6 +9,10 @@ android {
|
|||
namespace = "com.tangem.data.networks"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// region Project - Core
|
||||
implementation(projects.core.datasource)
|
||||
|
|
@ -52,7 +56,8 @@ dependencies {
|
|||
|
||||
// region Tests
|
||||
testImplementation(deps.test.coroutine)
|
||||
testImplementation(deps.test.junit)
|
||||
testImplementation(deps.test.junit5)
|
||||
testRuntimeOnly(deps.test.junit5.engine)
|
||||
testImplementation(deps.test.mockk)
|
||||
testImplementation(deps.test.truth)
|
||||
testImplementation(projects.common.test)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
package com.tangem.data.networks.repository
|
||||
|
||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.networks.store.NetworksStatusesStoreV2
|
||||
import com.tangem.data.networks.store.storeStatus
|
||||
import com.tangem.data.networks.utils.NetworkStatusFactory
|
||||
import com.tangem.domain.networks.repository.NetworksRepository
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Default implementation of [NetworksRepository]
|
||||
*
|
||||
* @property cardCryptoCurrencyFactory card crypto currency factory
|
||||
* @property walletManagersFacade wallet managers facade
|
||||
* @property networksStatusesStore networks statuses store
|
||||
* @property dispatchers dispatchers
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultNetworksRepository(
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val networksStatusesStore: NetworksStatusesStoreV2,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : NetworksRepository {
|
||||
|
||||
override suspend fun fetchPendingTransactions(userWalletId: UserWalletId, network: Network) {
|
||||
withContext(dispatchers.default) {
|
||||
val currencies = runCatching {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
}
|
||||
.getOrElse {
|
||||
Timber.e(it, "Unable to create wallet currencies")
|
||||
return@withContext
|
||||
}
|
||||
|
||||
fetchPendingTransactions(userWalletId = userWalletId, network = network, currencies = currencies)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getNetworkAddresses(
|
||||
userWalletId: UserWalletId,
|
||||
network: Network,
|
||||
): List<CryptoCurrencyAddress> {
|
||||
return runCatching { cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network) }
|
||||
.getOrElse {
|
||||
Timber.e(it, "Unable to create wallet currencies")
|
||||
return emptyList()
|
||||
}
|
||||
.map { currency ->
|
||||
CryptoCurrencyAddress(
|
||||
cryptoCurrency = currency,
|
||||
address = getDefaultAddress(userWalletId, network),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchPendingTransactions(
|
||||
userWalletId: UserWalletId,
|
||||
network: Network,
|
||||
currencies: List<CryptoCurrency>,
|
||||
) {
|
||||
val result = withContext(dispatchers.io) {
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
}
|
||||
|
||||
val networkStatus = NetworkStatusFactory.create(
|
||||
network = network,
|
||||
updatingResult = result,
|
||||
addedCurrencies = currencies.toSet(),
|
||||
)
|
||||
|
||||
networksStatusesStore.storeStatus(userWalletId = userWalletId, status = networkStatus)
|
||||
}
|
||||
|
||||
private suspend fun getDefaultAddress(userWalletId: UserWalletId, network: Network): String {
|
||||
return withContext(dispatchers.io) {
|
||||
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = network).orEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
package com.tangem.data.networks.repository
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.domain.walletmanager.MockUpdateWalletManagerResultFactory
|
||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.networks.store.NetworksStatusesStoreV2
|
||||
import com.tangem.data.networks.store.storeStatus
|
||||
import com.tangem.data.networks.utils.NetworkStatusFactory
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class DefaultNetworksRepositoryTest {
|
||||
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory = mockk()
|
||||
private val walletManagersFacade: WalletManagersFacade = mockk()
|
||||
private val networksStatusesStore: NetworksStatusesStoreV2 = mockk(relaxUnitFun = true)
|
||||
|
||||
private val repository: DefaultNetworksRepository = DefaultNetworksRepository(
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
networksStatusesStore = networksStatusesStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
||||
@BeforeEach
|
||||
fun resetMocks() {
|
||||
clearMocks(cardCryptoCurrencyFactory, walletManagersFacade, networksStatusesStore)
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class FetchPendingTransactions {
|
||||
|
||||
@Test
|
||||
fun `walletManagersFacade returns Verified`() = runTest {
|
||||
// Arrange
|
||||
val result = updateWalletManagerResultFactory.createVerified()
|
||||
val status = result.toNetworkStatus()
|
||||
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} returns listOf(cryptoCurrency)
|
||||
|
||||
coEvery {
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
} returns result
|
||||
|
||||
coEvery { networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status) } returns Unit
|
||||
|
||||
// Act
|
||||
repository.fetchPendingTransactions(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
coVerifyOrder {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `walletManagersFacade returns NoAccount`() = runTest {
|
||||
// Arrange
|
||||
val result = updateWalletManagerResultFactory.createNoAccount()
|
||||
val status = result.toNetworkStatus()
|
||||
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} returns listOf(cryptoCurrency)
|
||||
|
||||
coEvery {
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
} returns result
|
||||
|
||||
coEvery { networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status) } returns Unit
|
||||
|
||||
// Act
|
||||
repository.fetchPendingTransactions(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
coVerifyOrder {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `walletManagersFacade returns MissedDerivation`() = runTest {
|
||||
// Arrange
|
||||
val result = UpdateWalletManagerResult.MissedDerivation
|
||||
val status = result.toNetworkStatus()
|
||||
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} returns listOf(cryptoCurrency)
|
||||
|
||||
coEvery {
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
} returns result
|
||||
|
||||
coEvery { networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status) } returns Unit
|
||||
|
||||
// Act
|
||||
repository.fetchPendingTransactions(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
coVerifyOrder {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `walletManagersFacade returns Unreachable`() = runTest {
|
||||
// Arrange
|
||||
val result = updateWalletManagerResultFactory.createUnreachableWithAddress()
|
||||
val status = result.toNetworkStatus()
|
||||
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} returns listOf(cryptoCurrency)
|
||||
|
||||
coEvery {
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
} returns result
|
||||
|
||||
coEvery { networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status) } returns Unit
|
||||
|
||||
// Act
|
||||
repository.fetchPendingTransactions(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
coVerifyOrder {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = userWalletId, network = network)
|
||||
networksStatusesStore.storeStatus(userWalletId = userWalletId, status = status)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cardCryptoCurrencyFactory throws exception`() = runTest {
|
||||
// Arrange
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} throws IllegalStateException()
|
||||
|
||||
// Act
|
||||
repository.fetchPendingTransactions(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
coVerify {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
walletManagersFacade.updatePendingTransactions(userWalletId = any(), network = any())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class GetNetworkAddresses {
|
||||
|
||||
@Test
|
||||
fun `cardCryptoCurrencyFactory create throws exception`() = runTest {
|
||||
// Arrange
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} throws IllegalStateException()
|
||||
|
||||
// Act
|
||||
val actual = repository.getNetworkAddresses(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
val expected = emptyList<CryptoCurrencyAddress>()
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerify { cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network) }
|
||||
coVerify(inverse = true) {
|
||||
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = network)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cardCryptoCurrencyFactory create returns empty list`() = runTest {
|
||||
// Arrange
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} returns emptyList()
|
||||
|
||||
// Act
|
||||
val actual = repository.getNetworkAddresses(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
val expected = emptyList<CryptoCurrencyAddress>()
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerify { cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network) }
|
||||
coVerify(inverse = true) {
|
||||
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = network)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cardCryptoCurrencyFactory create returns not empty list`() = runTest {
|
||||
// Arrange
|
||||
val currencies = listOf(cryptoCurrency)
|
||||
|
||||
coEvery {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = network)
|
||||
} returns currencies
|
||||
|
||||
coEvery {
|
||||
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = cryptoCurrency.network)
|
||||
} returns "address"
|
||||
|
||||
// Act
|
||||
val actual = repository.getNetworkAddresses(userWalletId = userWalletId, network = network)
|
||||
|
||||
// Assert
|
||||
val expected = listOf(
|
||||
CryptoCurrencyAddress(cryptoCurrency = cryptoCurrency, address = "address"),
|
||||
)
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerify {
|
||||
cardCryptoCurrencyFactory.create(userWalletId = userWalletId, network = cryptoCurrency.network)
|
||||
walletManagersFacade.getDefaultAddress(userWalletId = userWalletId, network = cryptoCurrency.network)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
val userWalletId = UserWalletId("011")
|
||||
val cryptoCurrency = MockCryptoCurrencyFactory().ethereum
|
||||
val network = MockCryptoCurrencyFactory().ethereum.network
|
||||
|
||||
val updateWalletManagerResultFactory = MockUpdateWalletManagerResultFactory()
|
||||
|
||||
fun UpdateWalletManagerResult.toNetworkStatus(): NetworkStatus {
|
||||
return NetworkStatusFactory.create(
|
||||
network = network,
|
||||
updatingResult = this,
|
||||
addedCurrencies = setOf(cryptoCurrency),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue