Updated on 2026-08-14
This commit is contained in:
parent
1ad2c36a79
commit
502b5c5361
4 changed files with 257 additions and 0 deletions
|
|
@ -0,0 +1,44 @@
|
|||
package com.tangem.data.networks.single
|
||||
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusProducer
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
/**
|
||||
* Default implementation of [SingleNetworkStatusProducer]
|
||||
*
|
||||
* @property params params
|
||||
* @property multiNetworkStatusSupplier multi network status supplier
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultSingleNetworkStatusProducer @AssistedInject constructor(
|
||||
@Assisted val params: SingleNetworkStatusProducer.Params,
|
||||
private val multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
|
||||
) : SingleNetworkStatusProducer {
|
||||
|
||||
override val fallback: NetworkStatus
|
||||
get() = NetworkStatus(network = params.network, value = NetworkStatus.Unreachable(address = null))
|
||||
|
||||
override fun produce(): Flow<NetworkStatus> {
|
||||
return multiNetworkStatusSupplier(
|
||||
params = MultiNetworkStatusProducer.Params(params.userWalletId),
|
||||
)
|
||||
.mapNotNull { statuses ->
|
||||
statuses.firstOrNull { it.network == params.network }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : SingleNetworkStatusProducer.Factory {
|
||||
override fun create(params: SingleNetworkStatusProducer.Params): DefaultSingleNetworkStatusProducer
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
package com.tangem.data.networks.single
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.domain.network.MockNetworkStatusFactory
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.utils.getEmittedValues
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusProducer
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultSingleNetworkStatusProducerTest {
|
||||
|
||||
private val params = SingleNetworkStatusProducer.Params(
|
||||
userWalletId = UserWalletId(stringValue = "011"),
|
||||
network = ethereum,
|
||||
)
|
||||
|
||||
private val multiNetworkStatusSupplier = mockk<MultiNetworkStatusSupplier>()
|
||||
|
||||
private val producer = DefaultSingleNetworkStatusProducer(
|
||||
params = params,
|
||||
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `test that flow is mapped for network from params`() = runTest {
|
||||
val status = MockNetworkStatusFactory.createMissedDerivation(params.network)
|
||||
val expected = flowOf(
|
||||
setOf(
|
||||
status,
|
||||
MockNetworkStatusFactory.createMissedDerivation(cardano),
|
||||
),
|
||||
)
|
||||
|
||||
val multiParams = MultiNetworkStatusProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
|
||||
val actual = producer.produce()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values.size).isEqualTo(1)
|
||||
Truth.assertThat(values).isEqualTo(listOf(status))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test that flow is updated if network status is updated`() = runTest {
|
||||
val expected = MutableSharedFlow<Set<NetworkStatus>>(replay = 2, extraBufferCapacity = 1)
|
||||
|
||||
val multiParams = MultiNetworkStatusProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
|
||||
val actual = producer.produceWithFallback()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
// first emit
|
||||
val status = MockNetworkStatusFactory.createMissedDerivation(params.network)
|
||||
expected.emit(value = setOf(status))
|
||||
|
||||
val values1 = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values1.size).isEqualTo(1)
|
||||
Truth.assertThat(values1).isEqualTo(listOf(status))
|
||||
|
||||
// second emit
|
||||
val updatedStatus = status.copy(value = NetworkStatus.Unreachable(null))
|
||||
expected.emit(value = setOf(updatedStatus))
|
||||
|
||||
val values2 = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values2.size).isEqualTo(2)
|
||||
Truth.assertThat(values2).isEqualTo(listOf(status, updatedStatus))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test that flow is filtered the same status`() = runTest {
|
||||
val expected = MutableSharedFlow<Set<NetworkStatus>>(replay = 2, extraBufferCapacity = 1)
|
||||
|
||||
val multiParams = MultiNetworkStatusProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
|
||||
val actual = producer.produceWithFallback()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
// first emit
|
||||
val status = MockNetworkStatusFactory.createMissedDerivation(params.network)
|
||||
expected.emit(value = setOf(status))
|
||||
|
||||
val values1 = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values1.size).isEqualTo(1)
|
||||
Truth.assertThat(values1).isEqualTo(listOf(status))
|
||||
|
||||
// second emit
|
||||
expected.emit(value = setOf(status))
|
||||
|
||||
val values2 = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values2.size).isEqualTo(1)
|
||||
Truth.assertThat(values2).isEqualTo(listOf(status))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test if flow throws exception`() = runTest {
|
||||
val exception = IllegalStateException()
|
||||
val status = MockNetworkStatusFactory.createMissedDerivation(params.network)
|
||||
|
||||
val innerFlow = MutableStateFlow(value = false)
|
||||
val expected = flow {
|
||||
if (innerFlow.value) {
|
||||
emit(setOf(status))
|
||||
} else {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
.buffer(capacity = 5)
|
||||
|
||||
val multiParams = MultiNetworkStatusProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
|
||||
val actual = producer.produceWithFallback()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values1 = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values1.size).isEqualTo(1)
|
||||
val fallbackStatus = MockNetworkStatusFactory.createUnreachable(params.network)
|
||||
Truth.assertThat(values1).isEqualTo(listOf(fallbackStatus))
|
||||
|
||||
innerFlow.emit(value = true)
|
||||
|
||||
val values2 = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
Truth.assertThat(values2.size).isEqualTo(1)
|
||||
Truth.assertThat(values2).isEqualTo(listOf(status))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test if flow doesn't contain network from params`() = runTest {
|
||||
val expected = flowOf(
|
||||
setOf(MockNetworkStatusFactory.createMissedDerivation(cardano)),
|
||||
)
|
||||
|
||||
val multiParams = MultiNetworkStatusProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
|
||||
val actual = producer.produce()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values = backgroundScope.getEmittedValues(testScheduler = testScheduler, actual = actual)
|
||||
|
||||
Truth.assertThat(values.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
val mocks = MockCryptoCurrencyFactory()
|
||||
|
||||
val ethereum = mocks.ethereum.network
|
||||
val cardano = mocks.cardano.network
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.domain.networks.single
|
||||
|
||||
import com.tangem.domain.core.flow.FlowProducer
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
/**
|
||||
* Producer of network status [Network] for wallet with [UserWalletId]
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface SingleNetworkStatusProducer : FlowProducer<NetworkStatus> {
|
||||
|
||||
data class Params(val userWalletId: UserWalletId, val network: Network)
|
||||
|
||||
interface Factory : FlowProducer.Factory<Params, SingleNetworkStatusProducer>
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.domain.networks.single
|
||||
|
||||
import com.tangem.domain.core.flow.FlowCachingSupplier
|
||||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
|
||||
/**
|
||||
* Supplier of network status for selected wallet [SingleNetworkStatusProducer.Params]
|
||||
*
|
||||
* @property factory factory for creating [SingleNetworkStatusProducer]
|
||||
* @property keyCreator key creator
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
abstract class SingleNetworkStatusSupplier(
|
||||
override val factory: SingleNetworkStatusProducer.Factory,
|
||||
override val keyCreator: (SingleNetworkStatusProducer.Params) -> String,
|
||||
) : FlowCachingSupplier<SingleNetworkStatusProducer, SingleNetworkStatusProducer.Params, NetworkStatus>()
|
||||
Loading…
Add table
Add a link
Reference in a new issue