forked from hideokamoto/stripe-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable iDEAL for SetupIntents and PaymentIntents+setup_future_usage (s…
…tripe#2786) * Move Elements helper methods out of test into dedicated file * Refactor makeContactInformation in preparation for usage w/ other PMs. * PR feedback * Undo moving string to different module * PR feedback * Update LPMConfirmFlowTest * Enable iDEAL for SetupIntents and PaymentIntents+setup_future_usage * lint * fix up, call out debug helper * Use makeiDEAL for vanilla PIs too * Only give section a title if theres more than one element to keep consistent with other forms
- Loading branch information
1 parent
ba5f49c
commit 05cda47
Showing
6 changed files
with
109 additions
and
29 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,10 +1,14 @@ | ||
## x.y.z 2023-xx-yy | ||
### PaymentSheet | ||
* [Added] Enable SEPA Debit and iDEAL for SetupIntents and PaymentIntents with setup_future_usage. Note: PaymentSheet doesn't display saved SEPA Debit payment methods yet. | ||
|
||
### Identity | ||
* [ADDED][2452](https://github.com/stripe/stripe-ios/pull/2452) Supports [phone verification](https://stripe.com/docs/identity/phone) in Identity mobile SDK. | ||
|
||
|
||
## 23.11.2 2023-07-24 | ||
### PaymentSheet | ||
* [Fixed] Update [email protected] to 8bit color depth (Thanks @jszumski) | ||
* [Added] Enable SEPA Debit for SetupIntents and PaymentIntents with setup_future_usage. Note: PaymentSheet doesn't display saved SEPA Debit payment methods yet. | ||
|
||
### CustomerSheet | ||
* [Fixed] Ability to removing payment method immediately after adding it. | ||
|
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
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// | ||
// PaymentSheet+LPMTests.swift | ||
// PaymentSheet+LPMConfirmFlowTests.swift | ||
// StripeiOSTests | ||
// | ||
// Created by Yuki Tokuhiro on 7/18/23. | ||
|
@@ -14,14 +14,13 @@ import XCTest | |
@testable@_spi(STP) import StripePaymentSheet | ||
@testable@_spi(STP) import StripeUICore | ||
|
||
final class PaymentSheet_LPMTests: XCTestCase { | ||
/// These tests exercise 9 different confirm flows based on the combination of: | ||
/// - The Stripe Intent: PaymentIntent or PaymentIntent+SFU or SetupIntent | ||
/// - The confirmation type: "Normal" intent-first client-side confirmation or "Deferred" client-side confirmation or "Deferred" server-side confirmation | ||
/// They can also test the presence/absence of particular fields for a payment method form e.g. the SEPA test asserts that there's a mandate element. | ||
/// 👀 See `testIdealConfirmFlows` for an example with comments. | ||
final class PaymentSheet_LPM_ConfirmFlowTests: XCTestCase { | ||
let apiClient = STPAPIClient(publishableKey: STPTestingDefaultPublishableKey) | ||
lazy var paymentHandler: STPPaymentHandler = { | ||
return STPPaymentHandler( | ||
apiClient: apiClient, | ||
formSpecPaymentHandler: PaymentSheetFormSpecPaymentHandler() | ||
) | ||
}() | ||
lazy var configuration: PaymentSheet.Configuration = { | ||
var config = PaymentSheet.Configuration() | ||
config.apiClient = apiClient | ||
|
@@ -47,10 +46,35 @@ final class PaymentSheet_LPMTests: XCTestCase { | |
XCTAssertNotNil(form.getMandateElement()) | ||
} | ||
} | ||
|
||
/// 👋 👨🏫 Look at this test to understand how to write your own tests in this file | ||
@MainActor | ||
func testiDEALConfirmFlows() async throws { | ||
try await _testConfirm(intentKinds: [.paymentIntent], currency: "EUR", paymentMethodType: .dynamic("ideal")) { form in | ||
// Fill out your payment method form in here. | ||
// Note: Each required field you fill out implicitly tests that the field exists; if the field doesn't exist, the test will fail because the form is incomplete. | ||
form.getTextFieldElement("Full name")?.setText("Foo") | ||
XCTAssertNotNil(form.getDropdownFieldElement("iDEAL Bank")) | ||
// You can also explicitly assert for the existence/absence of certain elements. | ||
// e.g. iDEAL shouldn't show a mandate or email field for a vanilla payment | ||
XCTAssertNil(form.getMandateElement()) | ||
XCTAssertNil(form.getTextFieldElement("Email")) | ||
// Tip: To help you debug, print out `form.getAllUnwrappedSubElements()` | ||
} | ||
|
||
// If your payment method shows different fields depending on the kind of intent, you can call `_testConfirm` multiple times with different intents. | ||
// e.g. iDEAL should show an email field and mandate for PI+SFU and SIs, so we test those separately here: | ||
try await _testConfirm(intentKinds: [.paymentIntentWithSetupFutureUsage, .setupIntent], currency: "EUR", paymentMethodType: .dynamic("ideal")) { form in | ||
form.getTextFieldElement("Full name")?.setText("Foo") | ||
form.getTextFieldElement("Email")?.setText("[email protected]") | ||
XCTAssertNotNil(form.getDropdownFieldElement("iDEAL Bank")) | ||
XCTAssertNotNil(form.getMandateElement()) | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Helper methods | ||
extension PaymentSheet_LPMTests { | ||
extension PaymentSheet_LPM_ConfirmFlowTests { | ||
enum IntentKind: CaseIterable { | ||
case paymentIntent | ||
case paymentIntentWithSetupFutureUsage | ||
|
@@ -63,7 +87,7 @@ extension PaymentSheet_LPMTests { | |
} | ||
} | ||
|
||
/// A helper method that tests three confirmation flows successfully complete: | ||
/// A helper method that creates a form for the given `paymentMethodType` and tests three confirmation flows successfully complete: | ||
/// 1. normal" client-side confirmation | ||
/// 2. deferred client-side confirmation | ||
/// 3. deferred server-side | ||
|
@@ -78,7 +102,8 @@ extension PaymentSheet_LPMTests { | |
} | ||
let paymentMethodString = PaymentSheet.PaymentMethodType.string(from: paymentMethodType)! | ||
let intents: [(String, Intent)] | ||
let mandateDataParamsForServerSideConfirmation: [String: Any] = [ // We require merchants to set this themselves for server-side confirmation | ||
let paramsForServerSideConfirmation: [String: Any] = [ // We require merchants to set some extra parameters themselves for server-side confirmation | ||
"return_url": "foo://bar", | ||
"mandate_data": [ | ||
"customer_acceptance": [ | ||
"type": "online", | ||
|
@@ -99,7 +124,7 @@ extension PaymentSheet_LPMTests { | |
return try await STPTestingAPIClient.shared.fetchPaymentIntent(types: [paymentMethodString]) | ||
} | ||
let deferredSSC = PaymentSheet.IntentConfiguration(mode: .payment(amount: 1099, currency: currency)) { paymentMethod, _ in | ||
return try await STPTestingAPIClient.shared.fetchPaymentIntent(types: [paymentMethodString], paymentMethodID: paymentMethod.stripeId, confirm: true, otherParams: mandateDataParamsForServerSideConfirmation) | ||
return try await STPTestingAPIClient.shared.fetchPaymentIntent(types: [paymentMethodString], paymentMethodID: paymentMethod.stripeId, confirm: true, otherParams: paramsForServerSideConfirmation) | ||
} | ||
intents = [ | ||
("PaymentIntent", .paymentIntent(paymentIntent)), | ||
|
@@ -117,7 +142,7 @@ extension PaymentSheet_LPMTests { | |
let deferredSSC = PaymentSheet.IntentConfiguration(mode: .payment(amount: 1099, currency: currency, setupFutureUsage: .offSession)) { paymentMethod, _ in | ||
let otherParams = [ | ||
"setup_future_usage": "off_session", | ||
].merging(mandateDataParamsForServerSideConfirmation) { _, b in b } | ||
].merging(paramsForServerSideConfirmation) { _, b in b } | ||
return try await STPTestingAPIClient.shared.fetchPaymentIntent(types: [paymentMethodString], paymentMethodID: paymentMethod.stripeId, confirm: true, otherParams: otherParams) | ||
} | ||
intents = [ | ||
|
@@ -134,7 +159,7 @@ extension PaymentSheet_LPMTests { | |
return try await STPTestingAPIClient.shared.fetchSetupIntent(types: [paymentMethodString]) | ||
} | ||
let deferredSSC = PaymentSheet.IntentConfiguration(mode: .setup(setupFutureUsage: .offSession)) { paymentMethod, _ in | ||
return try await STPTestingAPIClient.shared.fetchSetupIntent(types: [paymentMethodString], paymentMethodID: paymentMethod.stripeId, confirm: true, otherParams: mandateDataParamsForServerSideConfirmation) | ||
return try await STPTestingAPIClient.shared.fetchSetupIntent(types: [paymentMethodString], paymentMethodID: paymentMethod.stripeId, confirm: true, otherParams: paramsForServerSideConfirmation) | ||
} | ||
intents = [ | ||
("SetupIntent", .setupIntent(setupIntent)), | ||
|
@@ -159,10 +184,13 @@ extension PaymentSheet_LPMTests { | |
return | ||
} | ||
let e = expectation(description: "Confirm") | ||
let paymentHandler = STPPaymentHandler(apiClient: apiClient, formSpecPaymentHandler: PaymentSheetFormSpecPaymentHandler()) | ||
var redirectShimCalled = false | ||
paymentHandler._redirectShim = { _, _, _ in | ||
// This gets called instead of the PaymentSheet.confirm callback if the Intent is successfully confirmed and requires next actions. | ||
print("✅ \(description): Successfully confirmed the intent. Its status is now requires_action.") | ||
e.fulfill() | ||
print("✅ \(description): Successfully confirmed the intent and saw a redirect attempt.") | ||
paymentHandler._handleWillForegroundNotification() | ||
redirectShimCalled = true | ||
} | ||
// Confirm the intent with the form details | ||
PaymentSheet.confirm( | ||
|
@@ -177,7 +205,7 @@ extension PaymentSheet_LPMTests { | |
case .failed(error: let error): | ||
XCTFail("❌ \(description): PaymentSheet.confirm failed - \(error)") | ||
case .canceled: | ||
XCTFail("❌ \(description): PaymentSheet.confirm canceled!") | ||
XCTAssertTrue(redirectShimCalled, "❌ \(description): PaymentSheet.confirm canceled") | ||
case .completed: | ||
print("✅ \(description): PaymentSheet.confirm completed") | ||
} | ||
|
@@ -187,7 +215,7 @@ extension PaymentSheet_LPMTests { | |
} | ||
} | ||
|
||
extension PaymentSheet_LPMTests: STPAuthenticationContext { | ||
extension PaymentSheet_LPM_ConfirmFlowTests: STPAuthenticationContext { | ||
func authenticationPresentingViewController() -> UIViewController { | ||
return UIViewController() | ||
} | ||
|
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
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
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