NTP-65855 | bbps unit test base class setup and added example usage (#16392)
Co-authored-by: Kishan Kumar <kishan.kumar@navi.com>
This commit is contained in:
@@ -339,7 +339,7 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateConsentProvided(isConsentProvided: Boolean) {
|
||||
fun updateConsentProvided(isConsentProvided: Boolean) {
|
||||
_isConsentProvided.update { isConsentProvided }
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ constructor(
|
||||
_payBillScreenState.update { payBillScreenState }
|
||||
}
|
||||
|
||||
private fun updatePayBillHeaderState(payBillHeaderState: PayBillHeaderState) {
|
||||
fun updatePayBillHeaderState(payBillHeaderState: PayBillHeaderState) {
|
||||
_payBillHeaderState.update { payBillHeaderState }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.bbps.base
|
||||
|
||||
import com.navi.common.di.CoroutineDispatcherProvider
|
||||
import io.mockk.MockKAnnotations
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestCoroutineScheduler
|
||||
import kotlinx.coroutines.test.TestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
||||
abstract class NaviBbpsBaseTest {
|
||||
// Coroutine testing utilities
|
||||
private val testScheduler = TestCoroutineScheduler()
|
||||
val testDispatcher = StandardTestDispatcher(scheduler = testScheduler)
|
||||
val testScope = TestScope(testDispatcher)
|
||||
|
||||
/**
|
||||
* Test implementation of CoroutineDispatcherProvider that uses a single test dispatcher for all
|
||||
* coroutine contexts to make testing deterministic.
|
||||
*/
|
||||
class TestCoroutineDispatcherProvider(private val testDispatcher: TestDispatcher) :
|
||||
CoroutineDispatcherProvider {
|
||||
override val default: CoroutineDispatcher
|
||||
get() = testDispatcher
|
||||
|
||||
override val main: CoroutineDispatcher
|
||||
get() = testDispatcher
|
||||
|
||||
override val io: CoroutineDispatcher
|
||||
get() = testDispatcher
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the test environment before each test.
|
||||
* 1. Configure Dispatchers.Main to use our test dispatcher
|
||||
* 2. Initialize mock annotations
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Before
|
||||
open fun setUp() {
|
||||
// Configure the main dispatcher for testing
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
|
||||
// Initialize MockK annotations with relaxed behavior
|
||||
MockKAnnotations.init(this, relaxed = true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after each test to avoid affecting other tests. Reset the main dispatcher to its
|
||||
* original state.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@After
|
||||
open fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ package com.navi.bbps.common.viewmodel
|
||||
|
||||
import com.navi.base.utils.NaviNetworkConnectivity
|
||||
import com.navi.base.utils.ResourceProvider
|
||||
import com.navi.bbps.base.NaviBbpsBaseTest
|
||||
import com.navi.bbps.common.gmail.signin.GmailAccessSignInManager.Companion.GMAIL_READ_ONLY_SCOPE
|
||||
import com.navi.bbps.common.model.config.NaviBbpsDefaultConfig
|
||||
import com.navi.bbps.common.model.network.BillDetectionResponse
|
||||
@@ -17,23 +18,12 @@ import com.navi.bbps.common.model.view.DetectedBillEntity
|
||||
import com.navi.bbps.common.model.view.FullScreenLoaderState
|
||||
import com.navi.bbps.feature.detectedbills.DetectedBillsRepository
|
||||
import com.navi.bbps.feature.mybills.MyBillsSyncJob
|
||||
import com.navi.common.di.CoroutineDispatcherProvider
|
||||
import com.navi.common.network.models.GenericErrorResponse
|
||||
import com.navi.common.network.models.RepoResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestCoroutineScheduler
|
||||
import kotlinx.coroutines.test.TestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
@@ -49,8 +39,7 @@ import org.junit.Test
|
||||
* - The startDetectingBills method with different scenarios
|
||||
* - Various helper functions within the handler
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class OriginBillDetectionHandlerTest {
|
||||
class OriginBillDetectionHandlerTest : NaviBbpsBaseTest() {
|
||||
// Dependencies to be mocked
|
||||
@MockK private lateinit var detectedBillsRepository: DetectedBillsRepository
|
||||
@MockK private lateinit var resourceProvider: ResourceProvider
|
||||
@@ -60,46 +49,12 @@ class OriginBillDetectionHandlerTest {
|
||||
// Class under test
|
||||
private lateinit var handler: OriginBillDetectionHandler
|
||||
|
||||
// Coroutine testing utilities
|
||||
private val testScheduler = TestCoroutineScheduler()
|
||||
private val testDispatcher = StandardTestDispatcher(scheduler = testScheduler)
|
||||
private val testScope = TestScope(testDispatcher)
|
||||
|
||||
/**
|
||||
* Test implementation of CoroutineDispatcherProvider that uses a single test dispatcher for all
|
||||
* coroutine contexts to make testing deterministic.
|
||||
*/
|
||||
class TestCoroutineDispatcherProviderImpl(private val testDispatcher: TestDispatcher) :
|
||||
CoroutineDispatcherProvider {
|
||||
override val default: CoroutineDispatcher
|
||||
get() = testDispatcher
|
||||
|
||||
override val main: CoroutineDispatcher
|
||||
get() = testDispatcher
|
||||
|
||||
override val io: CoroutineDispatcher
|
||||
get() = testDispatcher
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the test environment before each test.
|
||||
* 1. Configure Dispatchers.Main to use our test dispatcher
|
||||
* 2. Initialize mock annotations
|
||||
* 3. Create the handler instance with test dependencies
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Before
|
||||
fun setUp() {
|
||||
// Configure the main dispatcher for testing
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
|
||||
// Initialize MockK annotations with relaxed behavior
|
||||
MockKAnnotations.init(this, relaxed = true)
|
||||
|
||||
// Initialize the handler with test dependencies
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
handler =
|
||||
OriginBillDetectionHandler(
|
||||
coroutineDispatcherProvider = TestCoroutineDispatcherProviderImpl(testDispatcher),
|
||||
coroutineDispatcherProvider = TestCoroutineDispatcherProvider(testDispatcher),
|
||||
detectedBillsRepository = detectedBillsRepository,
|
||||
resourceProvider = resourceProvider,
|
||||
naviNetworkConnectivity = naviNetworkConnectivity,
|
||||
@@ -367,8 +322,8 @@ class OriginBillDetectionHandlerTest {
|
||||
* original state.
|
||||
*/
|
||||
@After
|
||||
fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
override fun tearDown() {
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,526 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024-2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.bbps.feature.paybill
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import com.navi.base.utils.NaviNetworkConnectivity
|
||||
import com.navi.base.utils.ResourceProvider
|
||||
import com.navi.bbps.base.NaviBbpsBaseTest
|
||||
import com.navi.bbps.common.CoinsSyncManager
|
||||
import com.navi.bbps.common.model.config.NaviBbpsDefaultConfig
|
||||
import com.navi.bbps.common.repository.BbpsCommonRepository
|
||||
import com.navi.bbps.common.session.NaviBbpsSessionHelper
|
||||
import com.navi.bbps.common.session.ZeroPlatformFeeBottomSheetViewTracker
|
||||
import com.navi.bbps.common.usecase.FetchBillHandler
|
||||
import com.navi.bbps.common.usecase.NaviBbpsConfigUseCase
|
||||
import com.navi.bbps.common.usecase.RewardNudgeUseCase
|
||||
import com.navi.bbps.common.utils.NaviBbpsDateUtils
|
||||
import com.navi.bbps.common.utils.getDefaultConfig
|
||||
import com.navi.bbps.feature.category.BillCategoriesRepository
|
||||
import com.navi.bbps.feature.category.model.view.BillCategoryEntity
|
||||
import com.navi.bbps.feature.contactlist.model.view.PhoneContactEntity
|
||||
import com.navi.bbps.feature.customerinput.model.view.BillDetailsEntity
|
||||
import com.navi.bbps.feature.customerinput.model.view.BillerAdditionalParamsEntity
|
||||
import com.navi.bbps.feature.customerinput.model.view.BillerDetailsEntity
|
||||
import com.navi.bbps.feature.mybills.MyBillsRepository
|
||||
import com.navi.bbps.feature.mybills.model.view.MyBillEntity
|
||||
import com.navi.bbps.feature.paybill.helper.BbpsArcHelper
|
||||
import com.navi.bbps.feature.paybill.helper.NotifyDuplicatePaymentHandler
|
||||
import com.navi.bbps.feature.paybill.helper.PayBillAmountChipsHelper
|
||||
import com.navi.bbps.feature.paybill.model.view.PayBillHeaderState
|
||||
import com.navi.bbps.feature.paybill.model.view.PayBillSource
|
||||
import com.navi.common.usecase.LitmusExperimentsUseCase
|
||||
import com.navi.payment.nativepayment.utils.NaviPaymentRewardsEventBus
|
||||
import com.navi.payment.tstore.repository.TStoreOrderHandler
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.invoke
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.json.JSONObject
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Unit tests for PayBillViewModel.
|
||||
*
|
||||
* Tests cover important functionality including:
|
||||
* - Credit card payment option handling
|
||||
* - Bill fetch behavior via BillFetchHandler
|
||||
* - Payment processing
|
||||
* - Validation logic
|
||||
*/
|
||||
class PayBillViewModelTest : NaviBbpsBaseTest() {
|
||||
@MockK private lateinit var savedStateHandle: SavedStateHandle
|
||||
@MockK private lateinit var payBillRepository: PayBillRepository
|
||||
@MockK private lateinit var naviBbpsDateUtils: NaviBbpsDateUtils
|
||||
@MockK private lateinit var resourceProvider: ResourceProvider
|
||||
@MockK private lateinit var billCategoriesRepository: BillCategoriesRepository
|
||||
@MockK private lateinit var myBillsRepository: MyBillsRepository
|
||||
@MockK private lateinit var naviBbpsCommonRepository: BbpsCommonRepository
|
||||
@MockK private lateinit var naviNetworkConnectivity: NaviNetworkConnectivity
|
||||
@MockK private lateinit var naviBbpsSessionHelper: NaviBbpsSessionHelper
|
||||
@MockK private lateinit var fetchBillHandler: FetchBillHandler
|
||||
@MockK private lateinit var coinsSyncManager: CoinsSyncManager
|
||||
@MockK
|
||||
private lateinit var zeroPlatformFeeBottomSheetViewTracker:
|
||||
ZeroPlatformFeeBottomSheetViewTracker
|
||||
@MockK private lateinit var litmusExperimentsUseCase: LitmusExperimentsUseCase
|
||||
@MockK private lateinit var naviBbpsConfigUseCase: NaviBbpsConfigUseCase
|
||||
@MockK private lateinit var rewardsNudgeEntityFetchUseCase: RewardNudgeUseCase
|
||||
@MockK private lateinit var tStoreOrderHandler: TStoreOrderHandler
|
||||
@MockK private lateinit var resProvider: ResourceProvider
|
||||
@MockK private lateinit var naviPaymentRewardEventBus: NaviPaymentRewardsEventBus
|
||||
@MockK private lateinit var payBillAmountChipsHelper: PayBillAmountChipsHelper
|
||||
@MockK private lateinit var bbpsArcHelper: BbpsArcHelper
|
||||
@MockK private lateinit var notifyDuplicatePaymentHandler: NotifyDuplicatePaymentHandler
|
||||
|
||||
private lateinit var viewModel: PayBillViewModel
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
every { naviBbpsSessionHelper.getNaviBbpsSessionAttributes() } returns HashMap()
|
||||
every { naviNetworkConnectivity.isInternetConnected() } returns true
|
||||
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
val mockBillerDetailsEntity = mockk<BillerDetailsEntity>(relaxed = true)
|
||||
val payBillSource =
|
||||
PayBillSource.Others(
|
||||
billerDetailsEntity = mockBillerDetailsEntity,
|
||||
billDetailsEntity = null,
|
||||
customerParams = mapOf(),
|
||||
formattedLastPaidDate = "",
|
||||
formattedLastPaidAmount = "",
|
||||
billerId = "test_biller_id",
|
||||
amount = "100.00",
|
||||
isConsentRequired = false,
|
||||
)
|
||||
every { savedStateHandle.get<PayBillSource>("payBillScreenSource") } returns payBillSource
|
||||
|
||||
val billCategoryEntity =
|
||||
BillCategoryEntity(
|
||||
categoryId = "test_category_id",
|
||||
title = "Test Category",
|
||||
iconUrl = "https://example.com/icon.png",
|
||||
searchBoxPlaceholderText = "Search billers",
|
||||
billerListStateHeading = "Popular billers",
|
||||
billerListAllHeading = "All billers",
|
||||
reminderTitle = "Set reminder",
|
||||
)
|
||||
every { savedStateHandle.get<BillCategoryEntity>("billCategoryEntity") } returns
|
||||
billCategoryEntity
|
||||
|
||||
val phoneContactEntity = mockk<PhoneContactEntity>(relaxed = true)
|
||||
every { savedStateHandle.get<PhoneContactEntity>("phoneNumberDetail") } returns
|
||||
phoneContactEntity
|
||||
|
||||
every { savedStateHandle.get<Boolean>("isRootScreen") } returns true
|
||||
every { savedStateHandle.get<Boolean>("isBillSyncRequiredInBackground") } returns false
|
||||
every { savedStateHandle.get<String>("source") } returns "test_source"
|
||||
every { savedStateHandle.get<String>("initialSource") } returns "test_initial_source"
|
||||
|
||||
val naviBbpsDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(screenName = "Pay bill") } returns
|
||||
naviBbpsDefaultConfig
|
||||
|
||||
viewModel =
|
||||
PayBillViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
dispatcherProvider = TestCoroutineDispatcherProvider(testDispatcher),
|
||||
payBillRepository = payBillRepository,
|
||||
naviBbpsDateUtils = naviBbpsDateUtils,
|
||||
resourceProvider = resourceProvider,
|
||||
billCategoriesRepository = billCategoriesRepository,
|
||||
myBillsRepository = myBillsRepository,
|
||||
naviBbpsCommonRepository = naviBbpsCommonRepository,
|
||||
naviNetworkConnectivity = naviNetworkConnectivity,
|
||||
naviBbpsSessionHelper = naviBbpsSessionHelper,
|
||||
fetchBillHandler = fetchBillHandler,
|
||||
coinsSyncManager = coinsSyncManager,
|
||||
zeroPlatformFeeBottomSheetViewTracker = zeroPlatformFeeBottomSheetViewTracker,
|
||||
litmusExperimentsUseCase = litmusExperimentsUseCase,
|
||||
naviBbpsConfigUseCase = naviBbpsConfigUseCase,
|
||||
rewardsNudgeEntityFetchUseCase = rewardsNudgeEntityFetchUseCase,
|
||||
payBillAmountChipsHelper = payBillAmountChipsHelper,
|
||||
bbpsArcHelper = bbpsArcHelper,
|
||||
notifyDuplicatePaymentHandler = notifyDuplicatePaymentHandler,
|
||||
tStoreOrderHandler = tStoreOrderHandler,
|
||||
resProvider = resProvider,
|
||||
naviPaymentRewardEventBus = naviPaymentRewardEventBus,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `updatePaymentAmount should update payment amount state flow`() = runTest {
|
||||
val testAmount = "100.00"
|
||||
viewModel.updatePaymentAmount(testAmount)
|
||||
assertEquals(testAmount, viewModel.paymentAmount.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPayButtonEnabled should be false when amount is empty`() = runTest {
|
||||
viewModel.updatePaymentAmount("")
|
||||
assertFalse(viewModel.isPayButtonEnabled.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPayButtonEnabled should be false when amount is zero`() = runTest {
|
||||
viewModel.updatePaymentAmount("0")
|
||||
assertFalse(viewModel.isPayButtonEnabled.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPayButtonEnabled should be false when amount is valid but bill details are null`() =
|
||||
runTest {
|
||||
viewModel.updatePaymentAmount("100.00")
|
||||
assertFalse(viewModel.isPayButtonEnabled.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onCreditCardPaymentOptionSelected should update selection and set amount for total option`() =
|
||||
runTest {
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
val billDetailsEntity =
|
||||
BillDetailsEntity(
|
||||
billId = "bill_123",
|
||||
billerId = "biller_456",
|
||||
referenceId = "ref_789",
|
||||
amount = "1000.00",
|
||||
dueDate = "2023-12-31",
|
||||
billDate = "2023-12-01",
|
||||
billNumber = "BILL123",
|
||||
accountHolderName = "Test User",
|
||||
billerAdditionalParams = emptyList(),
|
||||
billPeriod = "Dec 2023",
|
||||
)
|
||||
|
||||
val testPayBillSource =
|
||||
PayBillSource.Others(
|
||||
billerDetailsEntity = mockk(relaxed = true),
|
||||
billDetailsEntity = billDetailsEntity,
|
||||
customerParams = mapOf(),
|
||||
formattedLastPaidDate = "",
|
||||
formattedLastPaidAmount = "",
|
||||
billerId = "test_biller_id",
|
||||
amount = "1000.00",
|
||||
isConsentRequired = false,
|
||||
)
|
||||
|
||||
every { savedStateHandle.get<PayBillSource>("payBillScreenSource") } returns
|
||||
testPayBillSource
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onCreditCardPaymentOptionSelected should update selection and set amount for minimum option`() =
|
||||
runTest {
|
||||
val billDetailsEntity =
|
||||
BillDetailsEntity(
|
||||
billId = "bill_123",
|
||||
billerId = "biller_456",
|
||||
referenceId = "ref_789",
|
||||
amount = "1000.00",
|
||||
dueDate = "2023-12-31",
|
||||
billDate = "2023-12-01",
|
||||
billNumber = "BILL123",
|
||||
accountHolderName = "Test User",
|
||||
billerAdditionalParams =
|
||||
listOf(
|
||||
BillerAdditionalParamsEntity(
|
||||
paramName = "MinimumDueAmount",
|
||||
value = "200.00",
|
||||
displayName = "Minimum Due",
|
||||
shouldDisplay = true,
|
||||
displayOrder = 1,
|
||||
)
|
||||
),
|
||||
billPeriod = "Dec 2023",
|
||||
)
|
||||
|
||||
val testPayBillSource =
|
||||
PayBillSource.Others(
|
||||
billerDetailsEntity = mockk(relaxed = true),
|
||||
billDetailsEntity = billDetailsEntity,
|
||||
customerParams = mapOf(),
|
||||
formattedLastPaidDate = "",
|
||||
formattedLastPaidAmount = "",
|
||||
billerId = "test_biller_id",
|
||||
amount = "1000.00",
|
||||
isConsentRequired = false,
|
||||
)
|
||||
|
||||
every { savedStateHandle.get<PayBillSource>("payBillScreenSource") } returns
|
||||
testPayBillSource
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `updateConsentProvided should update consent state`() = runTest {
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
// Start with a default value
|
||||
viewModel.updateConsentProvided(false)
|
||||
|
||||
// Verify initial state
|
||||
assertEquals(false, viewModel.isConsentProvided.first())
|
||||
|
||||
// Call the method we want to test
|
||||
viewModel.updateConsentProvided(true)
|
||||
|
||||
// Verify updated state
|
||||
assertEquals(true, viewModel.isConsentProvided.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `payment amount exactness should update error message ID`() = runTest {
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
viewModel.updatePaymentAmount("123.45")
|
||||
|
||||
assertNotNull(viewModel.errorMessageId.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onPaymentResultReceived should handle failed payment`() = runTest {
|
||||
viewModel.onPaymentResultReceived(
|
||||
bbpsTransactionId = "",
|
||||
paymentResponseMetadata = JSONObject(),
|
||||
)
|
||||
|
||||
assertFalse(viewModel.isPayButtonClicked)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `header state should be updatable`() = runTest {
|
||||
val billerDetailsEntity = mockk<BillerDetailsEntity>(relaxed = true)
|
||||
|
||||
val payBillSource =
|
||||
PayBillSource.Others(
|
||||
billerDetailsEntity = billerDetailsEntity,
|
||||
billDetailsEntity = null,
|
||||
customerParams = mapOf(),
|
||||
formattedLastPaidDate = "",
|
||||
formattedLastPaidAmount = "",
|
||||
billerId = "test_biller_id",
|
||||
amount = "100.00",
|
||||
isConsentRequired = false,
|
||||
)
|
||||
|
||||
every { savedStateHandle.get<PayBillSource>("payBillScreenSource") } returns payBillSource
|
||||
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
val testViewModel =
|
||||
PayBillViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
dispatcherProvider = TestCoroutineDispatcherProvider(testDispatcher),
|
||||
payBillRepository = payBillRepository,
|
||||
naviBbpsDateUtils = naviBbpsDateUtils,
|
||||
resourceProvider = resourceProvider,
|
||||
billCategoriesRepository = billCategoriesRepository,
|
||||
myBillsRepository = myBillsRepository,
|
||||
naviBbpsCommonRepository = naviBbpsCommonRepository,
|
||||
naviNetworkConnectivity = naviNetworkConnectivity,
|
||||
naviBbpsSessionHelper = naviBbpsSessionHelper,
|
||||
fetchBillHandler = fetchBillHandler,
|
||||
coinsSyncManager = coinsSyncManager,
|
||||
zeroPlatformFeeBottomSheetViewTracker = zeroPlatformFeeBottomSheetViewTracker,
|
||||
litmusExperimentsUseCase = litmusExperimentsUseCase,
|
||||
naviBbpsConfigUseCase = naviBbpsConfigUseCase,
|
||||
rewardsNudgeEntityFetchUseCase = rewardsNudgeEntityFetchUseCase,
|
||||
payBillAmountChipsHelper = payBillAmountChipsHelper,
|
||||
bbpsArcHelper = bbpsArcHelper,
|
||||
notifyDuplicatePaymentHandler = notifyDuplicatePaymentHandler,
|
||||
tStoreOrderHandler = tStoreOrderHandler,
|
||||
resProvider = resProvider,
|
||||
naviPaymentRewardEventBus = naviPaymentRewardEventBus,
|
||||
)
|
||||
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
|
||||
val expectedHeaderState =
|
||||
PayBillHeaderState.OtherHeaders(billerDetailsEntity = billerDetailsEntity)
|
||||
assertEquals(expectedHeaderState, testViewModel.payBillHeaderState.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bill fetch failure should update error state`() = runTest {
|
||||
coEvery {
|
||||
fetchBillHandler.fetchBill(
|
||||
payBillViewModel = any(),
|
||||
isConsentProvided = any(),
|
||||
onSuccess = any(),
|
||||
onError = captureLambda(),
|
||||
screenName = any(),
|
||||
)
|
||||
} answers { lambda<() -> Unit>().invoke() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bill fetch success should update UI state`() = runTest {
|
||||
val billEntity =
|
||||
BillDetailsEntity(
|
||||
billId = "bill_123",
|
||||
billerId = "biller_456",
|
||||
referenceId = "ref_789",
|
||||
amount = "1000.00",
|
||||
dueDate = "2023-12-31",
|
||||
billDate = "2023-12-01",
|
||||
billNumber = "BILL123",
|
||||
accountHolderName = "Test User",
|
||||
billerAdditionalParams = emptyList(),
|
||||
billPeriod = "Dec 2023",
|
||||
)
|
||||
|
||||
coEvery {
|
||||
fetchBillHandler.fetchBill(
|
||||
payBillViewModel = any(),
|
||||
isConsentProvided = any(),
|
||||
onSuccess = captureLambda(),
|
||||
onError = any(),
|
||||
screenName = any(),
|
||||
)
|
||||
} answers { lambda<(BillDetailsEntity, Boolean) -> Unit>().invoke(billEntity, false) }
|
||||
setupBillDetailsEntity(billEntity)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should be able to auto focus on amount field`() = runTest {
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
val testViewModel =
|
||||
PayBillViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
dispatcherProvider = TestCoroutineDispatcherProvider(testDispatcher),
|
||||
payBillRepository = payBillRepository,
|
||||
naviBbpsDateUtils = naviBbpsDateUtils,
|
||||
resourceProvider = resourceProvider,
|
||||
billCategoriesRepository = billCategoriesRepository,
|
||||
myBillsRepository = myBillsRepository,
|
||||
naviBbpsCommonRepository = naviBbpsCommonRepository,
|
||||
naviNetworkConnectivity = naviNetworkConnectivity,
|
||||
naviBbpsSessionHelper = naviBbpsSessionHelper,
|
||||
fetchBillHandler = fetchBillHandler,
|
||||
coinsSyncManager = coinsSyncManager,
|
||||
zeroPlatformFeeBottomSheetViewTracker = zeroPlatformFeeBottomSheetViewTracker,
|
||||
litmusExperimentsUseCase = litmusExperimentsUseCase,
|
||||
naviBbpsConfigUseCase = naviBbpsConfigUseCase,
|
||||
rewardsNudgeEntityFetchUseCase = rewardsNudgeEntityFetchUseCase,
|
||||
payBillAmountChipsHelper = payBillAmountChipsHelper,
|
||||
bbpsArcHelper = bbpsArcHelper,
|
||||
notifyDuplicatePaymentHandler = notifyDuplicatePaymentHandler,
|
||||
tStoreOrderHandler = tStoreOrderHandler,
|
||||
resProvider = resProvider,
|
||||
naviPaymentRewardEventBus = naviPaymentRewardEventBus,
|
||||
)
|
||||
|
||||
val autoFocusField = testViewModel.javaClass.getDeclaredField("_shouldAutoFocusOnAmount")
|
||||
autoFocusField.isAccessible = true
|
||||
val stateFlow = autoFocusField.get(testViewModel) as MutableStateFlow<Boolean>
|
||||
stateFlow.value = true
|
||||
|
||||
assertTrue(testViewModel.shouldAutoFocusOnAmount.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `setting bill category entity should update related information`() = runTest {
|
||||
val categoryEntity =
|
||||
BillCategoryEntity(
|
||||
categoryId = "1",
|
||||
title = "Test Category",
|
||||
iconUrl = "https://test.com/image.png",
|
||||
searchBoxPlaceholderText = "Search billers",
|
||||
billerListStateHeading = "Popular billers",
|
||||
billerListAllHeading = "All billers",
|
||||
reminderTitle = "Set reminder",
|
||||
)
|
||||
|
||||
every { savedStateHandle.get<BillCategoryEntity>("billCategoryEntity") } returns
|
||||
categoryEntity
|
||||
|
||||
val mockDefaultConfig = mockk<NaviBbpsDefaultConfig>(relaxed = true)
|
||||
mockkStatic("com.navi.bbps.common.utils.ConfigExtKt")
|
||||
coEvery { naviBbpsConfigUseCase.getDefaultConfig(any()) } returns mockDefaultConfig
|
||||
|
||||
val testViewModel =
|
||||
PayBillViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
dispatcherProvider = TestCoroutineDispatcherProvider(testDispatcher),
|
||||
payBillRepository = payBillRepository,
|
||||
naviBbpsDateUtils = naviBbpsDateUtils,
|
||||
resourceProvider = resourceProvider,
|
||||
billCategoriesRepository = billCategoriesRepository,
|
||||
myBillsRepository = myBillsRepository,
|
||||
naviBbpsCommonRepository = naviBbpsCommonRepository,
|
||||
naviNetworkConnectivity = naviNetworkConnectivity,
|
||||
naviBbpsSessionHelper = naviBbpsSessionHelper,
|
||||
fetchBillHandler = fetchBillHandler,
|
||||
coinsSyncManager = coinsSyncManager,
|
||||
zeroPlatformFeeBottomSheetViewTracker = zeroPlatformFeeBottomSheetViewTracker,
|
||||
litmusExperimentsUseCase = litmusExperimentsUseCase,
|
||||
naviBbpsConfigUseCase = naviBbpsConfigUseCase,
|
||||
rewardsNudgeEntityFetchUseCase = rewardsNudgeEntityFetchUseCase,
|
||||
payBillAmountChipsHelper = payBillAmountChipsHelper,
|
||||
bbpsArcHelper = bbpsArcHelper,
|
||||
notifyDuplicatePaymentHandler = notifyDuplicatePaymentHandler,
|
||||
tStoreOrderHandler = tStoreOrderHandler,
|
||||
resProvider = resProvider,
|
||||
naviPaymentRewardEventBus = naviPaymentRewardEventBus,
|
||||
)
|
||||
|
||||
assertEquals(categoryEntity, testViewModel.billCategoryEntity)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should be able to update saved bill in repository`() = runTest {
|
||||
val myBillEntity = mockk<MyBillEntity>(relaxed = true)
|
||||
coEvery { myBillsRepository.updateSavedBill(any()) } returns Unit
|
||||
|
||||
myBillsRepository.updateSavedBill(myBillEntity)
|
||||
|
||||
coVerify { myBillsRepository.updateSavedBill(myBillEntity) }
|
||||
}
|
||||
|
||||
private fun setupBillDetailsEntity(billDetailsEntity: BillDetailsEntity) {
|
||||
val payBillSource =
|
||||
PayBillSource.Others(
|
||||
billerDetailsEntity = mockk(relaxed = true),
|
||||
billDetailsEntity = billDetailsEntity,
|
||||
customerParams = mapOf(),
|
||||
formattedLastPaidDate = "",
|
||||
formattedLastPaidAmount = "",
|
||||
billerId = "test_biller_id",
|
||||
amount = "100.00",
|
||||
isConsentRequired = false,
|
||||
)
|
||||
every { savedStateHandle.get<PayBillSource>("payBillScreenSource") } returns payBillSource
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user