Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Cleanup App Switch #1381

Merged
merged 9 commits into from
Aug 9, 2024
4 changes: 4 additions & 0 deletions Braintree.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
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 */; };
Expand Down Expand Up @@ -1066,6 +1067,7 @@
BED00CAD28A5419900D74AEC /* BTBinData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTBinData.swift; sourceTree = "<group>"; };
BED00CAF28A579D700D74AEC /* BTClientToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTClientToken.swift; sourceTree = "<group>"; };
BED00CB128A57AD400D74AEC /* BTClientTokenError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTClientTokenError.swift; sourceTree = "<group>"; };
BED3A2C52C5D74AC0034D9A6 /* LinkType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkType.swift; sourceTree = "<group>"; };
BED7493528579BAC0074C818 /* BTURLUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTURLUtils.swift; sourceTree = "<group>"; };
BEDA919F28EDDE64007441D9 /* FakeAnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAnalyticsService.swift; sourceTree = "<group>"; };
BEDB820129B109EE00075AF3 /* BTApplePayAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTApplePayAnalytics.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1599,6 +1601,7 @@
BEE2E4E5290080BD00C03FDD /* BTAnalyticsServiceError.swift */,
BEF388C02BE52CD2000965C8 /* BTCoreAnalytics.swift */,
800E78C329E0DD5300D1B0FC /* FPTIBatchData.swift */,
BED3A2C52C5D74AC0034D9A6 /* LinkType.swift */,
457D7FC72C29CEC300EF6523 /* RepeatingTimer.swift */,
);
path = Analytics;
Expand Down Expand Up @@ -3312,6 +3315,7 @@
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 */,
Expand Down
7 changes: 7 additions & 0 deletions Sources/BraintreeCore/Analytics/LinkType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// Used to describe the link type 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 {
jaxdesmarais marked this conversation as resolved.
Show resolved Hide resolved
case universal
case deeplink
}
4 changes: 2 additions & 2 deletions Sources/BraintreeCore/BTAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ import Foundation
errorDescription: String? = nil,
isConfigFromCache: Bool? = nil,
isVaultRequest: Bool? = nil,
linkType: String? = nil,
linkType: LinkType? = nil,
payPalContextID: String? = nil
) {
analyticsService.sendAnalyticsEvent(
Expand All @@ -320,7 +320,7 @@ import Foundation
eventName: eventName,
isConfigFromCache: isConfigFromCache,
isVaultRequest: isVaultRequest,
linkType: linkType,
linkType: linkType?.rawValue,
payPalContextID: payPalContextID
)
)
Expand Down
4 changes: 2 additions & 2 deletions Sources/BraintreePayPal/BTPayPalApprovalURLParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ struct BTPayPalApprovalURLParser {
return nil
}

