Updated on 2026-08-14
This commit is contained in:
parent
b12b46479c
commit
17008240b9
16 changed files with 123 additions and 76 deletions
|
|
@ -38,4 +38,5 @@ dependencies {
|
|||
testImplementation(deps.test.junit)
|
||||
testImplementation(deps.test.mockk)
|
||||
testImplementation(deps.test.turbine)
|
||||
testImplementation(deps.test.truth)
|
||||
}
|
||||
|
|
@ -10,13 +10,12 @@ import com.tangem.datasource.api.common.blockaid.models.request.EvmTransactionSc
|
|||
import com.tangem.datasource.api.common.blockaid.models.request.RpcData
|
||||
import com.tangem.datasource.api.common.blockaid.models.request.SolanaTransactionScanRequest
|
||||
import com.tangem.datasource.api.common.blockaid.models.response.*
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val SUCCESS_STATUS = "Success"
|
||||
private const val DOMAIN_CHECKED_STATUS = "hit"
|
||||
private const val VALIDATION_SAFE_STATUS = "Benign"
|
||||
|
||||
internal class BlockAidMapper @Inject constructor() {
|
||||
internal class BlockAidMapper {
|
||||
|
||||
fun mapToDomain(from: DomainScanResponse): CheckDAppResult {
|
||||
return when {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ import com.tangem.datasource.api.common.blockaid.BlockAidApi
|
|||
import com.tangem.datasource.api.common.blockaid.models.request.DomainScanRequest
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultBlockAidRepository @Inject constructor(
|
||||
internal class DefaultBlockAidRepository(
|
||||
private val api: BlockAidApi,
|
||||
private val dispatcherProvider: CoroutineDispatcherProvider,
|
||||
private val mapper: BlockAidMapper,
|
||||
|
|
|
|||
|
|
@ -1,18 +1,27 @@
|
|||
package com.tangem.data.blockaid.di
|
||||
|
||||
import com.tangem.data.blockaid.BlockAidMapper
|
||||
import com.tangem.data.blockaid.BlockAidRepository
|
||||
import com.tangem.data.blockaid.DefaultBlockAidRepository
|
||||
import dagger.Binds
|
||||
import com.tangem.datasource.api.common.blockaid.BlockAidApi
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface BlockAidDataInternalModule {
|
||||
internal object BlockAidDataInternalModule {
|
||||
|
||||
@Binds
|
||||
@Provides
|
||||
@Singleton
|
||||
fun bindRepository(repository: DefaultBlockAidRepository): BlockAidRepository
|
||||
fun provideRepository(api: BlockAidApi, dispatcherProvider: CoroutineDispatcherProvider): BlockAidRepository {
|
||||
return DefaultBlockAidRepository(
|
||||
api = api,
|
||||
dispatcherProvider = dispatcherProvider,
|
||||
mapper = BlockAidMapper(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@ import com.domain.blockaid.models.dapp.CheckDAppResult
|
|||
import com.domain.blockaid.models.transaction.SimulationResult
|
||||
import com.domain.blockaid.models.transaction.ValidationResult
|
||||
import com.domain.blockaid.models.transaction.simultation.SimulationData
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.datasource.api.common.blockaid.models.response.*
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -14,28 +14,28 @@ class BlockAidMapperTest {
|
|||
private val mapper = BlockAidMapper()
|
||||
|
||||
@Test
|
||||
fun whenStatusHitAndIsMaliciousFalseThenMapToDomainReturnsSafe() {
|
||||
fun `when status hit and is malicious false then map to domain returns safe`() {
|
||||
val response = DomainScanResponse(status = "hit", isMalicious = false)
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(CheckDAppResult.SAFE, result)
|
||||
Truth.assertThat(result).isEqualTo(CheckDAppResult.SAFE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenStatusHitAndIsMaliciousTrueThenMapToDomainReturnsUnsafe() {
|
||||
fun `when status hit and is malicious true then map to domain returns unsafe`() {
|
||||
val response = DomainScanResponse(status = "hit", isMalicious = true)
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(CheckDAppResult.UNSAFE, result)
|
||||
Truth.assertThat(result).isEqualTo(CheckDAppResult.UNSAFE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenStatusNotHitThenMapToDomainReturnsFailedToVerify() {
|
||||
fun `when status not hit then map to domain returns failed to verify`() {
|
||||
val response = DomainScanResponse(status = "miss", isMalicious = false)
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(CheckDAppResult.FAILED_TO_VERIFY, result)
|
||||
Truth.assertThat(result).isEqualTo(CheckDAppResult.FAILED_TO_VERIFY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenResponseBenignValidationThenReturnsSafeValidation() {
|
||||
fun `when response benign validation then returns safe validation`() {
|
||||
val spenderDetails = SpenderDetails(
|
||||
isApprovedForAll = true,
|
||||
exposure = listOf(ExposureDetail(value = "1000.0", rawValue = "0x123")),
|
||||
|
|
@ -53,20 +53,20 @@ class BlockAidMapperTest {
|
|||
)
|
||||
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(ValidationResult.SAFE, result.validation)
|
||||
Truth.assertThat(result.validation).isEqualTo(ValidationResult.SAFE)
|
||||
|
||||
val simulation = result.simulation as? SimulationResult.Success
|
||||
assertNotNull(simulation)
|
||||
Truth.assertThat(simulation).isNotNull()
|
||||
|
||||
val approve = simulation?.data as? SimulationData.Approve
|
||||
assertNotNull(approve)
|
||||
assertEquals(1, approve?.approvedAmounts?.size)
|
||||
assertEquals(BigDecimal("1000.0"), approve?.approvedAmounts?.first()?.approvedAmount)
|
||||
assertTrue(approve?.approvedAmounts?.first()?.isUnlimited == true)
|
||||
Truth.assertThat(approve).isNotNull()
|
||||
Truth.assertThat(approve?.approvedAmounts?.size).isEqualTo(1)
|
||||
Truth.assertThat(approve?.approvedAmounts?.first()?.approvedAmount).isEqualTo(BigDecimal("1000.0"))
|
||||
Truth.assertThat(approve?.approvedAmounts?.first()?.isUnlimited).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenResponseBenignValidationAndSuccessSimulationThenReturnsSendReceiveResult() {
|
||||
fun `when response benign validation and success simulation then returns send receive result`() {
|
||||
val assetDiff = AssetDiff(
|
||||
assetType = "ERC20",
|
||||
asset = Asset(chainId = 1, logoUrl = "logo", symbol = "ETH"),
|
||||
|
|
@ -82,19 +82,19 @@ class BlockAidMapperTest {
|
|||
)
|
||||
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(ValidationResult.SAFE, result.validation)
|
||||
Truth.assertThat(result.validation).isEqualTo(ValidationResult.SAFE)
|
||||
|
||||
val simulation = result.simulation as? SimulationResult.Success
|
||||
assertNotNull(simulation)
|
||||
Truth.assertThat(simulation).isNotNull()
|
||||
|
||||
val data = simulation?.data as? SimulationData.SendAndReceive
|
||||
assertNotNull(data)
|
||||
assertEquals(BigDecimal("1.5"), data?.send?.first()?.amount)
|
||||
assertEquals(BigDecimal("2.0"), data?.receive?.first()?.amount)
|
||||
Truth.assertThat(data).isNotNull()
|
||||
Truth.assertThat(data?.send?.first()?.amount).isEqualTo(BigDecimal("1.5"))
|
||||
Truth.assertThat(data?.receive?.first()?.amount).isEqualTo(BigDecimal("2.0"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenResponseErrorValidationThenReturnsFailedToValidate() {
|
||||
fun `when response error validation rhen returns failed to validate`() {
|
||||
val response = TransactionScanResponse(
|
||||
validation = ValidationResponse(status = "Error", resultType = "Benign"),
|
||||
simulation = SimulationResponse(
|
||||
|
|
@ -104,12 +104,12 @@ class BlockAidMapperTest {
|
|||
)
|
||||
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(ValidationResult.FAILED_TO_VALIDATE, result.validation)
|
||||
assertTrue(result.simulation is SimulationResult.FailedToSimulate)
|
||||
Truth.assertThat(result.validation).isEqualTo(ValidationResult.FAILED_TO_VALIDATE)
|
||||
Truth.assertThat(result.simulation is SimulationResult.FailedToSimulate).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenResponseNotBenignThenReturnsValidationUnsafe() {
|
||||
fun `when response not benign then returns validation unsafe`() {
|
||||
val response = TransactionScanResponse(
|
||||
validation = ValidationResponse(status = "Success", resultType = "Phishing"),
|
||||
simulation = SimulationResponse(
|
||||
|
|
@ -119,11 +119,11 @@ class BlockAidMapperTest {
|
|||
)
|
||||
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertEquals(ValidationResult.UNSAFE, result.validation)
|
||||
Truth.assertThat(result.validation).isEqualTo(ValidationResult.UNSAFE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenResponseSimulationNotSuccessThenReturnsSimulationFailedToSimulate() {
|
||||
fun `when response simulation not success then returns simulation failed ro simulate`() {
|
||||
val response = TransactionScanResponse(
|
||||
validation = ValidationResponse(status = "Success", resultType = "Benign"),
|
||||
simulation = SimulationResponse(
|
||||
|
|
@ -133,11 +133,11 @@ class BlockAidMapperTest {
|
|||
)
|
||||
|
||||
val result = mapper.mapToDomain(response)
|
||||
assertTrue(result.simulation is SimulationResult.FailedToSimulate)
|
||||
Truth.assertThat(result.simulation is SimulationResult.FailedToSimulate).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenResponseSimulationIsEmptyThenReturnsFailedToSimulate() {
|
||||
fun `when response simulation is empty then returns failed to simulate`() {
|
||||
val txResponse = TransactionScanResponse(
|
||||
validation = ValidationResponse(status = "Success", resultType = "Benign"),
|
||||
simulation = SimulationResponse(
|
||||
|
|
@ -150,6 +150,6 @@ class BlockAidMapperTest {
|
|||
)
|
||||
|
||||
val result = mapper.mapToDomain(txResponse)
|
||||
assertTrue(result.simulation is SimulationResult.FailedToSimulate)
|
||||
Truth.assertThat(result.simulation is SimulationResult.FailedToSimulate).isTrue()
|
||||
}
|
||||
}
|
||||
|
|
@ -5,24 +5,20 @@ import com.domain.blockaid.models.dapp.DAppData
|
|||
import com.domain.blockaid.models.transaction.CheckTransactionResult
|
||||
import com.domain.blockaid.models.transaction.TransactionData
|
||||
import com.domain.blockaid.models.transaction.TransactionParams
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.datasource.api.common.blockaid.BlockAidApi
|
||||
import com.tangem.datasource.api.common.blockaid.models.request.DomainScanRequest
|
||||
import com.tangem.datasource.api.common.blockaid.models.request.EvmTransactionScanRequest
|
||||
import com.tangem.datasource.api.common.blockaid.models.request.SolanaTransactionScanRequest
|
||||
import com.tangem.datasource.api.common.blockaid.models.response.DomainScanResponse
|
||||
import com.tangem.datasource.api.common.blockaid.models.response.TransactionScanResponse
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.*
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class DefaultBlockAidRepositoryTest {
|
||||
|
||||
@MockK
|
||||
|
|
@ -31,28 +27,18 @@ class DefaultBlockAidRepositoryTest {
|
|||
@MockK
|
||||
private lateinit var mapper: BlockAidMapper
|
||||
|
||||
@MockK
|
||||
private lateinit var dispatcherProvider: CoroutineDispatcherProvider
|
||||
|
||||
private lateinit var repository: DefaultBlockAidRepository
|
||||
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
private val testDispatcherProvider = TestingCoroutineDispatcherProvider()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
every { dispatcherProvider.io } returns testDispatcher
|
||||
repository = DefaultBlockAidRepository(api, dispatcherProvider, mapper)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
repository = DefaultBlockAidRepository(api, testDispatcherProvider, mapper)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenVerifyAppDomainThenCallsApiAndMapsResult() = runTest {
|
||||
fun `when verify app domain then calls api and maps result`() = runTest {
|
||||
val url = "https://example.com"
|
||||
val domainData = DAppData(url)
|
||||
val domainResponse = DomainScanResponse(status = "hit", isMalicious = false)
|
||||
|
|
@ -63,13 +49,13 @@ class DefaultBlockAidRepositoryTest {
|
|||
|
||||
val result = repository.verifyDAppDomain(domainData)
|
||||
|
||||
assertEquals(expectedResult, result)
|
||||
Truth.assertThat(result).isEqualTo(expectedResult)
|
||||
coVerify { api.scanDomain(DomainScanRequest(url)) }
|
||||
verify { mapper.mapToDomain(domainResponse) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenVerifyEvmTransactionThenCallsScanJsonRpcAndMaps() = runTest {
|
||||
fun `when verify evm transaction then calls scan json rpc and maps result`() = runTest {
|
||||
val data = TransactionData(
|
||||
chain = "ethereum",
|
||||
accountAddress = "0xabc",
|
||||
|
|
@ -88,14 +74,14 @@ class DefaultBlockAidRepositoryTest {
|
|||
|
||||
val result = repository.verifyTransaction(data)
|
||||
|
||||
assertEquals(expectedResult, result)
|
||||
Truth.assertThat(result).isEqualTo(expectedResult)
|
||||
coVerify { api.scanJsonRpc(request) }
|
||||
verify { mapper.mapToEvmRequest(data) }
|
||||
verify { mapper.mapToDomain(response) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenVerifySolanaTransactionThenCallsScanSolanaMessageAndMapsResult() = runTest {
|
||||
fun `when verify solana transaction then calls scan solana message and maps result`() = runTest {
|
||||
val data = TransactionData(
|
||||
chain = "mainnet",
|
||||
accountAddress = "/Rd2TLl...",
|
||||
|
|
@ -114,7 +100,7 @@ class DefaultBlockAidRepositoryTest {
|
|||
|
||||
val result = repository.verifyTransaction(data)
|
||||
|
||||
assertEquals(expectedResult, result)
|
||||
Truth.assertThat(result).isEqualTo(expectedResult)
|
||||
coVerify { api.scanSolanaMessage(request) }
|
||||
verify { mapper.mapToSolanaRequest(data) }
|
||||
verify { mapper.mapToDomain(response) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue