|
|
|
|
@@ -0,0 +1,589 @@
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* * Copyright © 2025 by Navi Technologies Limited
|
|
|
|
|
* * All rights reserved. Strictly confidential
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package com.navi.payment.utils
|
|
|
|
|
|
|
|
|
|
import com.google.gson.Gson
|
|
|
|
|
import com.navi.base.utils.ResourceProvider
|
|
|
|
|
import com.navi.common.utils.CommonUtils.getDisplayableAmount
|
|
|
|
|
import com.navi.common.utils.EMPTY
|
|
|
|
|
import com.navi.common.utils.SPACE
|
|
|
|
|
import com.navi.common.utils.appendStrings
|
|
|
|
|
import com.navi.pay.R as NaviPayR
|
|
|
|
|
import com.navi.pay.R
|
|
|
|
|
import com.navi.pay.management.common.sendmoney.model.view.EligibilityState
|
|
|
|
|
import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity
|
|
|
|
|
import com.navi.pay.utils.RUPEE_SYMBOL
|
|
|
|
|
import com.navi.payment.LinkedAccountTestData
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getDiscountAdjustedAmount
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getEligibilityStateForUpiLiteAccount
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getFirstEligibleAccount
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getLastSelectedAccountBeforeAccountsUpdate
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getLinkedAccountEntityState
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getPayloadBasedOnType
|
|
|
|
|
import com.navi.payment.nativepayment.utils.getScreenIdentifier
|
|
|
|
|
import com.navi.payment.nativepayment.utils.mapToLinkedAccountEntity
|
|
|
|
|
import com.navi.payment.nativepayment.utils.rankUpiAccountsByEligibility
|
|
|
|
|
import com.navi.payment.nativepayment.utils.updateAccountEligibilityStatusForNonUpiLiteAccounts
|
|
|
|
|
import com.navi.payment.nativepayment.utils.updateEligibilityStateForAmount
|
|
|
|
|
import io.mockk.every
|
|
|
|
|
import io.mockk.mockk
|
|
|
|
|
import io.mockk.spyk
|
|
|
|
|
import org.json.JSONObject
|
|
|
|
|
import org.junit.Assert.assertEquals
|
|
|
|
|
import org.junit.Assert.assertNotNull
|
|
|
|
|
import org.junit.Assert.assertNull
|
|
|
|
|
import org.junit.Assert.assertTrue
|
|
|
|
|
import org.junit.Test
|
|
|
|
|
|
|
|
|
|
class ScreenIdentifierTest {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getScreenIdentifier returnsLastSegment whenUrlHasSlashes`() {
|
|
|
|
|
val url = "https://example.com/home/dashboard"
|
|
|
|
|
val expected = "dashboard"
|
|
|
|
|
val actual = getScreenIdentifier(url)
|
|
|
|
|
assertEquals(expected, actual)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getScreenIdentifier returnsEmptyString whenUrlEndsWithSlash`() {
|
|
|
|
|
val url = "https://example.com/home/"
|
|
|
|
|
val expected = ""
|
|
|
|
|
val actual = getScreenIdentifier(url)
|
|
|
|
|
assertEquals(expected, actual)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getScreenIdentifier returnsEntireString ifNoSlash`() {
|
|
|
|
|
val url = "dashboard"
|
|
|
|
|
val expected = "dashboard"
|
|
|
|
|
val actual = getScreenIdentifier(url)
|
|
|
|
|
assertEquals(expected, actual)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getScreenIdentifier returnsEmptyString forEmptyInput`() {
|
|
|
|
|
val url = ""
|
|
|
|
|
val expected = ""
|
|
|
|
|
val actual = getScreenIdentifier(url)
|
|
|
|
|
assertEquals(expected, actual)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class LinkedAccountMapperTest {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `mapToLinkedAccountEntity should correctly map PMSLinkedAccountEntity to LinkedAccountEntity`() {
|
|
|
|
|
val pmsLinkedAccountEntity = LinkedAccountTestData.createPMSLinkedAccountEntity()
|
|
|
|
|
val pmsLinkedAccountEntityList = listOf(pmsLinkedAccountEntity)
|
|
|
|
|
val result = mapToLinkedAccountEntity(pmsLinkedAccountEntityList)
|
|
|
|
|
|
|
|
|
|
assertNotNull(result)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntityList.size, result.size)
|
|
|
|
|
val linkedAccountEntity = result[0]
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.accountId, linkedAccountEntity.accountId)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.bankCode, linkedAccountEntity.bankCode)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.bankName, linkedAccountEntity.bankName)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.name, linkedAccountEntity.name)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.ifsc, linkedAccountEntity.ifsc)
|
|
|
|
|
assertEquals(
|
|
|
|
|
pmsLinkedAccountEntity.maskedAccountNumber,
|
|
|
|
|
linkedAccountEntity.maskedAccountNumber,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(
|
|
|
|
|
pmsLinkedAccountEntity.originalMaskedAccountNumber,
|
|
|
|
|
linkedAccountEntity.originalMaskedAccountNumber,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.accountType, linkedAccountEntity.accountType)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.vpaEntityList, linkedAccountEntity.vpaEntityList)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.isMPinSet, linkedAccountEntity.isMPinSet)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.mPinLength, linkedAccountEntity.mPinLength)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.otpLength, linkedAccountEntity.otpLength)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.atmPinLength, linkedAccountEntity.atmPinLength)
|
|
|
|
|
assertEquals(
|
|
|
|
|
pmsLinkedAccountEntity.isAadhaarConsentProvided,
|
|
|
|
|
linkedAccountEntity.isAadhaarConsentProvided,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.bankIconImageUrl, linkedAccountEntity.bankIconImageUrl)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.isAccountPrimary, linkedAccountEntity.isAccountPrimary)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.balance, linkedAccountEntity.balance)
|
|
|
|
|
assertEquals(
|
|
|
|
|
pmsLinkedAccountEntity.accountTypeFormatted,
|
|
|
|
|
linkedAccountEntity.accountTypeFormatted,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(pmsLinkedAccountEntity.updatedAt, linkedAccountEntity.updatedAt)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class UpdateAccountEligibilityStatusForNonUpiLiteAccountsTest {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `updateAccountEligibilityStatusForNonUpiLiteAccounts updates eligibility for non UPI Lite accounts`() {
|
|
|
|
|
val connectedAccounts =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "1"),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "2"),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "3"),
|
|
|
|
|
)
|
|
|
|
|
val connectedAccountsEligibilityMap =
|
|
|
|
|
mapOf(
|
|
|
|
|
"1" to EligibilityState(isAccountEligible = true),
|
|
|
|
|
"2" to EligibilityState(isAccountEligible = false),
|
|
|
|
|
"3" to EligibilityState(isAccountEligible = true),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
updateAccountEligibilityStatusForNonUpiLiteAccounts(
|
|
|
|
|
connectedAccountsEligibilityMap,
|
|
|
|
|
connectedAccounts,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assertEquals(true, connectedAccounts[0].eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(false, connectedAccounts[1].eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(true, connectedAccounts[2].eligibilityState.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `updateAccountEligibilityStatusForNonUpiLiteAccounts ignores UPI Lite accounts`() {
|
|
|
|
|
val connectedAccounts =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "1"),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
accountId = "upi_lite"
|
|
|
|
|
), // it should have a underscore
|
|
|
|
|
)
|
|
|
|
|
val upiLiteEligibilityState = connectedAccounts[1].eligibilityState
|
|
|
|
|
val connectedAccountsEligibilityMap =
|
|
|
|
|
mapOf("1" to EligibilityState(isAccountEligible = false))
|
|
|
|
|
|
|
|
|
|
updateAccountEligibilityStatusForNonUpiLiteAccounts(
|
|
|
|
|
connectedAccountsEligibilityMap,
|
|
|
|
|
connectedAccounts,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assertEquals(false, connectedAccounts[0].eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(upiLiteEligibilityState, connectedAccounts[1].eligibilityState)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RankUpiAccountsByEligibilityTest {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `rankUpiAccountsByEligibility returns enabled accounts followed by disabled accounts`() {
|
|
|
|
|
val accountList =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = true)
|
|
|
|
|
),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = true)
|
|
|
|
|
),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
val result = rankUpiAccountsByEligibility(accountList)
|
|
|
|
|
|
|
|
|
|
assertEquals(true, result[0].eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(true, result[1].eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(false, result[2].eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(false, result[3].eligibilityState.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `rankUpiAccountsByEligibility returns empty list for empty input`() {
|
|
|
|
|
val result = rankUpiAccountsByEligibility(emptyList())
|
|
|
|
|
|
|
|
|
|
assertTrue(result.isEmpty())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GetEligibilityStateForUpiLiteAccountTest {
|
|
|
|
|
private val resourceProvider: ResourceProvider = mockk()
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getEligibilityStateForUpiLiteAccount return ineligible if balance is empty or upi lite unavailable`() {
|
|
|
|
|
val liteBalance = EMPTY
|
|
|
|
|
val liteAccount = LinkedAccountTestData.createLinkedAccountEntity(balance = liteBalance)
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider
|
|
|
|
|
.getString(resId = NaviPayR.string.balance)
|
|
|
|
|
.appendStrings(
|
|
|
|
|
SPACE,
|
|
|
|
|
RUPEE_SYMBOL,
|
|
|
|
|
liteAccount.balance.orEmpty().getDisplayableAmount(),
|
|
|
|
|
)
|
|
|
|
|
} returns "Balance: ₹${liteBalance.getDisplayableAmount()}"
|
|
|
|
|
every { resourceProvider.getString(resId = R.string.np_upi_lite_sync_needed) } returns
|
|
|
|
|
"UPI Lite is temporarily unavailable"
|
|
|
|
|
val result =
|
|
|
|
|
getEligibilityStateForUpiLiteAccount(
|
|
|
|
|
paymentAmount = 200.0,
|
|
|
|
|
liteAccount = liteAccount,
|
|
|
|
|
liteMaxPayableAmount = 1000.0,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(false, result.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getEligibilityStateForUpiLiteAccount return ineligible if upi lite max limit exceeded`() {
|
|
|
|
|
val liteBalance = "1100"
|
|
|
|
|
val liteAccount = LinkedAccountTestData.createLinkedAccountEntity(balance = liteBalance)
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider
|
|
|
|
|
.getString(resId = NaviPayR.string.balance)
|
|
|
|
|
.appendStrings(
|
|
|
|
|
SPACE,
|
|
|
|
|
RUPEE_SYMBOL,
|
|
|
|
|
liteAccount.balance.orEmpty().getDisplayableAmount(),
|
|
|
|
|
)
|
|
|
|
|
} returns "Balance: ₹${liteBalance.getDisplayableAmount()}"
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider.getString(
|
|
|
|
|
R.string.np_supported_up_to_amount_limit,
|
|
|
|
|
"1000.0".getDisplayableAmount(),
|
|
|
|
|
)
|
|
|
|
|
} returns "Only supported for transaction up to ₹1000.0"
|
|
|
|
|
val result =
|
|
|
|
|
getEligibilityStateForUpiLiteAccount(
|
|
|
|
|
paymentAmount = 1050.0,
|
|
|
|
|
liteAccount = liteAccount,
|
|
|
|
|
liteMaxPayableAmount = 1000.0,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(false, result.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getEligibilityStateForUpiLiteAccount returns ineligible if balance is insufficient`() {
|
|
|
|
|
val liteBalance = "100"
|
|
|
|
|
val liteAccount = LinkedAccountTestData.createLinkedAccountEntity(balance = liteBalance)
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider
|
|
|
|
|
.getString(resId = NaviPayR.string.balance)
|
|
|
|
|
.appendStrings(
|
|
|
|
|
SPACE,
|
|
|
|
|
RUPEE_SYMBOL,
|
|
|
|
|
liteAccount.balance.orEmpty().getDisplayableAmount(),
|
|
|
|
|
)
|
|
|
|
|
} returns "Balance: ₹100"
|
|
|
|
|
val result =
|
|
|
|
|
getEligibilityStateForUpiLiteAccount(
|
|
|
|
|
paymentAmount = 200.0,
|
|
|
|
|
liteAccount = liteAccount,
|
|
|
|
|
liteMaxPayableAmount = 1000.0,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(false, result.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getEligibilityStateForUpiLiteAccount return eligible if upi lite is enabled and all other check pass`() {
|
|
|
|
|
val liteBalance = "100"
|
|
|
|
|
val liteAccount = LinkedAccountTestData.createLinkedAccountEntity(balance = liteBalance)
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider
|
|
|
|
|
.getString(resId = NaviPayR.string.balance)
|
|
|
|
|
.appendStrings(
|
|
|
|
|
SPACE,
|
|
|
|
|
RUPEE_SYMBOL,
|
|
|
|
|
liteAccount.balance.orEmpty().getDisplayableAmount(),
|
|
|
|
|
)
|
|
|
|
|
} returns "Balance: ₹${liteBalance.getDisplayableAmount()}"
|
|
|
|
|
val result =
|
|
|
|
|
getEligibilityStateForUpiLiteAccount(
|
|
|
|
|
paymentAmount = 10.0,
|
|
|
|
|
liteAccount = liteAccount,
|
|
|
|
|
liteMaxPayableAmount = 1000.0,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(true, result.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getEligibilityStateForUpiLiteAccount return inEligible if upi lite is disabled but all other check pass`() {
|
|
|
|
|
val liteBalance = "100"
|
|
|
|
|
val pmsLiteAccountEntity =
|
|
|
|
|
LinkedAccountTestData.createPMSLinkedAccountEntity(
|
|
|
|
|
balance = liteBalance,
|
|
|
|
|
isDisabled = true,
|
|
|
|
|
)
|
|
|
|
|
val liteAccount =
|
|
|
|
|
mapToLinkedAccountEntity(accountList = listOf(pmsLiteAccountEntity)).first()
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider
|
|
|
|
|
.getString(resId = NaviPayR.string.balance)
|
|
|
|
|
.appendStrings(
|
|
|
|
|
SPACE,
|
|
|
|
|
RUPEE_SYMBOL,
|
|
|
|
|
liteAccount.balance.orEmpty().getDisplayableAmount(),
|
|
|
|
|
)
|
|
|
|
|
} returns "Balance: ₹${liteBalance.getDisplayableAmount()}"
|
|
|
|
|
val result =
|
|
|
|
|
getEligibilityStateForUpiLiteAccount(
|
|
|
|
|
paymentAmount = 10.0,
|
|
|
|
|
liteAccount = liteAccount,
|
|
|
|
|
liteMaxPayableAmount = 1000.0,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(false, result.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GetLinkedAccountEntityStateTest {
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLinkedAccountEntityState returns ineligible state when account is disabled`() {
|
|
|
|
|
val linkedAccountEntity = LinkedAccountTestData.createLinkedAccountEntity()
|
|
|
|
|
linkedAccountEntity.isDisabled = true
|
|
|
|
|
val accountEligibility = EligibilityState(isAccountEligible = true)
|
|
|
|
|
val result = getLinkedAccountEntityState(accountEligibility, linkedAccountEntity)
|
|
|
|
|
assertEquals(false, result.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLinkedAccountEntityState returns eligible state with mpin not set when mpin is not set`() {
|
|
|
|
|
val linkedAccountEntity = LinkedAccountTestData.createLinkedAccountEntity(isMPinSet = false)
|
|
|
|
|
val accountEligibility = EligibilityState(isAccountEligible = true)
|
|
|
|
|
val result = getLinkedAccountEntityState(accountEligibility, linkedAccountEntity)
|
|
|
|
|
assertEquals(true, result.isAccountEligible)
|
|
|
|
|
assertEquals(R.string.mpin_not_set, result.inEligibilityReasonResId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLinkedAccountEntityState returns provided eligibility state when account is enabled and mpin is set`() {
|
|
|
|
|
// Account is eligible
|
|
|
|
|
val linkedAccountEntity =
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = true)
|
|
|
|
|
)
|
|
|
|
|
val eligibleResult =
|
|
|
|
|
getLinkedAccountEntityState(
|
|
|
|
|
EligibilityState(isAccountEligible = true),
|
|
|
|
|
linkedAccountEntity,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(true, eligibleResult.isAccountEligible)
|
|
|
|
|
|
|
|
|
|
// Account is not eligible
|
|
|
|
|
linkedAccountEntity.eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
val inEligibleResult =
|
|
|
|
|
getLinkedAccountEntityState(
|
|
|
|
|
accountEligibility = EligibilityState(isAccountEligible = false),
|
|
|
|
|
linkedAccountEntity,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(false, inEligibleResult.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLinkedAccountEntityState returns default eligible state when eligibility is null and account is enabled with mpin set`() {
|
|
|
|
|
// Account is eligible
|
|
|
|
|
val linkedAccountEntity = LinkedAccountTestData.createLinkedAccountEntity()
|
|
|
|
|
val eligibleResult = getLinkedAccountEntityState(null, linkedAccountEntity)
|
|
|
|
|
assertEquals(true, eligibleResult.isAccountEligible)
|
|
|
|
|
|
|
|
|
|
// Account is not eligible
|
|
|
|
|
linkedAccountEntity.eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
val inEligibleResult = getLinkedAccountEntityState(null, linkedAccountEntity)
|
|
|
|
|
assertEquals(true, inEligibleResult.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class UpdateEligibilityStateForAmountTest {
|
|
|
|
|
|
|
|
|
|
private val resourceProvider: ResourceProvider = mockk()
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `updateEligibilityStateForAmount returns early when eligibilityState is null`() {
|
|
|
|
|
val linkedAccountEntity = LinkedAccountTestData.createLinkedAccountEntity()
|
|
|
|
|
val result =
|
|
|
|
|
updateEligibilityStateForAmount(
|
|
|
|
|
account = linkedAccountEntity,
|
|
|
|
|
amount = 100.0,
|
|
|
|
|
upiSendMoneylimit = 1000.0,
|
|
|
|
|
upiLiteSendMoneyLimit = 500.0,
|
|
|
|
|
eligibilityState = null,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(true, linkedAccountEntity.eligibilityState.isAccountEligible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `updateEligibilityStateForAmount sets ineligible for non UpiLite when amount exceeds limit`() {
|
|
|
|
|
val linkedAccountEntity = LinkedAccountTestData.createLinkedAccountEntity()
|
|
|
|
|
every {
|
|
|
|
|
resourceProvider.getString(com.navi.payment.R.string.payment_instrument_not_support)
|
|
|
|
|
} returns "Amount exceeds limit"
|
|
|
|
|
updateEligibilityStateForAmount(
|
|
|
|
|
account = linkedAccountEntity,
|
|
|
|
|
amount = 2000.0,
|
|
|
|
|
upiSendMoneylimit = 1000.0,
|
|
|
|
|
upiLiteSendMoneyLimit = 500.0,
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = true),
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(false, linkedAccountEntity.eligibilityState.isAccountEligible)
|
|
|
|
|
assertEquals(
|
|
|
|
|
"Amount exceeds limit",
|
|
|
|
|
linkedAccountEntity.eligibilityState.inEligibilityReason,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `updateEligibilityStateForAmount sets provided eligibility for non UpiLite when amount within limit`() {
|
|
|
|
|
val linkedAccountEntity = LinkedAccountTestData.createLinkedAccountEntity()
|
|
|
|
|
val providedEligibilityState =
|
|
|
|
|
EligibilityState(isAccountEligible = true, inEligibilityReason = "Some reason")
|
|
|
|
|
updateEligibilityStateForAmount(
|
|
|
|
|
account = linkedAccountEntity,
|
|
|
|
|
amount = 500.0,
|
|
|
|
|
upiSendMoneylimit = 1000.0,
|
|
|
|
|
upiLiteSendMoneyLimit = 500.0,
|
|
|
|
|
eligibilityState = providedEligibilityState,
|
|
|
|
|
resourceProvider = resourceProvider,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(
|
|
|
|
|
providedEligibilityState.isAccountEligible,
|
|
|
|
|
linkedAccountEntity.eligibilityState.isAccountEligible,
|
|
|
|
|
)
|
|
|
|
|
assertEquals(
|
|
|
|
|
providedEligibilityState.inEligibilityReason,
|
|
|
|
|
linkedAccountEntity.eligibilityState.inEligibilityReason,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GetFirstEligibleAccountTest {
|
|
|
|
|
@Test
|
|
|
|
|
fun `getFirstEligibleAccount returns first eligible account`() {
|
|
|
|
|
val linkedAccountList =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = true)
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
val result = getFirstEligibleAccount(linkedAccountList)
|
|
|
|
|
assertNotNull(result)
|
|
|
|
|
assertEquals(linkedAccountList[1], result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getFirstEligibleAccount returns null if no eligible accounts`() {
|
|
|
|
|
val linkedAccountList =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(
|
|
|
|
|
eligibilityState = EligibilityState(isAccountEligible = false)
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
val result = getFirstEligibleAccount(linkedAccountList)
|
|
|
|
|
assertNull(result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class DiscountAdjustedAmountTest {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getDiscountAdjustedAmount correctly applies discount and rounds`() {
|
|
|
|
|
val amount = 100.0
|
|
|
|
|
val discount = 15.237
|
|
|
|
|
val expected = 84.76 // 100.0 - 15.237 = 84.763 -> rounded to 2 decimals
|
|
|
|
|
val actual = getDiscountAdjustedAmount(amount, discount)
|
|
|
|
|
assertEquals(expected, actual, 0.001)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getDiscountAdjustedAmount zeroDiscount returns original amount`() {
|
|
|
|
|
val amount = 200.0
|
|
|
|
|
val discount = 0.0
|
|
|
|
|
val expected = 200.0
|
|
|
|
|
val actual = getDiscountAdjustedAmount(amount, discount)
|
|
|
|
|
assertEquals(expected, actual, 0.001)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GetPayloadBasedOnTypeTest {
|
|
|
|
|
|
|
|
|
|
private val deserializer: Gson = mockk()
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getPayloadBasedOnType returns null for null payload`() {
|
|
|
|
|
val spy = spyk(JSONObject())
|
|
|
|
|
every { spy.has("type") } returns false
|
|
|
|
|
every { spy.has("data") } returns false
|
|
|
|
|
val result = getPayloadBasedOnType(deserializer, null)
|
|
|
|
|
assertNull(result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getPayloadBasedOnType returns null when type is missing`() {
|
|
|
|
|
val spy = spyk(JSONObject())
|
|
|
|
|
every { spy.has("type") } returns false
|
|
|
|
|
every { spy.has("data") } returns true
|
|
|
|
|
val result = getPayloadBasedOnType(deserializer, spy)
|
|
|
|
|
assertNull(result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getPayloadBasedOnType returns null when data is missing`() {
|
|
|
|
|
val spy = spyk(JSONObject())
|
|
|
|
|
every { spy.has("type") } returns true
|
|
|
|
|
every { spy.has("data") } returns false
|
|
|
|
|
val result = getPayloadBasedOnType(deserializer, spy)
|
|
|
|
|
assertNull(result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GetLastSelectedAccountBeforeAccountsUpdateTest {
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLastSelectedAccountBeforeAccountsUpdate returns correct account`() {
|
|
|
|
|
val linkedAccountList =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "1"),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "2"),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "3"),
|
|
|
|
|
)
|
|
|
|
|
val lastSelectedAccountId = "2"
|
|
|
|
|
val result =
|
|
|
|
|
getLastSelectedAccountBeforeAccountsUpdate(linkedAccountList, lastSelectedAccountId)
|
|
|
|
|
assertNotNull(result)
|
|
|
|
|
assertEquals("2", result?.accountId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLastSelectedAccountBeforeAccountsUpdate returns first eligible account if not found`() {
|
|
|
|
|
val linkedAccountList =
|
|
|
|
|
listOf(
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "1"),
|
|
|
|
|
LinkedAccountTestData.createLinkedAccountEntity(accountId = "3"),
|
|
|
|
|
)
|
|
|
|
|
val lastSelectedAccountId = "2"
|
|
|
|
|
val result =
|
|
|
|
|
getLastSelectedAccountBeforeAccountsUpdate(linkedAccountList, lastSelectedAccountId)
|
|
|
|
|
assertEquals(getFirstEligibleAccount(linkedAccountList), result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `getLastSelectedAccountsBeforeAccountUpdate return null if list is empty`() {
|
|
|
|
|
val linkedAccountList = emptyList<LinkedAccountEntity>()
|
|
|
|
|
val lastSelectedAccountId = "1"
|
|
|
|
|
val result =
|
|
|
|
|
getLastSelectedAccountBeforeAccountsUpdate(
|
|
|
|
|
updatedAccountList = linkedAccountList,
|
|
|
|
|
lastSelectedBankAccountId = lastSelectedAccountId,
|
|
|
|
|
)
|
|
|
|
|
assertNull(result)
|
|
|
|
|
}
|
|
|
|
|
}
|