Updated on 2026-08-14
This commit is contained in:
parent
5ce84d1500
commit
f2891683e1
8 changed files with 780 additions and 0 deletions
|
|
@ -0,0 +1,106 @@
|
|||
package com.tangem.data.pay.repository
|
||||
|
||||
import arrow.core.left
|
||||
import arrow.core.right
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.data.pay.util.CashbackAccrualDocsConverter
|
||||
import com.tangem.data.pay.util.CashbackPromotionsConverter
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.pay.TangemPayApi
|
||||
import com.tangem.datasource.api.pay.models.response.CashbackAccrualDocsResponse
|
||||
import com.tangem.datasource.api.pay.models.response.CashbackPromotionsResponse
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class DefaultCashbackRepositoryTest {
|
||||
|
||||
private val tangemPayApi: TangemPayApi = mockk()
|
||||
private val requestHelper: TangemPayRequestPerformer = mockk()
|
||||
|
||||
private val userWalletId = UserWalletId("011")
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
clearMocks(tangemPayApi, requestHelper)
|
||||
coEvery {
|
||||
requestHelper.performRequest<Any>(userWalletId = any(), requestBlock = any())
|
||||
} coAnswers {
|
||||
val block = secondArg<suspend (String) -> ApiResponse<Any>>()
|
||||
when (val response = block(AUTH_HEADER)) {
|
||||
is ApiResponse.Success -> response.data.right()
|
||||
is ApiResponse.Error -> VisaApiError.Unspecified.left()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN promotions response WHEN getCashbackPromotions THEN converter result is returned`() = runTest {
|
||||
// Arrange
|
||||
val response = CashbackPromotionsResponse(cashbackOnCards = null, additionalCashback = null)
|
||||
coEvery { tangemPayApi.getCashbackPromotions(any(), any()) } returns ApiResponse.Success(response)
|
||||
|
||||
// Act
|
||||
val actual = createRepository().getCashbackPromotions(userWalletId)
|
||||
|
||||
// Assert
|
||||
assertThat(actual).isEqualTo(CashbackPromotionsConverter.convert(response).right())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN backend error WHEN getCashbackPromotions THEN error is propagated`() = runTest {
|
||||
// Arrange
|
||||
coEvery { tangemPayApi.getCashbackPromotions(any(), any()) } returns
|
||||
ApiResponse.Error(ApiResponseError.NetworkException()) as ApiResponse<CashbackPromotionsResponse>
|
||||
|
||||
// Act
|
||||
val actual = createRepository().getCashbackPromotions(userWalletId)
|
||||
|
||||
// Assert
|
||||
assertThat(actual).isEqualTo(VisaApiError.Unspecified.left())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN docs response WHEN getCashbackAccrualDocs THEN converter result is returned`() = runTest {
|
||||
// Arrange
|
||||
val response = CashbackAccrualDocsResponse(
|
||||
docs = listOf(CashbackAccrualDocsResponse.Doc(id = "1", title = "Terms", url = "https://a")),
|
||||
)
|
||||
coEvery { tangemPayApi.getCashbackAccrualDocs(any(), any()) } returns ApiResponse.Success(response)
|
||||
|
||||
// Act
|
||||
val actual = createRepository().getCashbackAccrualDocs(userWalletId)
|
||||
|
||||
// Assert
|
||||
assertThat(actual).isEqualTo(CashbackAccrualDocsConverter.convert(response).right())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN backend error WHEN getCashbackAccrualDocs THEN error is propagated`() = runTest {
|
||||
// Arrange
|
||||
coEvery { tangemPayApi.getCashbackAccrualDocs(any(), any()) } returns
|
||||
ApiResponse.Error(ApiResponseError.NetworkException()) as ApiResponse<CashbackAccrualDocsResponse>
|
||||
|
||||
// Act
|
||||
val actual = createRepository().getCashbackAccrualDocs(userWalletId)
|
||||
|
||||
// Assert
|
||||
assertThat(actual).isEqualTo(VisaApiError.Unspecified.left())
|
||||
}
|
||||
|
||||
private fun createRepository() = DefaultCashbackRepository(
|
||||
tangemPayApi = tangemPayApi,
|
||||
requestHelper = requestHelper,
|
||||
storage = mockk(),
|
||||
)
|
||||
|
||||
private companion object {
|
||||
const val AUTH_HEADER = "auth-header"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.tangem.data.pay.util
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.datasource.api.pay.models.response.CashbackAccrualDocsResponse
|
||||
import com.tangem.datasource.api.pay.models.response.CashbackAccrualDocsResponse.Doc
|
||||
import com.tangem.domain.pay.model.CashbackDocument
|
||||
import com.tangem.test.core.ProvideTestModels
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class CashbackAccrualDocsConverterTest {
|
||||
|
||||
@Test
|
||||
fun `GIVEN valid docs WHEN convert THEN all docs mapped in order`() {
|
||||
// Arrange
|
||||
val response = response(
|
||||
doc(id = "1", title = "All categories", url = "https://a"),
|
||||
doc(id = "2", title = "Full terms", url = "https://b"),
|
||||
)
|
||||
|
||||
// Act
|
||||
val result = CashbackAccrualDocsConverter.convert(response)
|
||||
|
||||
// Assert
|
||||
assertThat(result).containsExactly(
|
||||
CashbackDocument(id = "1", title = "All categories", url = "https://a"),
|
||||
CashbackDocument(id = "2", title = "Full terms", url = "https://b"),
|
||||
).inOrder()
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ProvideTestModels
|
||||
fun `GIVEN doc missing a required field WHEN convert THEN it is dropped`(malformed: Doc) {
|
||||
// Arrange
|
||||
val response = response(doc(), malformed)
|
||||
|
||||
// Act
|
||||
val result = CashbackAccrualDocsConverter.convert(response)
|
||||
|
||||
// Assert
|
||||
assertThat(result).containsExactly(CashbackDocument(id = "1", title = "Title", url = "https://a"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN null docs WHEN convert THEN empty list`() {
|
||||
// Act
|
||||
val result = CashbackAccrualDocsConverter.convert(CashbackAccrualDocsResponse(docs = null))
|
||||
|
||||
// Assert
|
||||
assertThat(result).isEmpty()
|
||||
}
|
||||
|
||||
private fun provideTestModels() = listOf(
|
||||
doc(id = null),
|
||||
doc(title = null),
|
||||
doc(url = null),
|
||||
)
|
||||
|
||||
private fun response(vararg docs: Doc) = CashbackAccrualDocsResponse(docs = docs.toList())
|
||||
|
||||
private fun doc(id: String? = "1", title: String? = "Title", url: String? = "https://a") =
|
||||
Doc(id = id, title = title, url = url)
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.tangem.data.pay.util
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.datasource.api.pay.models.response.CashbackPromotionsResponse
|
||||
import com.tangem.domain.pay.model.CashbackPromotions
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class CashbackPromotionsConverterTest {
|
||||
|
||||
@Test
|
||||
fun `GIVEN tiers WHEN convert THEN each tier mapped with its fields`() {
|
||||
// Arrange
|
||||
val response = response(tier(min = BigDecimal("30"), cap = BigDecimal("100")))
|
||||
|
||||
// Act
|
||||
val result = CashbackPromotionsConverter.convert(response)
|
||||
|
||||
// Assert
|
||||
assertThat(result).isEqualTo(
|
||||
CashbackPromotions(
|
||||
cardTiers = listOf(
|
||||
CashbackPromotions.CardTier(
|
||||
tier = "basic",
|
||||
label = "Basic",
|
||||
scope = "All purchases",
|
||||
minTransactionAmount = BigDecimal("30"),
|
||||
monthlyCapAmount = BigDecimal("100"),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN null cashbackOnCards WHEN convert THEN no card tiers`() {
|
||||
// Arrange
|
||||
val response = CashbackPromotionsResponse(cashbackOnCards = null, additionalCashback = null)
|
||||
|
||||
// Act
|
||||
val result = CashbackPromotionsConverter.convert(response)
|
||||
|
||||
// Assert
|
||||
assertThat(result.cardTiers).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN tier with null strings WHEN convert THEN strings default to empty and amounts stay null`() {
|
||||
// Arrange
|
||||
val response = response(tier(tier = null, label = null, scope = null))
|
||||
|
||||
// Act
|
||||
val result = CashbackPromotionsConverter.convert(response)
|
||||
|
||||
// Assert
|
||||
assertThat(result.cardTiers).containsExactly(
|
||||
CashbackPromotions.CardTier(
|
||||
tier = "",
|
||||
label = "",
|
||||
scope = "",
|
||||
minTransactionAmount = null,
|
||||
monthlyCapAmount = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun response(vararg tiers: CashbackPromotionsResponse.CardTier) = CashbackPromotionsResponse(
|
||||
cashbackOnCards = CashbackPromotionsResponse.CashbackOnCards(
|
||||
tiers = tiers.toList(),
|
||||
monthlyCapAmount = null,
|
||||
monthlyCapCurrency = null,
|
||||
),
|
||||
additionalCashback = null,
|
||||
)
|
||||
|
||||
private fun tier(
|
||||
tier: String? = "basic",
|
||||
label: String? = "Basic",
|
||||
scope: String? = "All purchases",
|
||||
min: BigDecimal? = null,
|
||||
cap: BigDecimal? = null,
|
||||
) = CashbackPromotionsResponse.CardTier(
|
||||
tier = tier,
|
||||
label = label,
|
||||
scope = scope,
|
||||
minTransactionAmount = min,
|
||||
tierMonthlyCapAmount = cap,
|
||||
promotionId = null,
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue