From 96dc1aa6d8960ee6ca82f7deea9249f600cc2282 Mon Sep 17 00:00:00 2001 From: Yun Cheng <129205442+ycheng-kickstarter@users.noreply.github.com> Date: Thu, 9 May 2024 18:32:01 -0400 Subject: [PATCH] MBL-1326 bonus support input (#2030) * Functionality minus currency symbol and styling * Move currency symbol out of TextField into its own Text * Wrap currency symbol and amount into a stylized right aligned row * Separate currency symbol start and end * Cursor brush * Remove logs * Fix lint * Address feedback and stylize max pledge amount * Remove unused util method * Fix lint * Fix max input amount error messaging * Fix relationship between initialBonusSupport and totalBonusSupport * Address feedback to move to util methods * Couple of tests * Oops lint * Change variable name --------- Co-authored-by: Isabel Martin Co-authored-by: mtgriego --- .../com/kickstarter/libs/utils/RewardUtils.kt | 13 ++ .../kickstarter/libs/utils/RewardViewUtils.kt | 40 ++++++ .../ui/activities/ProjectPageActivity.kt | 5 +- .../projectpage/ConfirmPledgeDetailsScreen.kt | 133 +++++++++++++----- ...ProjectPledgeButtonAndFragmentContainer.kt | 3 + .../projectpage/ConfirmDetailsViewModel.kt | 14 +- .../kickstarter/libs/utils/RewardUtilsTest.kt | 33 ++++- .../libs/utils/RewardViewUtilsTest.kt | 18 +++ .../viewmodels/ConfirmDetailsViewModelTest.kt | 20 +-- 9 files changed, 226 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/com/kickstarter/libs/utils/RewardUtils.kt b/app/src/main/java/com/kickstarter/libs/utils/RewardUtils.kt index 4e4a0c37af..43018233e0 100644 --- a/app/src/main/java/com/kickstarter/libs/utils/RewardUtils.kt +++ b/app/src/main/java/com/kickstarter/libs/utils/RewardUtils.kt @@ -208,4 +208,17 @@ object RewardUtils { else -> floor(seconds / 60.0 / 60.0 / 24.0).toInt() } } + + /** + * Returns the finalBonusSupportAmount as either the initialBonusSupport OR the addedBonusSupport, + * depending on if the user chose to change the bonus amount from the original initialBonusAmount. + * + * The initialBonusSupport is the bonus amount the user initially sees upon landing on the Confirm + * Pledge Details screen. Most of the time initialBonusSupport will be 0, but for the case of No + * Reward, the initialBonusSupport is 1. If the user inputs a bonus amount, we use that as + * the finalBonusSupportAmount, otherwise we use the initialBonusSupport. + */ + fun getFinalBonusSupportAmount(addedBonusSupport: Double, initialBonusSupport: Double): Double { + return if (addedBonusSupport > 0) addedBonusSupport else initialBonusSupport + } } diff --git a/app/src/main/java/com/kickstarter/libs/utils/RewardViewUtils.kt b/app/src/main/java/com/kickstarter/libs/utils/RewardViewUtils.kt index 4ffccab516..b7f2ae2039 100644 --- a/app/src/main/java/com/kickstarter/libs/utils/RewardViewUtils.kt +++ b/app/src/main/java/com/kickstarter/libs/utils/RewardViewUtils.kt @@ -9,6 +9,7 @@ import android.text.style.RelativeSizeSpan import android.util.Pair import androidx.annotation.StringRes import com.kickstarter.R +import com.kickstarter.libs.Environment import com.kickstarter.libs.KSCurrency import com.kickstarter.libs.KSString import com.kickstarter.libs.models.Country @@ -99,4 +100,43 @@ object RewardViewUtils { ) return spannable } + + /** + * Returns the string for the error message a user receives when their inputted bonus amount causes + * the total pledge amount to exceed the max pledge amount: + * + * Enter an amount less than $X. + * + * where X is calculated as maxPledgeAmount - rewardAmount + */ + fun getMaxInputString( + context: Context, + selectedReward: Reward?, + maxPledgeAmount: Double, + totalAmount: Double, + totalBonusSupport: Double, + currencySymbolStartAndEnd: kotlin.Pair, + environment: Environment? + ): String { + + // rewardAmount + totalBonusSupport = totalAmount + // totalAmount must be <= maxPledgeAmount + + val maxInputAmount = if (selectedReward != null && RewardUtils.isNoReward(selectedReward)) { + maxPledgeAmount + } else { + val rewardAmount = totalAmount - totalBonusSupport + maxPledgeAmount - rewardAmount + } + val maxInputAmountWithCurrency = + (currencySymbolStartAndEnd.first ?: "") + + if (maxInputAmount % 1.0 == 0.0) maxInputAmount.toInt().toString() + else maxInputAmount.toString() + (currencySymbolStartAndEnd.second ?: "") + + return environment?.ksString()?.format( + context.getString(R.string.Enter_an_amount_less_than_max_pledge), // TODO: MBL-1416 Copy should say less than or equal to + "max_pledge", + maxInputAmountWithCurrency + ) ?: "" + } } diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt index b503eb078e..c658de6bc5 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt @@ -540,7 +540,7 @@ class ProjectPageActivity : val rewardsAndAddOns = confirmUiState.rewardsAndAddOns val shippingAmount = confirmUiState.shippingAmount val initialBonusAmount = confirmUiState.initialBonusSupportAmount - val totalBonusSupportAmount = confirmUiState.totalBonusSupportAmount + val totalBonusSupportAmount = confirmUiState.finalBonusSupportAmount val maxPledgeAmount = confirmUiState.maxPledgeAmount val minStepAmount = confirmUiState.minStepAmount val confirmDetailsIsLoading = confirmUiState.isLoading @@ -684,6 +684,9 @@ class ProjectPageActivity : userEmail = userEmail, onBonusSupportMinusClicked = { confirmDetailsViewModel.decrementBonusSupport() }, onBonusSupportPlusClicked = { confirmDetailsViewModel.incrementBonusSupport() }, + onBonusSupportInputted = { input -> + confirmDetailsViewModel.inputBonusSupport(input) + }, selectedAddOnsMap = selectedAddOnsMap, onPledgeCtaClicked = { selectedCard -> selectedCard?.apply { diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ConfirmPledgeDetailsScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ConfirmPledgeDetailsScreen.kt index 9c50e08126..a6c4066a23 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ConfirmPledgeDetailsScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ConfirmPledgeDetailsScreen.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -14,6 +15,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Scaffold import androidx.compose.material.Surface import androidx.compose.material.Text @@ -21,14 +24,22 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.integerResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import com.kickstarter.R import com.kickstarter.libs.Environment import com.kickstarter.libs.KSString import com.kickstarter.libs.utils.DateTimeUtils +import com.kickstarter.libs.utils.ProjectViewUtils import com.kickstarter.libs.utils.RewardViewUtils import com.kickstarter.libs.utils.extensions.isNotNull +import com.kickstarter.libs.utils.extensions.parseToDouble import com.kickstarter.models.Project import com.kickstarter.models.Reward import com.kickstarter.models.ShippingRule @@ -64,7 +75,8 @@ private fun ConfirmPledgeDetailsScreenPreviewNoRewards() { minPledgeStep = 1.0, onShippingRuleSelected = {}, onBonusSupportMinusClicked = {}, - onBonusSupportPlusClicked = {} + onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {} ) } } @@ -90,7 +102,8 @@ private fun ConfirmPledgeDetailsScreenPreviewNoRewardsWarning() { minPledgeStep = 1.0, onShippingRuleSelected = {}, onBonusSupportMinusClicked = {}, - onBonusSupportPlusClicked = {} + onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {} ) } } @@ -121,7 +134,8 @@ private fun ConfirmPledgeDetailsScreenPreviewNoAddOnsOrBonusSupport() { countryList = listOf(ShippingRule.builder().build()), onShippingRuleSelected = {}, onBonusSupportMinusClicked = {}, - onBonusSupportPlusClicked = {} + onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {} ) } } @@ -151,7 +165,8 @@ private fun ConfirmPledgeDetailsScreenPreviewAddOnsOnly() { minPledgeStep = 1.0, onShippingRuleSelected = {}, onBonusSupportMinusClicked = {}, - onBonusSupportPlusClicked = {} + onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {} ) } } @@ -182,7 +197,8 @@ private fun ConfirmPledgeDetailsScreenPreviewBonusSupportOnly() { countryList = listOf(ShippingRule.builder().build()), onShippingRuleSelected = {}, onBonusSupportMinusClicked = {}, - onBonusSupportPlusClicked = {} + onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {} ) } } @@ -212,7 +228,8 @@ private fun ConfirmPledgeDetailsScreenPreviewAddOnsAndBonusSupport() { minPledgeStep = 1.0, onShippingRuleSelected = {}, onBonusSupportMinusClicked = {}, - onBonusSupportPlusClicked = {} + onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {} ) } } @@ -238,7 +255,8 @@ fun ConfirmPledgeDetailsScreen( minPledgeStep: Double, isLoading: Boolean = false, onBonusSupportPlusClicked: () -> Unit, - onBonusSupportMinusClicked: () -> Unit + onBonusSupportMinusClicked: () -> Unit, + onBonusSupportInputted: (input: Double) -> Unit ) { val interactionSource = remember { MutableInteractionSource() @@ -293,6 +311,21 @@ fun ConfirmPledgeDetailsScreen( ).toString() } ?: "" + // Currency symbol, which can be positioned at start or end of amount depending on country + val currencySymbolStartAndEnd = environment?.ksCurrency()?.let { + val symbolAndStart = ProjectViewUtils.currencySymbolAndPosition( + project, + it + ) + val symbol = symbolAndStart.first + val symbolAtStart = symbolAndStart.second + if (symbolAtStart) { + Pair(symbol.toString(), null) + } else { + Pair(null, symbol.toString()) + } + } ?: Pair(null, null) + val deliveryDateString = if (selectedReward?.estimatedDeliveryOn().isNotNull()) { DateTimeUtils.estimatedDeliveryOn( requireNotNull( @@ -301,11 +334,7 @@ fun ConfirmPledgeDetailsScreen( ) } else "" - val maxPledgeString = environment?.ksString()?.format( - stringResource(R.string.Enter_an_amount_less_than_max_pledge), - "max_pledge", - maxPledgeAmount.toString() - ) ?: "" + val maxInputString = RewardViewUtils.getMaxInputString(LocalContext.current, selectedReward, maxPledgeAmount, totalAmount, totalBonusSupport, currencySymbolStartAndEnd, environment) Box( modifier = Modifier.fillMaxSize(), @@ -428,20 +457,28 @@ fun ConfirmPledgeDetailsScreen( item { BonusSupportContainer( isForNoRewardPledge = rewardsList.isEmpty(), - initialValue = initialBonusSupportString, - totalBonusAmount = totalBonusSupportString, + initialBonusSupport = initialBonusSupport, + totalBonusSupport = totalBonusSupport, + currencySymbolAtStart = currencySymbolStartAndEnd.first, + currencySymbolAtEnd = currencySymbolStartAndEnd.second, canAddMore = totalAmount + minPledgeStep <= maxPledgeAmount, onBonusSupportPlusClicked = onBonusSupportPlusClicked, - onBonusSupportMinusClicked = onBonusSupportMinusClicked + onBonusSupportMinusClicked = onBonusSupportMinusClicked, + onBonusSupportInputted = onBonusSupportInputted ) - if (totalAmount >= maxPledgeAmount) { - Spacer(modifier = Modifier.height(dimensions.paddingXSmall)) - + if (totalAmount > maxPledgeAmount) { Text( - text = maxPledgeString, - style = typography.headline, - color = colors.textAccentRedBold + text = maxInputString, + textAlign = TextAlign.Right, + style = typography.footnoteMedium, + color = colors.textAccentRed, + modifier = Modifier + .fillMaxWidth() + .padding( + start = dimensions.paddingMedium, + end = dimensions.paddingMedium, + ) ) } } @@ -518,12 +555,17 @@ fun ConfirmPledgeDetailsScreen( @Composable fun BonusSupportContainer( isForNoRewardPledge: Boolean, - initialValue: String, - totalBonusAmount: String, + initialBonusSupport: Double, + totalBonusSupport: Double, + currencySymbolAtStart: String?, + currencySymbolAtEnd: String?, canAddMore: Boolean, onBonusSupportPlusClicked: () -> Unit, - onBonusSupportMinusClicked: () -> Unit + onBonusSupportMinusClicked: () -> Unit, + onBonusSupportInputted: (input: Double) -> Unit ) { + val bonusAmountMaxDigits = integerResource(R.integer.max_length) + Column( modifier = Modifier.padding(all = dimensions.paddingMedium) ) { @@ -543,6 +585,7 @@ fun BonusSupportContainer( style = typography.body2, color = colors.textSecondary ) + Spacer(modifier = Modifier.height(dimensions.paddingSmall)) } Row( @@ -553,7 +596,7 @@ fun BonusSupportContainer( onPlusClicked = onBonusSupportPlusClicked, isPlusEnabled = canAddMore, onMinusClicked = onBonusSupportMinusClicked, - isMinusEnabled = initialValue != totalBonusAmount, + isMinusEnabled = initialBonusSupport != totalBonusSupport, enabledButtonBackgroundColor = colors.kds_white ) @@ -565,22 +608,44 @@ fun BonusSupportContainer( Spacer(modifier = Modifier.width(dimensions.paddingMediumSmall)) } - Text( + Row( + verticalAlignment = Alignment.CenterVertically, modifier = Modifier .background( color = colors.kds_white, shape = shapes.small ) .padding( - start = dimensions.paddingMediumSmall, - top = dimensions.paddingMediumSmall, - bottom = dimensions.paddingMediumSmall, - end = dimensions.paddingMediumSmall + start = dimensions.paddingXSmall, + top = dimensions.paddingXSmall, + bottom = dimensions.paddingXSmall, + end = dimensions.paddingXSmall ), - text = totalBonusAmount, - style = typography.headline, - color = colors.textAccentGreen - ) + + ) { + Text( + text = currencySymbolAtStart ?: "", + color = colors.textAccentGreen + ) + BasicTextField( + modifier = Modifier.width(IntrinsicSize.Min), + value = if (totalBonusSupport % 1.0 == 0.0) totalBonusSupport.toInt().toString() else totalBonusSupport.toString(), + onValueChange = { + if (it.length <= bonusAmountMaxDigits) onBonusSupportInputted(it.parseToDouble()) + }, + textStyle = typography.title1.copy(color = colors.textAccentGreen), + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Number, + imeAction = ImeAction.Done + ), + cursorBrush = SolidColor(colors.iconSubtle) + + ) + Text( + text = currencySymbolAtEnd ?: "", + color = colors.textAccentGreen + ) + } } } } diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt index 0e78af1869..1e299bb02d 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt @@ -109,6 +109,7 @@ private fun ProjectPledgeButtonAndContainerPreview() { selectedRewardAndAddOnList = listOf(), onBonusSupportMinusClicked = {}, onBonusSupportPlusClicked = {}, + onBonusSupportInputted = {}, storedCards = listOf(), userEmail = "test@test.test", onPledgeCtaClicked = {}, @@ -154,6 +155,7 @@ fun ProjectPledgeButtonAndFragmentContainer( selectedRewardAndAddOnList: List, onBonusSupportPlusClicked: () -> Unit, onBonusSupportMinusClicked: () -> Unit, + onBonusSupportInputted: (input: Double) -> Unit, storedCards: List, userEmail: String, onPledgeCtaClicked: (selectedCard: StoredCard?) -> Unit, @@ -312,6 +314,7 @@ fun ProjectPledgeButtonAndFragmentContainer( }, onBonusSupportPlusClicked = onBonusSupportPlusClicked, onBonusSupportMinusClicked = onBonusSupportMinusClicked, + onBonusSupportInputted = onBonusSupportInputted, isLoading = isLoading, ) } diff --git a/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt index 364d1c76c8..cfb662c62c 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/projectpage/ConfirmDetailsViewModel.kt @@ -30,7 +30,7 @@ import kotlinx.coroutines.rx2.asFlow data class ConfirmDetailsUIState( val rewardsAndAddOns: List = listOf(), val initialBonusSupportAmount: Double = 0.0, - val totalBonusSupportAmount: Double = 0.0, + val finalBonusSupportAmount: Double = 0.0, val shippingAmount: Double = 0.0, val totalAmount: Double = 0.0, val minStepAmount: Double = 0.0, @@ -142,7 +142,7 @@ class ConfirmDetailsViewModel(val environment: Environment) : ViewModel() { private fun calculateTotal(): Double { var total = 0.0 total += getRewardsTotalAmount(rewardAndAddOns) - total += initialBonusSupport + addedBonusSupport + total += RewardUtils.getFinalBonusSupportAmount(addedBonusSupport, initialBonusSupport) if (::userSelectedReward.isInitialized) { total += if (RewardUtils.isNoReward(userSelectedReward)) 0.0 @@ -240,6 +240,14 @@ class ConfirmDetailsViewModel(val environment: Environment) : ViewModel() { } } + fun inputBonusSupport(input: Double) { + addedBonusSupport = input + totalAmount = calculateTotal() + viewModelScope.launch { + emitCurrentState() + } + } + fun onContinueClicked(defaultAction: () -> Unit) { if (projectData.project().postCampaignPledgingEnabled() == true && projectData.project() .isInPostCampaignPledgingPhase() == true @@ -304,7 +312,7 @@ class ConfirmDetailsViewModel(val environment: Environment) : ViewModel() { ConfirmDetailsUIState( rewardsAndAddOns = rewardAndAddOns, initialBonusSupportAmount = initialBonusSupport, - totalBonusSupportAmount = initialBonusSupport + addedBonusSupport, + finalBonusSupportAmount = RewardUtils.getFinalBonusSupportAmount(addedBonusSupport, initialBonusSupport), shippingAmount = shippingAmount, totalAmount = totalAmount, minStepAmount = minStepAmount, diff --git a/app/src/test/java/com/kickstarter/libs/utils/RewardUtilsTest.kt b/app/src/test/java/com/kickstarter/libs/utils/RewardUtilsTest.kt index 8d4578117d..8a4138e9f3 100644 --- a/app/src/test/java/com/kickstarter/libs/utils/RewardUtilsTest.kt +++ b/app/src/test/java/com/kickstarter/libs/utils/RewardUtilsTest.kt @@ -64,7 +64,8 @@ class RewardUtilsTest : KSRobolectricTestCase() { rewardLimitReached = RewardFactory.limitReached() rewardMultipleShippingLocation = RewardFactory.multipleLocationShipping() rewardWorldWideShipping = RewardFactory.rewardWithShipping() - rewardSingleShippingLocation = RewardFactory.singleLocationShipping(LocationFactory.nigeria().displayableName()) + rewardSingleShippingLocation = + RewardFactory.singleLocationShipping(LocationFactory.nigeria().displayableName()) rewardWithAddons = RewardFactory.rewardHasAddOns() } @@ -329,10 +330,22 @@ class RewardUtilsTest : KSRobolectricTestCase() { .build() assertNull(shippingSummary(rewardWithNullShipping)) assertNull(shippingSummary(reward)) - assertEquals(Pair.create(R.string.Limited_shipping, ""), shippingSummary(rewardWithNullLocation)) - assertEquals(Pair.create(R.string.Limited_shipping, null), shippingSummary(rewardMultipleShippingLocation)) - assertEquals(Pair.create(R.string.location_name_only, COUNTRY_NIGERIA), shippingSummary(rewardSingleShippingLocation)) - assertEquals(Pair.create(R.string.Ships_worldwide, null), shippingSummary(rewardWorldWideShipping)) + assertEquals( + Pair.create(R.string.Limited_shipping, ""), + shippingSummary(rewardWithNullLocation) + ) + assertEquals( + Pair.create(R.string.Limited_shipping, null), + shippingSummary(rewardMultipleShippingLocation) + ) + assertEquals( + Pair.create(R.string.location_name_only, COUNTRY_NIGERIA), + shippingSummary(rewardSingleShippingLocation) + ) + assertEquals( + Pair.create(R.string.Ships_worldwide, null), + shippingSummary(rewardWorldWideShipping) + ) } @Test @@ -452,6 +465,16 @@ class RewardUtilsTest : KSRobolectricTestCase() { assertTrue(isLocalPickup(reward)) } + @Test + fun `test when user doesn't input any extra bonus amount that the final bonus support amount is initial bonus support amount `() { + assertEquals(1.0, RewardUtils.getFinalBonusSupportAmount(0.0, 1.0)) + } + + @Test + fun `test when user inputs some extra bonus amount that the final bonus support amount is whatever the user inputted`() { + assertEquals(5.0, RewardUtils.getFinalBonusSupportAmount(5.0, 1.0)) + } + companion object { private const val DAYS_TO_GO = "days to go" private const val HOURS_TO_GO = "hours to go" diff --git a/app/src/test/java/com/kickstarter/libs/utils/RewardViewUtilsTest.kt b/app/src/test/java/com/kickstarter/libs/utils/RewardViewUtilsTest.kt index 5e431c1f38..d4bdd84dbd 100644 --- a/app/src/test/java/com/kickstarter/libs/utils/RewardViewUtilsTest.kt +++ b/app/src/test/java/com/kickstarter/libs/utils/RewardViewUtilsTest.kt @@ -64,4 +64,22 @@ class RewardViewUtilsTest : KSRobolectricTestCase() { assertEquals("Limited shipping", RewardViewUtils.shippingSummary(context(), ksString, Pair(R.string.location_name_only, null))) assertEquals("Nigeria only", RewardViewUtils.shippingSummary(context(), ksString, Pair(R.string.location_name_only, "Nigeria"))) } + + @Test + fun `test when user exceeds max pledge amount the appropriate error message is returned`() { + val maxPledgeAmount = 1000.0 + val totalAmount = 1100.0 + val totalBonusSupport = 600.0 + + val maxInputString = RewardViewUtils.getMaxInputString( + context(), + RewardFactory.reward(), + maxPledgeAmount, + totalAmount, + totalBonusSupport, + kotlin.Pair("$", null), + environment().toBuilder().build() + ) + assertEquals("Enter an amount less than $500.", maxInputString) + } } diff --git a/app/src/test/java/com/kickstarter/viewmodels/ConfirmDetailsViewModelTest.kt b/app/src/test/java/com/kickstarter/viewmodels/ConfirmDetailsViewModelTest.kt index 1577ca4027..c55cbe1b84 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/ConfirmDetailsViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/ConfirmDetailsViewModelTest.kt @@ -71,7 +71,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(), initialBonusSupportAmount = 1.0, - totalBonusSupportAmount = 1.0, + finalBonusSupportAmount = 1.0, shippingAmount = 0.0, totalAmount = 1.0, minStepAmount = 1.0, @@ -99,7 +99,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 0.0, + finalBonusSupportAmount = 0.0, shippingAmount = 0.0, totalAmount = 20.0, minStepAmount = 1.0, @@ -131,7 +131,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 0.0, + finalBonusSupportAmount = 0.0, shippingAmount = 0.0, totalAmount = 40.0, minStepAmount = 1.0, @@ -147,7 +147,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_2), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 0.0, + finalBonusSupportAmount = 0.0, shippingAmount = 0.0, totalAmount = 60.0, minStepAmount = 1.0, @@ -180,7 +180,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 1.0, + finalBonusSupportAmount = 1.0, shippingAmount = 0.0, totalAmount = 41.0, minStepAmount = 1.0, @@ -196,7 +196,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 2.0, + finalBonusSupportAmount = 2.0, shippingAmount = 0.0, totalAmount = 42.0, minStepAmount = 1.0, @@ -212,7 +212,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 1.0, + finalBonusSupportAmount = 1.0, shippingAmount = 0.0, totalAmount = 41.0, minStepAmount = 1.0, @@ -228,7 +228,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 0.0, + finalBonusSupportAmount = 0.0, shippingAmount = 0.0, totalAmount = 40.0, minStepAmount = 1.0, @@ -262,7 +262,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 0.0, + finalBonusSupportAmount = 0.0, shippingAmount = 30.0, totalAmount = 70.0, minStepAmount = 1.0, @@ -278,7 +278,7 @@ class ConfirmDetailsViewModelTest : KSRobolectricTestCase() { ConfirmDetailsUIState( rewardsAndAddOns = listOf(reward, addOnQuantity_1), initialBonusSupportAmount = 0.0, - totalBonusSupportAmount = 0.0, + finalBonusSupportAmount = 0.0, shippingAmount = 40.0, totalAmount = 80.0, minStepAmount = 1.0,