init?(body: BTJSON, linkType: String?) {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

if linkType == "universal", let payPalAppRedirectURL = body["agreementSetup"]["paypalAppApprovalUrl"].asURL() {
init?(body: BTJSON) {
if let payPalAppRedirectURL = body["agreementSetup"]["paypalAppApprovalUrl"].asURL() {
Copy link
Contributor

@KunJeongPark KunJeongPark Aug 7, 2024

Choose a reason for hiding this comment

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

For EditFI work, we are not using payPalAppApprovalUrl because app switching is not in scope yet for that work stream. But if the gateway returns this value as well as approvalURL in generate_edit_fi_url response, using this Parser we would get payPalAppRedirectURL instead of the approvalURL. For right now for the draft on a branch (editFI-gateway-endpoints), I just forced the web Url fetching by passing in linkType as nil (or could have passed in "deepLink" ). I guess I can use something else to get the webURL.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is the gateway returning a payPalAppApprovalUrl for the edit FI endpoints? Because they should not be and we should raise that if so. This was only ever added because when we were working off of stage we always got a payPalAppApprovalUrl regardless of eligibility and was just never cleaned up. See old convo here: #1271 (comment). I tested the experience in this PR and no longer see this behavior with the app uninstalled.

Copy link
Contributor

@KunJeongPark KunJeongPark Aug 7, 2024

Choose a reason for hiding this comment

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

The Gateway specs on Confluence show: Response - agreementSetup {tokenId, paypalAppApprovalUrl, approvalUrl}
as response for edit FI url endpoint. Maybe the doc is not updated or maybe it's supposed to return just approval url. I will check with you and Gateway team tomorrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, then removing the link type will not impact that flow and we should not need to pass in a link type, it will always fail this first check for a payPalAppApprovalUrl and move on to the next block which includes the web URL.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've posted the question on the collaboration channel so we can clarify with them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fwiw we also have to opt in to the app switch flow for the Gateway to return that property, so I would expect it only exists to future proof this feature. We need to pass them everything here to say the merchant opted into app switch which we won't be doing for Edit FI currently:

if enablePayPalAppSwitch, let universalLink {
let appSwitchParameters: [String: Any] = [
"launch_paypal_app": enablePayPalAppSwitch,
"os_version": UIDevice.current.systemVersion,
"os_type": UIDevice.current.systemName,
"merchant_app_return_url": universalLink.absoluteString
]
return baseParameters.merging(appSwitchParameters) { $1 }
}

The gateway only returns a payPalAppApprovalUrl if those properties are passed AND the merchant is eligible on the gateway side.

Copy link
Contributor

@KunJeongPark KunJeongPark Aug 8, 2024

Choose a reason for hiding this comment

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

Great! thank you for the clarification. I do want to make sure that this is true for editFI endpoint as well since there are no details given in the specs. I want to clarify that payPalAppApprovalUrl will return a nil value or not exist at all for generate_edit_fi_url endpoint if these parameters are not passed. And these parameters are not mentioned for generate_edi_fi_url endpoint.

What you are saying makes sense though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For sure! Will be good to clarify but shouldn't block this PR. If the gateway does something weird we can make the necessary updates in the Edit FI branch.

redirectType = .payPalApp(url: payPalAppRedirectURL)
url = payPalAppRedirectURL
} else if let approvalURL = body["paymentResource"]["redirectUrl"].asURL() ??
Expand Down
2 changes: 1 addition & 1 deletion Sources/BraintreePayPal/BTPayPalCheckoutRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ import BraintreeCore

/// :nodoc: Exposed publicly for use by PayPal Native Checkout module. This method is not covered by semantic versioning.
@_documentation(visibility: private)
public override func parameters(with configuration: BTConfiguration, universalLink: URL? = nil) -> [String: Any] {
public override func parameters(with configuration: BTConfiguration, universalLink: URL? = nil, isPayPalAppInstalled: Bool = false) -> [String: Any] {
var baseParameters = super.parameters(with: configuration)
var checkoutParameters: [String: Any] = [
"intent": intent.stringValue,
Expand Down
20 changes: 8 additions & 12 deletions Sources/BraintreePayPal/BTPayPalClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ import BraintreeDataCollector
/// This allows us to set and return a completion in our methods that otherwise cannot require a completion.
var appSwitchCompletion: (BTPayPalAccountNonce?, Error?) -> Void = { _, _ in }

/// Exposed for testing to check if the PayPal app is installed
var payPalAppInstalled: Bool = false

/// True if `tokenize()` was called with a Vault request object type
var isVaultRequest: Bool = false

Expand All @@ -65,7 +62,7 @@ import BraintreeDataCollector
private var isConfigFromCache: Bool?

/// Used for sending the type of flow, universal vs deeplink to FPTI
private var linkType: String? = nil
private var linkType: LinkType? = nil

// MARK: - Initializer

Expand Down Expand Up @@ -311,8 +308,7 @@ import BraintreeDataCollector
request: BTPayPalRequest,
completion: @escaping (BTPayPalAccountNonce?, Error?) -> Void
) {
payPalAppInstalled = application.isPayPalAppInstalled()
linkType = (request as? BTPayPalVaultRequest)?.enablePayPalAppSwitch == true && payPalAppInstalled ? "universal" : "deeplink"
linkType = (request as? BTPayPalVaultRequest)?.enablePayPalAppSwitch == true ? .universal : .deeplink

apiClient.sendAnalyticsEvent(BTPayPalAnalytics.tokenizeStarted, isVaultRequest: isVaultRequest, linkType: linkType)
apiClient.fetchOrReturnRemoteConfiguration { configuration, error in
Expand All @@ -333,14 +329,14 @@ import BraintreeDataCollector
return
}

if !self.payPalAppInstalled {
(request as? BTPayPalVaultRequest)?.enablePayPalAppSwitch = false
}

self.payPalRequest = request
self.apiClient.post(
request.hermesPath,
parameters: request.parameters(with: configuration, universalLink: self.universalLink)
parameters: request.parameters(
with: configuration,
universalLink: self.universalLink,
isPayPalAppInstalled: self.application.isPayPalAppInstalled()
)
) { body, response, error in
if let error = error as? NSError {
guard let jsonResponseBody = error.userInfo[BTCoreConstants.jsonResponseBodyKey] as? BTJSON else {
Expand All @@ -355,7 +351,7 @@ import BraintreeDataCollector
return
}

guard let body, let approvalURL = BTPayPalApprovalURLParser(body: body, linkType: self.linkType) else {
guard let body, let approvalURL = BTPayPalApprovalURLParser(body: body) else {
self.notifyFailure(with: BTPayPalError.invalidURL("Missing approval URL in gateway response."), completion: completion)
return
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/BraintreePayPal/BTPayPalRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ import BraintreeCore

/// :nodoc: Exposed publicly for use by PayPal Native Checkout module. This method is not covered by semantic versioning.
@_documentation(visibility: private)
public func parameters(with configuration: BTConfiguration, universalLink: URL? = nil) -> [String: Any] {
public func parameters(with configuration: BTConfiguration, universalLink: URL? = nil, isPayPalAppInstalled: Bool = false) -> [String: Any] {
var experienceProfile: [String: Any] = [:]

experienceProfile["no_shipping"] = !isShippingAddressRequired
Expand Down
4 changes: 2 additions & 2 deletions Sources/BraintreePayPal/BTPayPalReturnURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct BTPayPalReturnURL {
url.scheme == "https" && (url.path.contains("cancel") || url.path.contains("success"))
}

static func isValidURLAction(url: URL, linkType: String?) -> Bool {
static func isValidURLAction(url: URL, linkType: LinkType?) -> Bool {
guard let host = url.host, let scheme = url.scheme, !scheme.isEmpty else {
return false
}
Expand All @@ -59,7 +59,7 @@ struct BTPayPalReturnURL {

/// If we are using the deeplink/ASWeb based PayPal flow we want to check that the host and path matches
/// the static callbackURLHostAndPath. For the universal link flow we do not care about this check.
if hostAndPath != BTPayPalRequest.callbackURLHostAndPath && linkType == "deeplink" {
if hostAndPath != BTPayPalRequest.callbackURLHostAndPath && linkType == .deeplink {
return false
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/BraintreePayPal/BTPayPalVaultBaseRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import BraintreeCore

/// :nodoc: Exposed publicly for use by PayPal Native Checkout module. This method is not covered by semantic versioning.
@_documentation(visibility: private)
public override func parameters(with configuration: BTConfiguration, universalLink: URL? = nil) -> [String: Any] {
public override func parameters(with configuration: BTConfiguration, universalLink: URL? = nil, isPayPalAppInstalled: Bool = false) -> [String: Any] {
let baseParameters = super.parameters(with: configuration)
var vaultParameters: [String: Any] = ["offer_paypal_credit": offerCredit]

Expand Down
5 changes: 3 additions & 2 deletions Sources/BraintreePayPal/BTPayPalVaultRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,21 @@ import BraintreeCore
super.init(offerCredit: offerCredit)
}

public override func parameters(with configuration: BTConfiguration, universalLink: URL? = nil) -> [String: Any] {
public override func parameters(with configuration: BTConfiguration, universalLink: URL? = nil, isPayPalAppInstalled: Bool = false) -> [String: Any] {
var baseParameters = super.parameters(with: configuration)

if let userAuthenticationEmail {
baseParameters["payer_email"] = userAuthenticationEmail
}

if enablePayPalAppSwitch, let universalLink {
if let universalLink, enablePayPalAppSwitch, isPayPalAppInstalled {
let appSwitchParameters: [String: Any] = [
"launch_paypal_app": enablePayPalAppSwitch,
"os_version": UIDevice.current.systemVersion,
"os_type": UIDevice.current.systemName,
"merchant_app_return_url": universalLink.absoluteString
]

return baseParameters.merging(appSwitchParameters) { $1 }
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/BraintreeVenmo/BTVenmoClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import BraintreeCore
private var payPalContextID: String? = nil

/// Used for sending the type of flow, universal vs deeplink to FPTI
private var linkType: String? = nil
private var linkType: LinkType? = nil

// MARK: - Initializer

Expand All @@ -64,7 +64,7 @@ import BraintreeCore
/// If the user cancels out of the flow, the error code will be `.canceled`.
@objc(tokenizeWithVenmoRequest:completion:)
public func tokenize(_ request: BTVenmoRequest, completion: @escaping (BTVenmoAccountNonce?, Error?) -> Void) {
linkType = request.fallbackToWeb ? "universal" : "deeplink"
linkType = request.fallbackToWeb ? .universal : .deeplink
apiClient.sendAnalyticsEvent(BTVenmoAnalytics.tokenizeStarted, isVaultRequest: shouldVault, linkType: linkType)
let returnURLScheme = BTAppContextSwitcher.sharedInstance.returnURLScheme

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class FPTIBatchData_Tests: XCTestCase {
eventName: "fake-event-1",
isConfigFromCache: false,
isVaultRequest: false,
linkType: "universal",
linkType: LinkType.universal.rawValue,
payPalContextID: "fake-order-id",
requestStartTime: 456,
startTime: 999888777666
Expand Down
9 changes: 4 additions & 5 deletions UnitTests/BraintreePayPalTests/BTPayPalClient_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ class BTPayPalClient_Tests: XCTestCase {
func testTokenize_whenPayPalAppApprovalURLContainsPayPalContextID_sendsPayPalContextIDAndLinkTypeInAnalytics() {
let fakeApplication = FakeApplication()
payPalClient.application = fakeApplication
payPalClient.payPalAppInstalled = true
payPalClient.webAuthenticationSession = MockWebAuthenticationSession()

let vaultRequest = BTPayPalVaultRequest(
Expand All @@ -252,7 +251,7 @@ class BTPayPalClient_Tests: XCTestCase {
payPalClient.handleReturnURL(returnURL)

XCTAssertEqual(mockAPIClient.postedPayPalContextID, "BA-Random-Value")
XCTAssertEqual(mockAPIClient.postedLinkType, "universal")
XCTAssertEqual(mockAPIClient.postedLinkType, .universal)
XCTAssertNotNil(payPalClient.clientMetadataID)
}

Expand Down Expand Up @@ -282,7 +281,7 @@ class BTPayPalClient_Tests: XCTestCase {
payPalClient.tokenize(request) { _, _ in }

XCTAssertEqual(mockAPIClient.postedPayPalContextID, "BA-Random-Value")
XCTAssertEqual(mockAPIClient.postedLinkType, "deeplink")
XCTAssertEqual(mockAPIClient.postedLinkType, .deeplink)
XCTAssertTrue(mockAPIClient.postedAnalyticsEvents.contains("paypal:tokenize:handle-return:started"))
}

Expand All @@ -301,7 +300,7 @@ class BTPayPalClient_Tests: XCTestCase {
payPalClient.tokenize(request) { _, _ in }

XCTAssertEqual(mockAPIClient.postedPayPalContextID, "A_FAKE_BA_TOKEN")
XCTAssertEqual(mockAPIClient.postedLinkType, "deeplink")
XCTAssertEqual(mockAPIClient.postedLinkType, .deeplink)
XCTAssertTrue(mockAPIClient.postedAnalyticsEvents.contains("paypal:tokenize:handle-return:started"))
}

Expand Down Expand Up @@ -931,8 +930,8 @@ class BTPayPalClient_Tests: XCTestCase {

func testIsiOSAppSwitchAvailable_whenApplicationCanOpenPayPalInAppURL_returnsTrueAndSendsAnalytics() {
let fakeApplication = FakeApplication()
fakeApplication.cannedCanOpenURL = true
payPalClient.application = fakeApplication
payPalClient.payPalAppInstalled = true

let vaultRequest = BTPayPalVaultRequest(
userAuthenticationEmail: "[email protected]",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import XCTest
@testable import BraintreeCore
@testable import BraintreePayPal
@testable import BraintreeTestShared

class BTPayPalVaultRequest_Tests: XCTestCase {

Expand Down Expand Up @@ -76,7 +77,7 @@ class BTPayPalVaultRequest_Tests: XCTestCase {
enablePayPalAppSwitch: true
)

let parameters = request.parameters(with: configuration, universalLink: URL(string: "some-url")!)
let parameters = request.parameters(with: configuration, universalLink: URL(string: "some-url")!, isPayPalAppInstalled: true)

XCTAssertEqual(parameters["launch_paypal_app"] as? Bool, true)
XCTAssertTrue((parameters["os_version"] as! String).matches("\\d+\\.\\d+"))
Expand Down
4 changes: 2 additions & 2 deletions UnitTests/BraintreeTestShared/MockAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class MockAPIClient: BTAPIClient {

public var postedAnalyticsEvents : [String] = []
public var postedPayPalContextID: String? = nil
public var postedLinkType: String? = nil
public var postedLinkType: LinkType? = nil
public var postedIsVaultRequest = false

@objc public var cannedConfigurationResponseBody : BTJSON? = nil
Expand Down Expand Up @@ -94,7 +94,7 @@ public class MockAPIClient: BTAPIClient {
errorDescription: String? = nil,
isConfigFromCache: Bool? = nil,
isVaultRequest: Bool? = nil,
linkType: String? = nil,
linkType: LinkType? = nil,
payPalContextID: String? = nil
) {
postedPayPalContextID = payPalContextID
Expand Down
6 changes: 3 additions & 3 deletions UnitTests/BraintreeVenmoTests/BTVenmoClient_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ class BTVenmoClient_Tests: XCTestCase {

XCTAssertEqual(mockAPIClient.postedAnalyticsEvents.last!, BTVenmoAnalytics.tokenizeSucceeded)
XCTAssertEqual(mockAPIClient.postedPayPalContextID, "some-resource-id")
XCTAssertEqual(mockAPIClient.postedLinkType, "deeplink")
XCTAssertEqual(mockAPIClient.postedLinkType, .deeplink)
}

func testTokenizeVenmoAccount_fallbackToWebTrue_sendsSuccessAnalyticsEvent() {
Expand Down Expand Up @@ -625,7 +625,7 @@ class BTVenmoClient_Tests: XCTestCase {

XCTAssertEqual(mockAPIClient.postedAnalyticsEvents.last!, BTVenmoAnalytics.tokenizeSucceeded)
XCTAssertEqual(mockAPIClient.postedPayPalContextID, "some-resource-id")
XCTAssertEqual(mockAPIClient.postedLinkType, "universal")
XCTAssertEqual(mockAPIClient.postedLinkType, .universal)
}

func testTokenizeVenmoAccount_vaultTrue_sendsFailureAnalyticsEvent() {
Expand All @@ -651,7 +651,7 @@ class BTVenmoClient_Tests: XCTestCase {

XCTAssertEqual(mockAPIClient.postedAnalyticsEvents.last!, BTVenmoAnalytics.tokenizeFailed)
XCTAssertEqual(mockAPIClient.postedPayPalContextID, "some-resource-id")
XCTAssertEqual(mockAPIClient.postedLinkType, "deeplink")
XCTAssertEqual(mockAPIClient.postedLinkType, .deeplink)
}

func testTokenizeVenmoAccount_whenAppSwitchCanceled_callsBackWithCancelError() {
Expand Down
Loading