Skip to content

Commit

Permalink
use isAvailable property on the reward model to render rewards
Browse files Browse the repository at this point in the history
* updates tests as well
  • Loading branch information
scottkicks committed Apr 2, 2024
1 parent 6fcf7ee commit 44a9373
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 39 deletions.
4 changes: 2 additions & 2 deletions KsApi/models/templates/RewardTemplates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension Reward {
startsAt: nil,
title: "My Reward",
localPickup: nil,
isAvailable: nil
isAvailable: true
)

public static let noReward = Reward(
Expand Down Expand Up @@ -59,7 +59,7 @@ extension Reward {
startsAt: nil,
title: nil,
localPickup: nil,
isAvailable: nil
isAvailable: true
)

public static let otherReward = Reward(
Expand Down
26 changes: 1 addition & 25 deletions Library/SharedFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -279,30 +279,6 @@ public func isNativeRiskMessagingControlEnabled() -> Bool {
return true
}

public func rewardIsAvailable(project: Project, reward: Reward) -> Bool {
let isLimited = reward.isLimitedQuantity
let isTimebased = reward.isLimitedTime

guard isLimited || isTimebased else { return true }

let remainingQty = rewardLimitRemainingForBacker(project: project, reward: reward)
let isRemaining = remainingQty == nil || (remainingQty ?? 0) > 0

let now = AppEnvironment.current.dateType.init().timeIntervalSince1970
let endsAt = reward.endsAt.coalesceWith(now)
let timeLimitNotReached = endsAt > now

// Limited availability is valid if the reward is limited and remaining > 0 OR this reward is not limited.
let limitedAvailabilityValid = (isLimited && isRemaining) || !isLimited

// Timebased availability is valid if the reward is timebased and the time limit has not been reached
// OR the reward is not timebased.
let timebasedAvailabilityValid = (isTimebased && timeLimitNotReached) || !isTimebased

// Both types of availability must be valid in order for this reward to be considered available.
return limitedAvailabilityValid && timebasedAvailabilityValid
}

public func rewardLimitRemainingForBacker(project: Project, reward: Reward) -> Int? {
guard let remaining = reward.remaining else {
return nil
Expand Down Expand Up @@ -377,7 +353,7 @@ public func rewardsCarouselCanNavigateToReward(_ reward: Reward, in project: Pro
guard !currentUserIsCreator(of: project) else { return false }

let isBacking = userIsBacking(reward: reward, inProject: project)
let isAvailableForNewBacker = rewardIsAvailable(project: project, reward: reward) && !isBacking
let isAvailableForNewBacker = reward.isAvailable == true && !isBacking
let isAvailableForExistingBackerToEdit = (isBacking && reward.hasAddOns)

if featurePostCampaignPledgeEnabled(), project.isInPostCampaignPledgingPhase {
Expand Down
2 changes: 2 additions & 0 deletions Library/SharedFunctionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ final class SharedFunctionsTests: TestCase {
|> Reward.lens.limit .~ 5
|> Reward.lens.remaining .~ 5
|> Reward.lens.endsAt .~ (MockDate().timeIntervalSince1970 + 60)
|> Reward.lens.isAvailable .~ true

let project = Project.template
|> Project.lens.rewardData.rewards .~ [reward]
Expand Down Expand Up @@ -231,6 +232,7 @@ final class SharedFunctionsTests: TestCase {
|> Reward.lens.remaining .~ 5
|> Reward.lens.endsAt .~ (MockDate().timeIntervalSince1970 + 60)
|> Reward.lens.hasAddOns .~ true
|> Reward.lens.isAvailable .~ true

let project = Project.template
|> Project.lens.rewardData.rewards .~ [reward]
Expand Down
2 changes: 1 addition & 1 deletion Library/ViewModels/RewardCardContainerViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private func pledgeButtonTitle(project: Project, reward: Reward) -> String? {

let projectBackingState = RewardCellProjectBackingStateType.state(with: project)
let isBackingThisReward = userIsBacking(reward: reward, inProject: project)
let isRewardAvailable = rewardIsAvailable(project: project, reward: reward)
let isRewardAvailable = reward.isAvailable == true

switch (projectBackingState, isBackingThisReward, isRewardAvailable) {
case (.backedError, false, true):
Expand Down
6 changes: 5 additions & 1 deletion Library/ViewModels/RewardCardContainerViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,27 @@ final class RewardCardContainerViewModelTests: TestCase {

let availableHasAddOns = Reward.postcards
|> Reward.lens.hasAddOns .~ true
|> Reward.lens.isAvailable .~ true
let availableLimitedReward = Reward.postcards
|> Reward.lens.limit .~ 100
|> Reward.lens.remaining .~ 25
|> Reward.lens.endsAt .~ nil
|> Reward.lens.isAvailable .~ true
let availableTimebasedReward = Reward.postcards
|> Reward.lens.limit .~ nil
|> Reward.lens.remaining .~ nil
|> Reward.lens.endsAt .~ (MockDate().timeIntervalSince1970 + 60.0 * 60.0 * 24.0)
|> Reward.lens.isAvailable .~ true
let availableLimitedTimebasedReward = Reward.postcards
|> Reward.lens.limit .~ 100
|> Reward.lens.remaining .~ 25
|> Reward.lens.endsAt .~ (MockDate().timeIntervalSince1970 + 60.0 * 60.0 * 24.0)
|> Reward.lens.isAvailable .~ true
let availableNonLimitedReward = Reward.postcards
|> Reward.lens.limit .~ nil
|> Reward.lens.remaining .~ nil
|> Reward.lens.endsAt .~ nil

|> Reward.lens.isAvailable .~ true
let unavailableLimitedReward = Reward.postcards
|> Reward.lens.limit .~ 100
|> Reward.lens.remaining .~ 0
Expand Down
2 changes: 2 additions & 0 deletions Library/ViewModels/RewardCardViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ final class RewardCardViewModelTests: TestCase {
let reward = Reward.template
|> Reward.lens.remaining .~ nil
|> Reward.lens.minimum .~ 1_000
|> Reward.lens.isAvailable .~ true

self.vm.inputs.configure(with: (project, reward, .pledge))

Expand All @@ -532,6 +533,7 @@ final class RewardCardViewModelTests: TestCase {
let reward = Reward.template
|> Reward.lens.remaining .~ 10
|> Reward.lens.minimum .~ 1_000.0
|> Reward.lens.isAvailable .~ true

self.vm.inputs.configure(with: (project, reward, .pledge))

Expand Down
7 changes: 4 additions & 3 deletions Library/ViewModels/RewardsCollectionViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public final class RewardsCollectionViewModel: RewardsCollectionViewModelType,

self.reloadDataWithValues = Signal.combineLatest(project, rewards)
.map { project, rewards in
rewards.filter { reward in isStartDateBeforeToday(for: reward) }
rewards
.filter { reward in isStartDateBeforeToday(for: reward) }
.map { reward in (project, reward, .pledge) }
}

Expand Down Expand Up @@ -389,7 +390,7 @@ private func backingAndShippingTotal(for project: Project, and reward: Reward) -
}

private func allowableSortedProjectRewards(from project: Project) -> [Reward] {
let availableRewards = project.rewards.filter { rewardIsAvailable(project: project, reward: $0) }
let unAvailableRewards = project.rewards.filter { !rewardIsAvailable(project: project, reward: $0) }
let availableRewards = project.rewards.filter { $0.isAvailable == true || $0.isNoReward }
let unAvailableRewards = project.rewards.filter { $0.isAvailable == false }
return availableRewards + unAvailableRewards
}
33 changes: 26 additions & 7 deletions Library/ViewModels/RewardsCollectionViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ final class RewardsCollectionViewModelTests: TestCase {
|> Reward.lens.localPickup .~ .brooklyn
|> Reward.lens.shipping.preference .~ .local
|> Reward.lens.shipping.enabled .~ false
|> Reward.lens.isAvailable .~ true

return updatedReward
}
Expand Down Expand Up @@ -131,6 +132,7 @@ final class RewardsCollectionViewModelTests: TestCase {
|> Reward.lens.localPickup .~ .brooklyn
|> Reward.lens.shipping.preference .~ .local
|> Reward.lens.shipping.enabled .~ false
|> Reward.lens.isAvailable .~ true

return updatedReward
}
Expand Down Expand Up @@ -172,6 +174,7 @@ final class RewardsCollectionViewModelTests: TestCase {
|> Reward.lens.localPickup .~ .brooklyn
|> Reward.lens.shipping.preference .~ .local
|> Reward.lens.shipping.enabled .~ false
|> Reward.lens.isAvailable .~ true

return updatedReward
}
Expand Down Expand Up @@ -208,6 +211,7 @@ final class RewardsCollectionViewModelTests: TestCase {

let reward = rewards.first!
|> Reward.lens.hasAddOns .~ true
|> Reward.lens.isAvailable .~ true

rewards[0] = reward

Expand Down Expand Up @@ -310,6 +314,7 @@ final class RewardsCollectionViewModelTests: TestCase {
let firstReward = Project.cosmicSurgery.rewards[0]
let secondReward = Project.cosmicSurgery.rewards[1]
|> Reward.lens.remaining .~ 5
|> Reward.lens.isAvailable .~ true

let project = Project.cosmicSurgery
|> Project.lens.rewardData.rewards .~ [firstReward, secondReward]
Expand Down Expand Up @@ -360,6 +365,7 @@ final class RewardsCollectionViewModelTests: TestCase {
withEnvironment(config: .template) {
let reward = Reward.template
|> Reward.lens.hasAddOns .~ true
|> Reward.lens.isAvailable .~ true

let project = Project.cosmicSurgery
|> Project.lens.rewardData.rewards .~ [reward]
Expand Down Expand Up @@ -404,6 +410,7 @@ final class RewardsCollectionViewModelTests: TestCase {
|> Reward.lens.limit .~ 5
|> Reward.lens.remaining .~ 0
|> Reward.lens.endsAt .~ (MockDate().timeIntervalSince1970 - 1)
|> Reward.lens.isAvailable .~ true

let project = Project.cosmicSurgery
|> Project.lens.rewardData.rewards .~ [reward]
Expand Down Expand Up @@ -445,9 +452,11 @@ final class RewardsCollectionViewModelTests: TestCase {
withEnvironment(config: .template) {
let reward = Reward.template
|> Reward.lens.hasAddOns .~ true
|> Reward.lens.isAvailable .~ true

let backedReward = Reward.template
|> Reward.lens.id .~ 55
|> Reward.lens.isAvailable .~ true

let project = Project.cosmicSurgery
|> Project.lens.rewardData.rewards .~ [reward, backedReward]
Expand Down Expand Up @@ -505,10 +514,11 @@ final class RewardsCollectionViewModelTests: TestCase {
withEnvironment(config: .template) {
let reward = Reward.template
|> Reward.lens.hasAddOns .~ false
|> Reward.lens.isAvailable .~ true

let backedReward = Reward.template
|> Reward.lens.id .~ 55

|> Reward.lens.isAvailable .~ true
let project = Project.cosmicSurgery
|> Project.lens.rewardData.rewards .~ [reward, backedReward]
|> Project.lens.personalization.backing .~ (
Expand Down Expand Up @@ -799,16 +809,21 @@ final class RewardsCollectionViewModelTests: TestCase {
func testBackedRewardIndexPath() {
let backedReward = Reward.template
|> Reward.lens.id .~ 5
|> Reward.lens.isAvailable .~ true

let rewards = [
.template
|> Reward.lens.id .~ 1,
|> Reward.lens.id .~ 1
|> Reward.lens.isAvailable .~ true,
.template
|> Reward.lens.id .~ 2,
|> Reward.lens.id .~ 2
|> Reward.lens.isAvailable .~ true,
.template
|> Reward.lens.id .~ 3,
|> Reward.lens.id .~ 3
|> Reward.lens.isAvailable .~ true,
.template
|> Reward.lens.id .~ 4,
|> Reward.lens.id .~ 4
|> Reward.lens.isAvailable .~ true,
backedReward
]

Expand Down Expand Up @@ -884,7 +899,8 @@ final class RewardsCollectionViewModelTests: TestCase {
.template
|> Reward.lens.id .~ 1,
.template
|> Reward.lens.id .~ 2,
|> Reward.lens.id .~ 2
|> Reward.lens.isAvailable .~ true,
.template
|> Reward.lens.id .~ 3,
.template
Expand All @@ -906,6 +922,7 @@ final class RewardsCollectionViewModelTests: TestCase {
func testTrackingRewardClicked_ProjectBackingNil() {
let rewardTwo = Reward.template
|> Reward.lens.id .~ 2
|> Reward.lens.isAvailable .~ true

let rewards = [
.template
Expand Down Expand Up @@ -940,6 +957,7 @@ final class RewardsCollectionViewModelTests: TestCase {
func testTrackingRewardClicked_ProjectBackingNotNil() {
let rewardTwo = Reward.template
|> Reward.lens.id .~ 2
|> Reward.lens.isAvailable .~ true
let backing = Backing.template
|> Backing.lens.amount .~ 20.00
|> Backing.lens.bonusAmount .~ 100.00
Expand Down Expand Up @@ -982,7 +1000,8 @@ final class RewardsCollectionViewModelTests: TestCase {
.template
|> Reward.lens.id .~ 1,
.template
|> Reward.lens.id .~ 2,
|> Reward.lens.id .~ 2
|> Reward.lens.isAvailable .~ true,
.template
|> Reward.lens.id .~ 3,
.template
Expand Down

0 comments on commit 44a9373

Please sign in to comment.