Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[MBL-1328] Pledge Button Active/Inactive States #2019

Merged
merged 5 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Library/ViewModels/PostCampaignCheckoutViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class PostCampaignCheckoutViewModel: PostCampaignCheckoutViewModelType,
.skipNil()

let context = initialData.map(\.context)
let project = initialData.map(\.project)
let checkoutId = initialData.map(\.checkoutId)
let baseReward = initialData.map(\.rewards).map(\.first)

Expand All @@ -109,14 +110,23 @@ public class PostCampaignCheckoutViewModel: PostCampaignCheckoutViewModelType,
.map { _ in AppEnvironment.current.currentUser }
.map(isNotNil)

let shouldEnablePledgeButton = self.creditCardSelectedProperty.signal.skipNil().mapConst(true)

let pledgeButtonEnabled = Signal.merge(
self.viewDidLoadProperty.signal.mapConst(false),
shouldEnablePledgeButton
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Is it possible for the credit card information to load before viewDidLoad? Or is the credit card server request itself triggered by viewDidLoad?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes its tied to viewDidLoad so it's not possible πŸ‘

)
.skipRepeats()

self.configurePledgeViewCTAContainerView = Signal.combineLatest(
isLoggedIn,
pledgeButtonEnabled,
context
)
.map { isLoggedIn, context in
.map { isLoggedIn, pledgeButtonEnabled, context in
PledgeViewCTAContainerViewData(
isLoggedIn: isLoggedIn,
isEnabled: true, // Pledge button never needs to be disabled on checkout page.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well that's a convenient comment πŸ˜†

isEnabled: pledgeButtonEnabled,
context: context,
willRetryPaymentMethod: false // Only retry in the `fixPaymentMethod` context.
)
Expand Down
59 changes: 59 additions & 0 deletions Library/ViewModels/PostCampaignCheckoutViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@ final class PostCampaignCheckoutViewModelTests: TestCase {
fileprivate let processingViewIsHidden = TestObserver<Bool, Never>()
fileprivate let validateCheckoutSuccess = TestObserver<PaymentSourceValidation, Never>()

private let configurePledgeViewCTAContainerViewIsLoggedIn = TestObserver<Bool, Never>()
private let configurePledgeViewCTAContainerViewIsEnabled = TestObserver<Bool, Never>()
private let configurePledgeViewCTAContainerViewContext = TestObserver<PledgeViewContext, Never>()

override func setUp() {
super.setUp()
self.vm.goToApplePayPaymentAuthorization.observe(self.goToApplePayPaymentAuthorization.observer)
self.vm.checkoutComplete.observe(self.checkoutComplete.observer)
self.vm.processingViewIsHidden.observe(self.processingViewIsHidden.observer)
self.vm.validateCheckoutSuccess.observe(self.validateCheckoutSuccess.observer)

self.vm.outputs.configurePledgeViewCTAContainerView.map { $0.0 }
.observe(self.configurePledgeViewCTAContainerViewIsLoggedIn.observer)
self.vm.outputs.configurePledgeViewCTAContainerView.map { $0.1 }
.observe(self.configurePledgeViewCTAContainerViewIsEnabled.observer)
self.vm.outputs.configurePledgeViewCTAContainerView.map { $0.2 }
.observe(self.configurePledgeViewCTAContainerViewContext.observer)
}

func testApplePayAuthorization_noReward_isCorrect() {
Expand Down Expand Up @@ -383,8 +394,14 @@ final class PostCampaignCheckoutViewModelTests: TestCase {
self.vm.viewDidLoad()

let paymentSource = PaymentSourceSelected.paymentIntentClientSecret("123")

self.vm.inputs
.creditCardSelected(source: paymentSource, paymentMethodId: "123", isNewPaymentMethod: true)

self.configurePledgeViewCTAContainerViewIsLoggedIn.assertValues([false, false])
self.configurePledgeViewCTAContainerViewIsEnabled.assertValues([false, true])
self.configurePledgeViewCTAContainerViewContext.assertValues([.latePledge, .latePledge])

self.vm.inputs.submitButtonTapped()

self.processingViewIsHidden.assertLastValue(false)
Expand Down Expand Up @@ -429,6 +446,11 @@ final class PostCampaignCheckoutViewModelTests: TestCase {
let paymentSource = PaymentSourceSelected.paymentIntentClientSecret("123")
self.vm.inputs
.creditCardSelected(source: paymentSource, paymentMethodId: "123", isNewPaymentMethod: true)

self.configurePledgeViewCTAContainerViewIsLoggedIn.assertValues([false, false])
self.configurePledgeViewCTAContainerViewIsEnabled.assertValues([false, true])
self.configurePledgeViewCTAContainerViewContext.assertValues([.latePledge, .latePledge])

self.vm.inputs.submitButtonTapped()

self.processingViewIsHidden.assertLastValue(false)
Expand Down Expand Up @@ -469,6 +491,11 @@ final class PostCampaignCheckoutViewModelTests: TestCase {
let paymentSource = PaymentSourceSelected.paymentIntentClientSecret("123")
self.vm.inputs
.creditCardSelected(source: paymentSource, paymentMethodId: "123", isNewPaymentMethod: true)

self.configurePledgeViewCTAContainerViewIsLoggedIn.assertValues([false, false])
self.configurePledgeViewCTAContainerViewIsEnabled.assertValues([false, true])
self.configurePledgeViewCTAContainerViewContext.assertValues([.latePledge, .latePledge])

self.vm.inputs.submitButtonTapped()

self.processingViewIsHidden.assertLastValue(false)
Expand All @@ -483,4 +510,36 @@ final class PostCampaignCheckoutViewModelTests: TestCase {
self.processingViewIsHidden.assertLastValue(true)
}
}

func testPledgeViewCTA_LoggedIn_State() {
let mockService = MockService(serverConfig: ServerConfig.staging)

withEnvironment(apiService: mockService, currentUser: .template) {
let project = Project.cosmicSurgery
let reward = Reward.noReward |> Reward.lens.minimum .~ 5

let data = PostCampaignCheckoutData(
project: project,
rewards: [reward],
selectedQuantities: [:],
bonusAmount: 0,
total: 5,
shipping: nil,
refTag: nil,
context: .latePledge,
checkoutId: "0"
)

self.vm.inputs.configure(with: data)
self.vm.inputs.viewDidLoad()

let paymentSource = PaymentSourceSelected.paymentIntentClientSecret("123")
self.vm.inputs
.creditCardSelected(source: paymentSource, paymentMethodId: "123", isNewPaymentMethod: true)

self.configurePledgeViewCTAContainerViewIsLoggedIn.assertValues([true, true])
self.configurePledgeViewCTAContainerViewIsEnabled.assertValues([false, true])
self.configurePledgeViewCTAContainerViewContext.assertValues([.latePledge, .latePledge])
}
}
}