-
Notifications
You must be signed in to change notification settings - Fork 990
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MBL-1296] Add tests for confirm details viewmodel (#2033)
* add tests for confirm details viewmodel * LINT --------- Co-authored-by: Yun Cheng <[email protected]>
- Loading branch information
1 parent
67362a7
commit 4974fd2
Showing
1 changed file
with
384 additions
and
0 deletions.
There are no files selected for viewing
384 changes: 384 additions & 0 deletions
384
app/src/test/java/com/kickstarter/viewmodels/ConfirmDetailsViewModelTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,384 @@ | ||
package com.kickstarter.viewmodels | ||
|
||
import com.kickstarter.KSRobolectricTestCase | ||
import com.kickstarter.mock.factories.ProjectDataFactory | ||
import com.kickstarter.mock.factories.ProjectFactory | ||
import com.kickstarter.mock.factories.RewardFactory | ||
import com.kickstarter.mock.factories.ShippingRuleFactory | ||
import com.kickstarter.mock.services.MockApolloClientV2 | ||
import com.kickstarter.models.CheckoutPayment | ||
import com.kickstarter.services.mutations.CreateCheckoutData | ||
import com.kickstarter.viewmodels.projectpage.ConfirmDetailsUIState | ||
import com.kickstarter.viewmodels.projectpage.ConfirmDetailsViewModel | ||
import io.reactivex.Observable | ||
import kotlinx.coroutines.ExperimentalCoroutinesApi | ||
import kotlinx.coroutines.flow.toList | ||
import kotlinx.coroutines.launch | ||
import kotlinx.coroutines.test.UnconfinedTestDispatcher | ||
import kotlinx.coroutines.test.runTest | ||
import org.junit.Before | ||
import org.junit.Test | ||
|
||
@OptIn(ExperimentalCoroutinesApi::class) | ||
class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { | ||
|
||
private lateinit var viewModel: ConfirmDetailsViewModel | ||
|
||
@Before | ||
fun setUpWithEnvironment() { | ||
viewModel = ConfirmDetailsViewModel.Factory(environment = environment()) | ||
.create(ConfirmDetailsViewModel::class.java) | ||
} | ||
|
||
@Test | ||
fun `test_when_project_provided_then_min_and_max_step_is_updated`() = runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
// US Project, min amount $1, max amount $10,000 | ||
val projectData1 = ProjectDataFactory.project(ProjectFactory.project()).toBuilder().build() | ||
viewModel.provideProjectData(projectData1) | ||
viewModel.onUserSelectedReward(RewardFactory.noReward()) | ||
|
||
assertEquals(uiState.last().minStepAmount, 1.0) | ||
assertEquals(uiState.last().maxPledgeAmount, 10000.0) | ||
|
||
// MX Project, min amount $10, max amount $200,000 | ||
val projectData2 = | ||
ProjectDataFactory.project(ProjectFactory.mxProject()).toBuilder().build() | ||
viewModel.provideProjectData(projectData2) | ||
viewModel.onUserSelectedReward(RewardFactory.noReward()) | ||
|
||
assertEquals(uiState.last().minStepAmount, 10.0) | ||
assertEquals(uiState.last().maxPledgeAmount, 200000.0) | ||
} | ||
|
||
@Test | ||
fun `test_when_no_reward_selected_then_ui_state_is_correct`() = runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val projectData1 = ProjectDataFactory.project(ProjectFactory.project()).toBuilder().build() | ||
viewModel.provideProjectData(projectData1) | ||
viewModel.onUserSelectedReward(RewardFactory.noReward()) | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(), | ||
initialBonusSupportAmount = 1.0, | ||
totalBonusSupportAmount = 1.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 1.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
} | ||
|
||
@Test | ||
fun `test_when_reward_selected_then_ui_state_is_correct`() = runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val reward = RewardFactory.reward() | ||
val projectData1 = ProjectDataFactory.project(ProjectFactory.project()).toBuilder().build() | ||
|
||
viewModel.provideProjectData(projectData1) | ||
viewModel.onUserSelectedReward(reward) | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 0.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 20.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
} | ||
|
||
@Test | ||
fun `test_when_reward_and_add_ons_selected_then_ui_state_is_correct`() = runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val reward = RewardFactory.reward() | ||
val addOn = RewardFactory.addOn() | ||
val addOnQuantity_1 = addOn.toBuilder().quantity(1).build() | ||
val addOnQuantity_2 = addOn.toBuilder().quantity(2).build() | ||
val projectData1 = ProjectDataFactory.project(ProjectFactory.project()).toBuilder().build() | ||
|
||
viewModel.provideProjectData(projectData1) | ||
viewModel.onUserSelectedReward(reward) | ||
viewModel.onUserUpdatedAddOns(mapOf(Pair(addOn, 1))) | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 0.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 40.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
|
||
viewModel.onUserUpdatedAddOns(mapOf(Pair(addOn, 2))) | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_2), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 0.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 60.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
} | ||
|
||
@Test | ||
fun `test_when_bonus_amount_changes_then_total_is_updated`() = runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val reward = RewardFactory.reward() | ||
val addOn = RewardFactory.addOn() | ||
val addOnQuantity_1 = addOn.toBuilder().quantity(1).build() | ||
val projectData1 = ProjectDataFactory.project(ProjectFactory.project()).toBuilder().build() | ||
|
||
viewModel.provideProjectData(projectData1) | ||
viewModel.onUserSelectedReward(reward) | ||
viewModel.onUserUpdatedAddOns(mapOf(Pair(addOn, 1))) | ||
|
||
viewModel.incrementBonusSupport() | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 1.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 41.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
|
||
viewModel.incrementBonusSupport() | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 2.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 42.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
|
||
viewModel.decrementBonusSupport() | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 1.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 41.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
|
||
viewModel.decrementBonusSupport() | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 0.0, | ||
shippingAmount = 0.0, | ||
totalAmount = 40.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
} | ||
|
||
@Test | ||
fun `test_when_shipping_rule_changes_then_total_and_shipping_amount_is_updated`() = runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val reward = RewardFactory.rewardWithShipping() | ||
val addOn = RewardFactory.addOn() | ||
val addOnQuantity_1 = addOn.toBuilder().quantity(1).build() | ||
val projectData1 = ProjectDataFactory.project(ProjectFactory.project()).toBuilder().build() | ||
val shippingRule1 = ShippingRuleFactory.usShippingRule() | ||
val shippingRule2 = ShippingRuleFactory.germanyShippingRule() | ||
|
||
viewModel.provideProjectData(projectData1) | ||
viewModel.onUserSelectedReward(reward) | ||
viewModel.onUserUpdatedAddOns(mapOf(Pair(addOn, 1))) | ||
viewModel.provideCurrentShippingRule(shippingRule1) | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 0.0, | ||
shippingAmount = 30.0, | ||
totalAmount = 70.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
|
||
viewModel.provideCurrentShippingRule(shippingRule2) | ||
|
||
assertEquals( | ||
uiState.last(), | ||
ConfirmDetailsUIState( | ||
rewardsAndAddOns = listOf(reward, addOnQuantity_1), | ||
initialBonusSupportAmount = 0.0, | ||
totalBonusSupportAmount = 0.0, | ||
shippingAmount = 40.0, | ||
totalAmount = 80.0, | ||
minStepAmount = 1.0, | ||
maxPledgeAmount = 10000.0, | ||
isLoading = false | ||
) | ||
) | ||
} | ||
|
||
@Test | ||
fun `test_when_continue_clicked_when_late_pledge_disabled_then_default_action_is_called`() = | ||
runTest { | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val projectData1 = ProjectDataFactory.project( | ||
ProjectFactory | ||
.project() | ||
.toBuilder() | ||
.isInPostCampaignPledgingPhase(false) | ||
.build() | ||
).toBuilder().build() | ||
|
||
var defaultActionCalled = false | ||
|
||
viewModel.provideProjectData(projectData1) | ||
|
||
val defaultAction: () -> Unit = { | ||
defaultActionCalled = true | ||
} | ||
|
||
viewModel.onContinueClicked(defaultAction) | ||
|
||
assertTrue(defaultActionCalled) | ||
} | ||
|
||
@Test | ||
fun `test_when_continue_clicked_when_late_pledge_enabled_then_create_checkout_is_called`() = | ||
runTest { | ||
var createCheckoutCalled = false | ||
viewModel = ConfirmDetailsViewModel.Factory( | ||
environment = environment().toBuilder() | ||
.apolloClientV2(object : MockApolloClientV2() { | ||
override fun createCheckout(createCheckoutData: CreateCheckoutData): Observable<CheckoutPayment> { | ||
createCheckoutCalled = true | ||
return Observable.empty() | ||
} | ||
}).build() | ||
).create(ConfirmDetailsViewModel::class.java) | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val projectData1 = ProjectDataFactory.project( | ||
ProjectFactory | ||
.project() | ||
.toBuilder() | ||
.isInPostCampaignPledgingPhase(true) | ||
.postCampaignPledgingEnabled(true) | ||
.build() | ||
).toBuilder().build() | ||
viewModel.provideProjectData(projectData1) | ||
viewModel.onContinueClicked {} | ||
|
||
assertTrue(createCheckoutCalled) | ||
} | ||
|
||
@Test | ||
fun `test_when_continue_clicked_when_late_pledge_enabled_and_errors_then_error_action_occurs`() = | ||
runTest { | ||
var errorMessage: String? = "error" | ||
viewModel = ConfirmDetailsViewModel.Factory( | ||
environment = environment().toBuilder() | ||
.apolloClientV2(object : MockApolloClientV2() { | ||
override fun createCheckout(createCheckoutData: CreateCheckoutData): Observable<CheckoutPayment> { | ||
return Observable.error(Throwable("This is an error")) | ||
} | ||
}).build() | ||
).create(ConfirmDetailsViewModel::class.java) | ||
val uiState = mutableListOf<ConfirmDetailsUIState>() | ||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) { | ||
viewModel.confirmDetailsUIState.toList(uiState) | ||
} | ||
|
||
val projectData1 = ProjectDataFactory.project( | ||
ProjectFactory | ||
.project() | ||
.toBuilder() | ||
.isInPostCampaignPledgingPhase(true) | ||
.postCampaignPledgingEnabled(true) | ||
.build() | ||
).toBuilder().build() | ||
viewModel.provideProjectData(projectData1) | ||
viewModel.provideErrorAction { errorMessage = it } | ||
viewModel.onContinueClicked {} | ||
|
||
// Default message is null | ||
assertNull(errorMessage) | ||
} | ||
} |