From 05a0581d592e0d8fc082f18e85982ac3ab16edcd Mon Sep 17 00:00:00 2001 From: JL Date: Mon, 23 Feb 2026 15:38:38 -0800 Subject: [PATCH] [MBL-2995] Create test for Featured Rewards (#2476) * add test for secret rewards * fix tests and naming --- .../mock/factories/RewardFactory.kt | 16 ++++++ .../kickstarter/libs/utils/RewardUtilsTest.kt | 21 +++++++ .../services/GraphQLTransformersTest.kt | 2 +- .../usecases/GetShippingRulesUseCaseTest.kt | 55 ++++++++++++++++--- 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/kickstarter/mock/factories/RewardFactory.kt b/app/src/main/java/com/kickstarter/mock/factories/RewardFactory.kt index be3030d3d..790098ea4 100644 --- a/app/src/main/java/com/kickstarter/mock/factories/RewardFactory.kt +++ b/app/src/main/java/com/kickstarter/mock/factories/RewardFactory.kt @@ -80,6 +80,22 @@ object RewardFactory { .build() } + @JvmStatic + fun featured(): Reward { + return reward().toBuilder() + .isFeatured(true) + .title("Featured reward") + .build() + } + + @JvmStatic + fun secret(): Reward { + return reward().toBuilder() + .isSecretReward(true) + .title("Secret reward") + .build() + } + fun endingSoon(): Reward { return reward().toBuilder() .endsAt(DateTime.now().plusDays(2)) 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 01ca897cb..da6c12085 100644 --- a/app/src/test/java/com/kickstarter/libs/utils/RewardUtilsTest.kt +++ b/app/src/test/java/com/kickstarter/libs/utils/RewardUtilsTest.kt @@ -19,6 +19,7 @@ import com.kickstarter.libs.utils.RewardUtils.isLocalPickup import com.kickstarter.libs.utils.RewardUtils.isNoReward import com.kickstarter.libs.utils.RewardUtils.isReward import com.kickstarter.libs.utils.RewardUtils.isShippable +import com.kickstarter.libs.utils.RewardUtils.isShippableToLocation import com.kickstarter.libs.utils.RewardUtils.isTimeLimitedEnd import com.kickstarter.libs.utils.RewardUtils.isTimeLimitedStart import com.kickstarter.libs.utils.RewardUtils.isValidTimeRange @@ -29,6 +30,7 @@ import com.kickstarter.libs.utils.RewardUtils.timeInSecondsUntilDeadline import com.kickstarter.mock.factories.LocationFactory import com.kickstarter.mock.factories.ProjectFactory import com.kickstarter.mock.factories.RewardFactory +import com.kickstarter.mock.factories.ShippingRuleFactory import com.kickstarter.models.Project import com.kickstarter.models.Reward import org.joda.time.DateTime @@ -491,6 +493,25 @@ class RewardUtilsTest : KSRobolectricTestCase() { assertFalse(shipsWorldwide(reward)) } + @Test + fun `isShippableToLocation when not restricted returns true`() { + assertTrue(isShippableToLocation(RewardFactory.rewardWithShipping(), null)) + assertTrue(isShippableToLocation(RewardFactory.digitalReward(), null)) + } + + @Test + fun `isShippableToLocation when restricted returns true only for location in rules`() { + val usRule = ShippingRuleFactory.usShippingRule() + val restrictedReward = RewardFactory.reward().toBuilder() + .shippingPreference(Reward.ShippingPreference.RESTRICTED.name) + .shippingType(Reward.SHIPPING_TYPE_MULTIPLE_LOCATIONS) + .shippingRules(listOf(usRule)) + .build() + assertTrue(isShippableToLocation(restrictedReward, usRule.location()!!.id())) + assertFalse(isShippableToLocation(restrictedReward, LocationFactory.mexico().id())) + assertFalse(isShippableToLocation(restrictedReward, null)) + } + 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/services/GraphQLTransformersTest.kt b/app/src/test/java/com/kickstarter/services/GraphQLTransformersTest.kt index ededb2615..2fbb852ef 100644 --- a/app/src/test/java/com/kickstarter/services/GraphQLTransformersTest.kt +++ b/app/src/test/java/com/kickstarter/services/GraphQLTransformersTest.kt @@ -311,7 +311,7 @@ class GraphQLTransformersTest : KSRobolectricTestCase() { } @Test - fun `test rewardTransformer returns correct featured value`() { + fun `test rewardTransformer maps featured from fragment to reward model`() { val reward = rewardTransformer( rewardGr = fragmentReward ) diff --git a/app/src/test/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCaseTest.kt b/app/src/test/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCaseTest.kt index b7b174b0b..f3add6054 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCaseTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/usecases/GetShippingRulesUseCaseTest.kt @@ -173,14 +173,12 @@ class GetShippingRulesUseCaseTest : KSRobolectricTestCase() { .isAvailable(true) .build() - val secretReward1 = RewardFactory.reward().toBuilder() - .isSecretReward(true) + val secretReward1 = RewardFactory.secret().toBuilder() .minimum(30.0) .isAvailable(true) .build() - val secretReward2 = RewardFactory.reward().toBuilder() - .isSecretReward(true) + val secretReward2 = RewardFactory.secret().toBuilder() .minimum(10.0) .isAvailable(true) .build() @@ -218,10 +216,8 @@ class GetShippingRulesUseCaseTest : KSRobolectricTestCase() { fun `unavailable secret rewards are preserved in order`() = runTest { val config = ConfigFactory.configForUSUser() - val secretUnavailable = RewardFactory.reward().toBuilder() - .isSecretReward(true) + val secretUnavailable = RewardFactory.secret().toBuilder() .isAvailable(false) - .minimum(50.0) .build() val regularAvailable = RewardFactory.reward().toBuilder() @@ -252,4 +248,49 @@ class GetShippingRulesUseCaseTest : KSRobolectricTestCase() { assertEquals(listOf(regularAvailable, secretUnavailable), filtered) } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun `featured and secret rewards are preserved in order`() = runTest { + val config = ConfigFactory.configForUSUser() + + val noReward = RewardFactory.noReward().toBuilder() + .isAvailable(true) + .build() + + val secretReward = RewardFactory.secret().toBuilder() + .isAvailable(true) + .build() + + val featuredReward = RewardFactory.featured().toBuilder() + .isAvailable(true) + .build() + + val regularReward = RewardFactory.reward().toBuilder() + .isAvailable(true) + .shippingPreference(Reward.ShippingPreference.UNRESTRICTED.name) + .build() + + val project = ProjectFactory.project() + .toBuilder() + .rewards(listOf(noReward, secretReward, featuredReward, regularReward)) + .isInPostCampaignPledgingPhase(true) + .postCampaignPledgingEnabled(true) + .build() + + val dispatcher = UnconfinedTestDispatcher(testScheduler) + val scope = backgroundScope + + val useCase = GetShippingRulesUseCase(project, config, project.rewards() ?: emptyList(), scope, dispatcher) + + val state = mutableListOf() + scope.launch(dispatcher) { + useCase.invoke() + useCase.shippingRulesState.toList(state) + } + advanceUntilIdle() + + val filtered = state.last().filteredRw + assertEquals(listOf(noReward, secretReward, featuredReward, regularReward), filtered) + } }