From 38672686086503c0ff47d1ff3b44ee91ea368f0d Mon Sep 17 00:00:00 2001 From: Stephanie <127455800+stechiu@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:03:53 -0800 Subject: [PATCH] Removed Venmo `fallbacktoWeb` (#1434) * Removed Venmo `fallbacktoWeb` * Addressed PR comment * Updated CHANGELOG * Removed `LinkType` and `urlSchemeURL()` * Added link type back to PayPal * Fixed `linkType` error * Removed Venmo UI tests. Updated docstrings * Updated CHANGELOG * Revert "Merge branch 'v7' of https://github.com/braintree/braintree_ios into v7-venmo-universal-link" This reverts commit 438dfc7af31d42a040bd55957f3e95ce1840f79e, reversing changes made to 1a24560d78b449a4bcde006d0f4d26cbd17cfb25. * Revert "Revert "Merge branch 'v7' of https://github.com/braintree/braintree_ios into v7-venmo-universal-link"" This reverts commit 2d0d7e015565c0c7f7fe46cc36b819794a09cc5b. * Reset v7 files * Removed duplicate LinkType file * Removed unused `return` * Reverted cocoapods version * Updated migration guide. Added `TODO` --- Braintree.xcodeproj/project.pbxproj | 8 +-- CHANGELOG.md | 1 + .../Features/VenmoViewController.swift | 7 +- .../Venmo UI Tests/Venmo_UITests.swift | 44 +----------- .../BraintreeCore/Analytics/LinkType.swift | 2 +- Sources/BraintreePayPal/BTPayPalClient.swift | 2 +- .../BTVenmoAppSwitchRedirectURL.swift | 7 -- Sources/BraintreeVenmo/BTVenmoClient.swift | 51 +++---------- Sources/BraintreeVenmo/BTVenmoRequest.swift | 8 +-- .../BTVenmoAppSwitchRedirectURL_Tests.swift | 22 ------ .../BTVenmoClient_Tests.swift | 72 ++----------------- .../BTVenmoRequest_Tests.swift | 5 -- V7_MIGRATION.md | 4 +- 13 files changed, 30 insertions(+), 203 deletions(-) diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index bc7ee97d0d..bfc0a7c5a7 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 04ECD8A02CC9CB1E000329EC /* LinkType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04ECD89F2CC9CB1A000329EC /* LinkType.swift */; }; 0917F6E42A27BDC700ACED2E /* BTVenmoLineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 096C6B2529CCDCEB00912863 /* BTVenmoLineItem.swift */; }; 09357DCB2A2FBEC10096D449 /* BTVenmoLineItem_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09357DCA2A2FBEC10096D449 /* BTVenmoLineItem_Tests.swift */; }; 1FEB89E614CB6BF0B9858EE4 /* Pods_Tests_IntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85BD589D380436A0C9D1DEC1 /* Pods_Tests_IntegrationTests.framework */; }; @@ -313,7 +314,6 @@ BED00CAE28A5419900D74AEC /* BTBinData.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED00CAD28A5419900D74AEC /* BTBinData.swift */; }; BED00CB028A579D700D74AEC /* BTClientToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED00CAF28A579D700D74AEC /* BTClientToken.swift */; }; BED00CB228A57AD400D74AEC /* BTClientTokenError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED00CB128A57AD400D74AEC /* BTClientTokenError.swift */; }; - BED3A2C62C5D74B20034D9A6 /* LinkType.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED3A2C52C5D74AC0034D9A6 /* LinkType.swift */; }; BED7493628579BAC0074C818 /* BTURLUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED7493528579BAC0074C818 /* BTURLUtils.swift */; }; BEDA91A028EDDE64007441D9 /* FakeAnalyticsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEDA919F28EDDE64007441D9 /* FakeAnalyticsService.swift */; }; BEDB820229B109EE00075AF3 /* BTApplePayAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEDB820129B109EE00075AF3 /* BTApplePayAnalytics.swift */; }; @@ -677,6 +677,7 @@ 035A59D91EA5DE97002960C8 /* BTLocalPaymentClient_UnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BTLocalPaymentClient_UnitTests.swift; sourceTree = ""; }; 039A8BD91F9E993500D607E7 /* BTAmericanExpressRewardsBalance_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTAmericanExpressRewardsBalance_Tests.swift; sourceTree = ""; }; 03F921C1200EBB200076CD80 /* BTThreeDSecurePostalAddress_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTThreeDSecurePostalAddress_Tests.swift; sourceTree = ""; }; + 04ECD89F2CC9CB1A000329EC /* LinkType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkType.swift; sourceTree = ""; }; 09357DCA2A2FBEC10096D449 /* BTVenmoLineItem_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTVenmoLineItem_Tests.swift; sourceTree = ""; }; 096C6B2529CCDCEB00912863 /* BTVenmoLineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTVenmoLineItem.swift; sourceTree = ""; }; 162174E1192D9220008DC35D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -996,7 +997,6 @@ BED00CAD28A5419900D74AEC /* BTBinData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTBinData.swift; sourceTree = ""; }; BED00CAF28A579D700D74AEC /* BTClientToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTClientToken.swift; sourceTree = ""; }; BED00CB128A57AD400D74AEC /* BTClientTokenError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTClientTokenError.swift; sourceTree = ""; }; - BED3A2C52C5D74AC0034D9A6 /* LinkType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkType.swift; sourceTree = ""; }; BED7493528579BAC0074C818 /* BTURLUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTURLUtils.swift; sourceTree = ""; }; BEDA919F28EDDE64007441D9 /* FakeAnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAnalyticsService.swift; sourceTree = ""; }; BEDB820129B109EE00075AF3 /* BTApplePayAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTApplePayAnalytics.swift; sourceTree = ""; }; @@ -1554,13 +1554,13 @@ 80F4F4D529F8A628003EACB1 /* Analytics */ = { isa = PBXGroup; children = ( + 04ECD89F2CC9CB1A000329EC /* LinkType.swift */, 808E4A152C581CD40006A737 /* AnalyticsSendable.swift */, BE549F132BF6576300B6F441 /* BTAnalyticsEventsStorage.swift */, BEE2E4E329007FF100C03FDD /* BTAnalyticsService.swift */, BEE2E4E5290080BD00C03FDD /* BTAnalyticsServiceError.swift */, BEF388C02BE52CD2000965C8 /* BTCoreAnalytics.swift */, 800E78C329E0DD5300D1B0FC /* FPTIBatchData.swift */, - BED3A2C52C5D74AC0034D9A6 /* LinkType.swift */, 457D7FC72C29CEC300EF6523 /* RepeatingTimer.swift */, ); path = Analytics; @@ -3123,6 +3123,7 @@ files = ( BE9FB82D28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift in Sources */, BED00CAE28A5419900D74AEC /* BTBinData.swift in Sources */, + 04ECD8A02CC9CB1E000329EC /* LinkType.swift in Sources */, BE549F142BF6576300B6F441 /* BTAnalyticsEventsStorage.swift in Sources */, BC17F9BE28D25054004B18CC /* BTGraphQLErrorNode.swift in Sources */, 800E78C429E0DD5300D1B0FC /* FPTIBatchData.swift in Sources */, @@ -3159,7 +3160,6 @@ BE63A3A7288F3026001936DA /* BTPostalAddress.swift in Sources */, BE2F98D028A2BCCD008EF189 /* BTConfiguration.swift in Sources */, 804DC45D2B2D08FF00F17A15 /* BTConfigurationRequest.swift in Sources */, - BED3A2C62C5D74B20034D9A6 /* LinkType.swift in Sources */, BED00CB228A57AD400D74AEC /* BTClientTokenError.swift in Sources */, BE24C67328E73E810067B11A /* BTAPIClientHTTPType.swift in Sources */, 457D7FC82C29CEC300EF6523 /* RepeatingTimer.swift in Sources */, diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b57308ef3..3fffdbca84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Remove entire PayPal Native Checkout module * BraintreeVenmo * Update `BTVenmoRequest` to make all properties accessible on the initializer only vs via the dot syntax. + * Remove `fallbacktoWeb` property from `BTVenmoRequest`. All Venmo flows will now use universal links to switch to the Venmo app or fallback to the web flow if the Venmo app is not installed * BraintreeSEPADirectDebit * Update `BTSEPADirectDebitRequest` to make all properties accessible on the initializer only vs via the dot syntax. * BraintreeLocalPayment diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index aab95cb0b7..24b6494a0c 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -6,7 +6,6 @@ class VenmoViewController: PaymentButtonBaseViewController { // swiftlint:disable:next implicitly_unwrapped_optional var venmoClient: BTVenmoClient! - let webFallbackToggle = Toggle(title: "Enable Web Fallback") let vaultToggle = Toggle(title: "Vault") override func viewDidLoad() { @@ -18,7 +17,7 @@ class VenmoViewController: PaymentButtonBaseViewController { override func createPaymentButton() -> UIView { let venmoButton = createButton(title: "Venmo", action: #selector(tappedVenmo)) - let stackView = UIStackView(arrangedSubviews: [webFallbackToggle, vaultToggle, venmoButton]) + let stackView = UIStackView(arrangedSubviews: [vaultToggle, venmoButton]) stackView.axis = .vertical stackView.spacing = 15 stackView.alignment = .fill @@ -31,12 +30,10 @@ class VenmoViewController: PaymentButtonBaseViewController { @objc func tappedVenmo() { self.progressBlock("Tapped Venmo - initiating Venmo auth") - let isWebFallbackEnabled = webFallbackToggle.isOn let isVaultingEnabled = vaultToggle.isOn let venmoRequest = BTVenmoRequest( paymentMethodUsage: .multiUse, - vault: isVaultingEnabled, - fallbackToWeb: isWebFallbackEnabled + vault: isVaultingEnabled ) Task { diff --git a/Demo/UI Tests/Venmo UI Tests/Venmo_UITests.swift b/Demo/UI Tests/Venmo UI Tests/Venmo_UITests.swift index 265e3cef39..74e5a4614b 100644 --- a/Demo/UI Tests/Venmo UI Tests/Venmo_UITests.swift +++ b/Demo/UI Tests/Venmo UI Tests/Venmo_UITests.swift @@ -4,60 +4,18 @@ class Venmo_UITests: XCTestCase { // swiftlint:disable implicitly_unwrapped_optional var demoApp: XCUIApplication! - var mockVenmo: XCUIApplication! // swiftlint:enable implicitly_unwrapped_optional override func setUp() { super.setUp() continueAfterFailure = false - mockVenmo = XCUIApplication(bundleIdentifier: "com.braintreepayments.MockVenmo") - mockVenmo.activate() - demoApp = XCUIApplication(bundleIdentifier: "com.braintreepayments.Demo") demoApp.launchArguments.append("-EnvironmentSandbox") demoApp.launchArguments.append("-ClientToken") demoApp.launchArguments.append("-Integration:VenmoViewController") demoApp.launch() } - - func testTokenizeVenmo_whenSignInSuccessfulWithPaymentContext_returnsNonce() { - waitForElementToBeHittable(demoApp.buttons["Venmo"]) - demoApp.buttons["Venmo"].tap() - - waitForElementToBeHittable(mockVenmo.buttons["SUCCESS WITH PAYMENT CONTEXT"]) - mockVenmo.buttons["SUCCESS WITH PAYMENT CONTEXT"].tap() - - XCTAssertTrue(demoApp.buttons["Got a nonce. Tap to make a transaction."].waitForExistence(timeout: 30)) - } - - func testTokenizeVenmo_whenSignInSuccessfulWithoutPaymentContext_returnsNonce() { - waitForElementToBeHittable(demoApp.buttons["Venmo"]) - demoApp.buttons["Venmo"].tap() - - waitForElementToBeHittable(mockVenmo.buttons["SUCCESS WITHOUT PAYMENT CONTEXT"]) - mockVenmo.buttons["SUCCESS WITHOUT PAYMENT CONTEXT"].tap() - - XCTAssertTrue(demoApp.buttons["Got a nonce. Tap to make a transaction."].waitForExistence(timeout: 30)) - } - func testTokenizeVenmo_whenErrorOccurs_returnsError() { - waitForElementToBeHittable(demoApp.buttons["Venmo"]) - demoApp.buttons["Venmo"].tap() - - waitForElementToBeHittable(mockVenmo.buttons["ERROR"]) - mockVenmo.buttons["ERROR"].tap() - - XCTAssertTrue(demoApp.buttons["An error occurred during the Venmo flow"].waitForExistence(timeout: 30)) - } - - func testTokenizeVenmo_whenUserCancels_returnsCancel() { - waitForElementToBeHittable(demoApp.buttons["Venmo"]) - demoApp.buttons["Venmo"].tap() - - waitForElementToBeHittable(mockVenmo.buttons["Cancel"]) - mockVenmo.buttons["Cancel"].tap() - - XCTAssertTrue(demoApp.buttons["Canceled 🔰"].waitForExistence(timeout: 30)) - } + // TODO: Add UI test } diff --git a/Sources/BraintreeCore/Analytics/LinkType.swift b/Sources/BraintreeCore/Analytics/LinkType.swift index 0fb70292ce..f494262362 100644 --- a/Sources/BraintreeCore/Analytics/LinkType.swift +++ b/Sources/BraintreeCore/Analytics/LinkType.swift @@ -1,4 +1,4 @@ -/// Used to describe the link type for analytics +/// Used to describe the type of link that directs users to a specific URL for analytics /// :nodoc: This class is exposed for internal Braintree use only. Do not use. It is not covered by Semantic Versioning and may change or be removed at any time. @_documentation(visibility: private) public enum LinkType: String { diff --git a/Sources/BraintreePayPal/BTPayPalClient.swift b/Sources/BraintreePayPal/BTPayPalClient.swift index 0362ed1597..629c542408 100644 --- a/Sources/BraintreePayPal/BTPayPalClient.swift +++ b/Sources/BraintreePayPal/BTPayPalClient.swift @@ -62,7 +62,7 @@ import BraintreeDataCollector /// Used for analytics purposes, to determine if brower-presentation event is associated with a locally cached, or remotely fetched `BTConfiguration` private var isConfigFromCache: Bool? - /// Used for sending the type of flow, universal vs deeplink to FPTI + /// Used for indicating the type of URL link, universal link or deep link, that directs users to a specific URL to FPTI private var linkType: LinkType? // MARK: - Initializer diff --git a/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift b/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift index b9d561e064..c02ad1e2a0 100644 --- a/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift +++ b/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift @@ -75,13 +75,6 @@ struct BTVenmoAppSwitchRedirectURL { return urlComponent.url } - func urlSchemeURL() -> URL? { - var components = BTVenmoAppSwitchRedirectURL.appSwitchBaseURLComponents() - components.percentEncodedQuery = BTURLUtils.queryString(from: queryParameters as NSDictionary) - - return components.url - } - // MARK: - Private Helper Methods private func constructRedirectURL(with scheme: String, result: String) -> URL? { diff --git a/Sources/BraintreeVenmo/BTVenmoClient.swift b/Sources/BraintreeVenmo/BTVenmoClient.swift index 50f677676c..873db989fe 100644 --- a/Sources/BraintreeVenmo/BTVenmoClient.swift +++ b/Sources/BraintreeVenmo/BTVenmoClient.swift @@ -67,8 +67,7 @@ import BraintreeCore @objc(tokenizeWithVenmoRequest:completion:) // swiftlint:disable:next function_body_length cyclomatic_complexity public func tokenize(_ request: BTVenmoRequest, completion: @escaping (BTVenmoAccountNonce?, Error?) -> Void) { - linkType = request.fallbackToWeb ? .universal : .deeplink - apiClient.sendAnalyticsEvent(BTVenmoAnalytics.tokenizeStarted, isVaultRequest: shouldVault, linkType: linkType) + apiClient.sendAnalyticsEvent(BTVenmoAnalytics.tokenizeStarted, isVaultRequest: shouldVault) let returnURLScheme = BTAppContextSwitcher.sharedInstance.returnURLScheme if returnURLScheme.isEmpty { @@ -100,7 +99,7 @@ import BraintreeCore } do { - _ = try self.verifyAppSwitch(with: configuration, fallbackToWeb: request.fallbackToWeb) + _ = try self.verifyAppSwitch(with: configuration) } catch { self.notifyFailure(with: error, completion: completion) return @@ -160,24 +159,15 @@ import BraintreeCore environment: configuration.venmoEnvironment ) - if request.fallbackToWeb { - guard let universalLinksURL = appSwitchURL.universalLinksURL() else { - self.notifyFailure( - with: BTVenmoError.invalidReturnURL("Universal links URL cannot be nil"), - completion: completion - ) - return - } - - self.startVenmoFlow(with: universalLinksURL, shouldVault: request.vault, completion: completion) - } else { - guard let urlSchemeURL = appSwitchURL.urlSchemeURL() else { - self.notifyFailure(with: BTVenmoError.invalidReturnURL("App switch URL cannot be nil"), completion: completion) - return - } - - self.startVenmoFlow(with: urlSchemeURL, shouldVault: request.vault, completion: completion) + guard let universalLinksURL = appSwitchURL.universalLinksURL() else { + self.notifyFailure( + with: BTVenmoError.invalidReturnURL("Universal links URL cannot be nil"), + completion: completion + ) + return } + + self.startVenmoFlow(with: universalLinksURL, shouldVault: request.vault, completion: completion) } catch { self.notifyFailure(with: error, completion: completion) return @@ -202,15 +192,6 @@ import BraintreeCore } } - /// Returns true if the proper Venmo app is installed and configured correctly, returns false otherwise. - @objc public func isVenmoAppInstalled() -> Bool { - guard let appSwitchURL = BTVenmoAppSwitchRedirectURL.baseAppSwitchURL else { - return false - } - - return application.canOpenURL(appSwitchURL) - } - /// Switches to the App Store to download the Venmo application. @objc public func openVenmoAppPageInAppStore() { application.open(appStoreURL, completionHandler: nil) @@ -291,7 +272,6 @@ import BraintreeCore apiClient.sendAnalyticsEvent( BTVenmoAnalytics.handleReturnStarted, isVaultRequest: shouldVault, - linkType: linkType, payPalContextID: payPalContextID ) guard let cleanedURL = URL(string: url.absoluteString.replacingOccurrences(of: "#", with: "?")) else { @@ -394,7 +374,6 @@ import BraintreeCore apiClient.sendAnalyticsEvent( BTVenmoAnalytics.appSwitchSucceeded, isVaultRequest: shouldVault, - linkType: linkType, payPalContextID: payPalContextID, appSwitchURL: appSwitchURL ) @@ -443,16 +422,11 @@ import BraintreeCore // MARK: - App Switch Methods - func verifyAppSwitch(with configuration: BTConfiguration, fallbackToWeb: Bool) throws -> Bool { + func verifyAppSwitch(with configuration: BTConfiguration) throws -> Bool { if !configuration.isVenmoEnabled { throw BTVenmoError.disabled } - - if !fallbackToWeb && !isVenmoAppInstalled() { - throw BTVenmoError.appNotAvailable - } - guard bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") != nil else { throw BTVenmoError.bundleDisplayNameMissing } @@ -469,7 +443,6 @@ import BraintreeCore apiClient.sendAnalyticsEvent( BTVenmoAnalytics.tokenizeSucceeded, isVaultRequest: shouldVault, - linkType: linkType, payPalContextID: payPalContextID ) completion(result, nil) @@ -480,7 +453,6 @@ import BraintreeCore BTVenmoAnalytics.tokenizeFailed, errorDescription: error.localizedDescription, isVaultRequest: shouldVault, - linkType: linkType, payPalContextID: payPalContextID ) completion(nil, error) @@ -490,7 +462,6 @@ import BraintreeCore apiClient.sendAnalyticsEvent( BTVenmoAnalytics.appSwitchCanceled, isVaultRequest: shouldVault, - linkType: linkType, payPalContextID: payPalContextID ) completion(nil, BTVenmoError.canceled) diff --git a/Sources/BraintreeVenmo/BTVenmoRequest.swift b/Sources/BraintreeVenmo/BTVenmoRequest.swift index b95daca2a7..a974cb31fc 100644 --- a/Sources/BraintreeVenmo/BTVenmoRequest.swift +++ b/Sources/BraintreeVenmo/BTVenmoRequest.swift @@ -37,7 +37,6 @@ import Foundation var shippingAmount: String? var totalAmount: String? var lineItems: [BTVenmoLineItem]? - var fallbackToWeb: Bool = false // MARK: - Initializer @@ -57,9 +56,8 @@ import Foundation /// - shippingAmount: The shipping amount for the transaction to be displayed on the paysheet. If this value is set, `totalAmount` must also be set. /// - totalAmount: The grand total amount on the transaction that should be displayed on the paysheet. /// - lineItems: The line items for this transaction. It can include up to 249 line items. If this value is set, `totalAmount` must also be set. - /// - fallbackToWeb: Used to determine if the customer should fallback to the web flow if Venmo app is not installed. Defaults to `false` @objc(initWithPaymentMethodUsage:profileID:vault:displayName:collectCustomerBillingAddress:collectCustomerShippingAddress: - isFinalAmount:subTotalAmount:discountAmount:taxAmount:shippingAmount:totalAmount:lineItems:fallbackToWeb:) + isFinalAmount:subTotalAmount:discountAmount:taxAmount:shippingAmount:totalAmount:lineItems:) public init( paymentMethodUsage: BTVenmoPaymentMethodUsage, profileID: String? = nil, @@ -73,8 +71,7 @@ import Foundation taxAmount: String? = nil, shippingAmount: String? = nil, totalAmount: String? = nil, - lineItems: [BTVenmoLineItem]? = [], - fallbackToWeb: Bool = false + lineItems: [BTVenmoLineItem]? = [] ) { self.paymentMethodUsage = paymentMethodUsage self.profileID = profileID @@ -89,6 +86,5 @@ import Foundation self.shippingAmount = shippingAmount self.totalAmount = totalAmount self.lineItems = lineItems - self.fallbackToWeb = fallbackToWeb } } diff --git a/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift b/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift index da92e9bc00..98b2cdf2ee 100644 --- a/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift +++ b/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift @@ -4,28 +4,6 @@ import XCTest class BTVenmoAppSwitchRedirectURL_Tests: XCTestCase { - func testUrlSchemeURL_whenAllValuesAreInitialized_returnsURLWithPaymentContextID() { - do { - let requestURL = try BTVenmoAppSwitchRedirectURL( - returnURLScheme: "url-scheme", - paymentContextID: "12345", - metadata: BTClientMetadata(), - forMerchantID: "merchant-id", - accessToken: "access-token", - bundleDisplayName: "display-name", - environment: "sandbox" - ) - - XCTAssertTrue(requestURL.urlSchemeURL()!.absoluteString.contains("com.venmo.touch.v2://x-callback-url/vzero/auth")) - - let components = URLComponents(string: requestURL.urlSchemeURL()!.absoluteString) - guard let queryItems = components?.queryItems else { XCTFail(); return } - XCTAssertTrue(queryItems.contains(URLQueryItem(name: "resource_id", value: "12345"))) - } catch { - XCTFail("This request URL should be constructed successfully") - } - } - func testAppSwitchURL_whenMerchantIDNil_throwsError() { do { _ = try BTVenmoAppSwitchRedirectURL( diff --git a/UnitTests/BraintreeVenmoTests/BTVenmoClient_Tests.swift b/UnitTests/BraintreeVenmoTests/BTVenmoClient_Tests.swift index e9101a4380..2d8a8183a4 100644 --- a/UnitTests/BraintreeVenmoTests/BTVenmoClient_Tests.swift +++ b/UnitTests/BraintreeVenmoTests/BTVenmoClient_Tests.swift @@ -275,7 +275,7 @@ class BTVenmoClient_Tests: XCTestCase { return } - XCTAssertEqual(urlComponents.scheme, "com.venmo.touch.v2") + XCTAssertEqual(urlComponents.scheme, "https") XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_merchant_id", value: "venmo_merchant_id"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_access_token", value: "venmo-access-token"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_environment", value: "sandbox"))) @@ -344,7 +344,7 @@ class BTVenmoClient_Tests: XCTestCase { return } - XCTAssertEqual(urlComponents.scheme, "com.venmo.touch.v2") + XCTAssertEqual(urlComponents.scheme, "https") XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_merchant_id", value: "venmo_merchant_id"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_access_token", value: "venmo-access-token"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_environment", value: "sandbox"))) @@ -584,48 +584,6 @@ class BTVenmoClient_Tests: XCTestCase { XCTAssertEqual(mockAPIClient.postedAnalyticsEvents.last!, BTVenmoAnalytics.tokenizeSucceeded) XCTAssertEqual(mockAPIClient.postedPayPalContextID, "some-resource-id") - XCTAssertEqual(mockAPIClient.postedLinkType, .deeplink) - } - - func testTokenizeVenmoAccount_fallbackToWebTrue_sendsSuccessAnalyticsEvent() { - mockAPIClient.authorization = try! BTClientToken(clientToken: TestClientTokenFactory.validClientToken) - - let venmoClient = BTVenmoClient(apiClient: mockAPIClient) - venmoClient.application = FakeApplication() - venmoClient.bundle = FakeBundle() - BTAppContextSwitcher.sharedInstance.returnURLScheme = "scheme" - - let expectation = expectation(description: "Callback invoked") - - venmoRequest.fallbackToWeb = true - - venmoClient.tokenize(venmoRequest) { venmoAccount, error in - XCTAssertNil(error) - XCTAssertEqual(venmoAccount?.username, "venmojoe") - XCTAssertEqual(venmoAccount?.nonce, "abcd-venmo-nonce") - expectation.fulfill() - } - - mockAPIClient.cannedResponseBody = BTJSON(value: [ - "venmoAccounts": [[ - "type": "VenmoAccount", - "nonce": "abcd-venmo-nonce", - "description": "VenmoAccount", - "consumed": false, - "default": true, - "details": [ - "cardType": "Discover", - "username": "venmojoe" - ] - ] as [String: Any]] - ]) - - BTVenmoClient.handleReturnURL(URL(string: "scheme://x-callback-url/vzero/auth/venmo/success?paymentMethodNonce=abcd-venmo-nonce&username=venmojoe")!) - waitForExpectations(timeout: 2) - - XCTAssertEqual(mockAPIClient.postedAnalyticsEvents.last!, BTVenmoAnalytics.tokenizeSucceeded) - XCTAssertEqual(mockAPIClient.postedPayPalContextID, "some-resource-id") - XCTAssertEqual(mockAPIClient.postedLinkType, .universal) } func testTokenizeVenmoAccount_vaultTrue_sendsFailureAnalyticsEvent() { @@ -651,7 +609,6 @@ class BTVenmoClient_Tests: XCTestCase { XCTAssertEqual(mockAPIClient.postedAnalyticsEvents.last!, BTVenmoAnalytics.tokenizeFailed) XCTAssertEqual(mockAPIClient.postedPayPalContextID, "some-resource-id") - XCTAssertEqual(mockAPIClient.postedLinkType, .deeplink) } func testTokenizeVenmoAccount_whenAppSwitchCanceled_callsBackWithCancelError() { @@ -686,7 +643,7 @@ class BTVenmoClient_Tests: XCTestCase { venmoClient.tokenize(venmoRequest) { _, _ in } XCTAssertTrue(fakeApplication.openURLWasCalled) - XCTAssertEqual(fakeApplication.lastOpenURL!.scheme, "com.venmo.touch.v2") + XCTAssertEqual(fakeApplication.lastOpenURL!.scheme, "https") XCTAssertNotNil(fakeApplication.lastOpenURL!.absoluteString.range(of: "venmo_merchant_id")); XCTAssertNotNil(fakeApplication.lastOpenURL!.absoluteString.range(of: "venmo-access-token")); } @@ -703,7 +660,7 @@ class BTVenmoClient_Tests: XCTestCase { venmoClient.tokenize(venmoRequest) { _, _ in } XCTAssertTrue(fakeApplication.openURLWasCalled) - XCTAssertEqual(fakeApplication.lastOpenURL!.scheme, "com.venmo.touch.v2") + XCTAssertEqual(fakeApplication.lastOpenURL!.scheme, "https") XCTAssertNotNil(fakeApplication.lastOpenURL!.absoluteString.range(of: "second_venmo_merchant_id")); XCTAssertNotNil(fakeApplication.lastOpenURL!.absoluteString.range(of: "venmo-access-token")); } @@ -821,27 +778,6 @@ class BTVenmoClient_Tests: XCTestCase { // MARK: - BTAppContextSwitchClient - func testIsiOSAppSwitchAvailable_whenApplicationCanOpenVenmoURL_returnsTrue() { - let venmoClient = BTVenmoClient(apiClient: mockAPIClient) - BTAppContextSwitcher.sharedInstance.returnURLScheme = "scheme" - let fakeApplication = FakeApplication() - fakeApplication.cannedCanOpenURL = false - fakeApplication.canOpenURLWhitelist.append(URL(string: "com.venmo.touch.v2://x-callback-url/path")!) - venmoClient.application = fakeApplication - - XCTAssertTrue(venmoClient.isVenmoAppInstalled()) - } - - func testIsiOSAppSwitchAvailable_whenApplicationCantOpenVenmoURL_returnsFalse() { - let venmoClient = BTVenmoClient(apiClient: mockAPIClient) - BTAppContextSwitcher.sharedInstance.returnURLScheme = "scheme" - let fakeApplication = FakeApplication() - fakeApplication.cannedCanOpenURL = false - venmoClient.application = fakeApplication - - XCTAssertFalse(venmoClient.isVenmoAppInstalled()) - } - func testCanHandleReturnURL_withValidHost_andValidPath_returnsTrue() { let host = "x-callback-url" let path = "/vzero/auth/venmo/" diff --git a/UnitTests/BraintreeVenmoTests/BTVenmoRequest_Tests.swift b/UnitTests/BraintreeVenmoTests/BTVenmoRequest_Tests.swift index 1685de690e..00f215e4bf 100644 --- a/UnitTests/BraintreeVenmoTests/BTVenmoRequest_Tests.swift +++ b/UnitTests/BraintreeVenmoTests/BTVenmoRequest_Tests.swift @@ -23,9 +23,4 @@ class BTVenmoRequest_Tests: XCTestCase { let request = BTVenmoRequest(paymentMethodUsage: .singleUse) XCTAssertEqual(request.isFinalAmount, false) } - - func testFallbackToWeb_whenNotPassed_defaultsValueAsFalse() { - let request = BTVenmoRequest(paymentMethodUsage: .singleUse) - XCTAssertEqual(request.fallbackToWeb, false) - } } diff --git a/V7_MIGRATION.md b/V7_MIGRATION.md index 8d0c509ae7..5e57c5e12f 100644 --- a/V7_MIGRATION.md +++ b/V7_MIGRATION.md @@ -19,8 +19,10 @@ v7 bumps to a minimum deployment target of iOS 16+. ## Venmo All properties within `BTVenmoRequest` can only be accessed on the initializer vs via the dot syntax. +Remove the `fallbackToWeb` boolean parameter from `BTVenmoRequest`. If a Buyer has the Venmo app installed and taps on "Pay with Venmo", they will automatically be switched to the Venmo app. If the Venmo app isn't installed, the Buyer will fallback to their default web brower to checkout. + ``` -let venmoRequest = BTVenmoRequest(paymentMethodUsage: .multiUse, vault: true, fallbackToWeb: true) +let venmoRequest = BTVenmoRequest(paymentMethodUsage: .multiUse, vault: true) ``` ## SEPA Direct Debit