From e8e4d1158d88ae682bb809f902efb5a4f01a8723 Mon Sep 17 00:00:00 2001 From: ageddam Date: Wed, 12 Feb 2025 15:49:23 -0600 Subject: [PATCH] address pr feedback --- CHANGELOG.md | 9 ++- .../BTPayPalClient_Tests.swift | 69 ++++++++++++++++++- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08927304d..17c27b962 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Braintree iOS SDK Release Notes +## unreleased +* BraintreePayPal + * Add PayPal App Switch checkout Flow (BETA) + * Add `BTPayPalCheckoutRequest(userAuthenticationEmail:enablePayPalAppSwitch:amount:intent:userAction:offerPayLater:currencyCode:requestBillingAgreement:)` + * **Note:** This feature is currently in beta and may change or be removed in future releases. + ## 6.28.0 (2025-02-05) * BraintreeVenmo * Allow universal links to be set without a return URL scheme (fixes #1505) @@ -32,9 +38,6 @@ ## 6.25.0 (2024-12-11) * BraintreePayPal * Add `BTPayPalRequest.userPhoneNumber` optional property - * Add PayPal App Switch checkout Flow (BETA) - * Add `BTPayPalCheckoutRequest(userAuthenticationEmail:enablePayPalAppSwitch:amount:intent:userAction: offerPayLater:currencyCode:requestBillingAgreement:)` - * **Note:** This feature is currently in beta and may change or be removed in future releases. * Send `url` in `event_params` for App Switch events to PayPal's analytics service (FPTI) * BraintreeVenmo * Send `url` in `event_params` for App Switch events to PayPal's analytics service (FPTI) diff --git a/UnitTests/BraintreePayPalTests/BTPayPalClient_Tests.swift b/UnitTests/BraintreePayPalTests/BTPayPalClient_Tests.swift index 44cb6d4b0..3dd180264 100644 --- a/UnitTests/BraintreePayPalTests/BTPayPalClient_Tests.swift +++ b/UnitTests/BraintreePayPalTests/BTPayPalClient_Tests.swift @@ -745,7 +745,7 @@ class BTPayPalClient_Tests: XCTestCase { XCTAssertNil(BTPayPalClient.payPalClient) } - // MARK: - App Switch - tokenize + // MARK: - App Switch - Tokenize func testTokenizeVaultAccount_whenPayPalAppApprovalURLPresent_attemptsAppSwitchWithParameters() async { let fakeApplication = FakeApplication() @@ -858,6 +858,73 @@ class BTPayPalClient_Tests: XCTestCase { waitForExpectations(timeout: 1) } + + func testTokenizeCheckoutAccount_whenPayPalAppApprovalURLPresent_attemptsAppSwitchWithParameters() async { + let fakeApplication = FakeApplication() + payPalClient.application = fakeApplication + + mockAPIClient.cannedResponseBody = BTJSON(value: [ + "paymentResource": [ + "redirectUrl": "https://www.some-url.com/some-path?token=value1", + "launchPayPalApp": true + ] + ]) + + let checkoutRequest = BTPayPalCheckoutRequest( + userAuthenticationEmail: "fake-pp@gmail.com", + enablePayPalAppSwitch: true, + amount: "10.00" + ) + payPalClient.tokenize(checkoutRequest) { _, _ in } + + XCTAssertTrue(fakeApplication.openURLWasCalled) + + let urlComponents = URLComponents(url: fakeApplication.lastOpenURL!, resolvingAgainstBaseURL: true) + XCTAssertEqual(urlComponents?.host, "www.some-url.com") + XCTAssertEqual(urlComponents?.path, "/some-path") + + XCTAssertEqual(urlComponents?.queryItems?[0].name, "token") + XCTAssertEqual(urlComponents?.queryItems?[0].value, "value1") + XCTAssertEqual(urlComponents?.queryItems?[1].name, "source") + XCTAssertEqual(urlComponents?.queryItems?[1].value, "braintree_sdk") + XCTAssertEqual(urlComponents?.queryItems?[2].name, "switch_initiated_time") + if let urlTimestamp = urlComponents?.queryItems?[2].value { + XCTAssertNotNil(urlTimestamp) + } else { + XCTFail("Expected integer value for query param `switch_initiated_time`") + } + } + + func testTokenizeCheckoutAccount_whenPayPalAppApprovalURLMissingECToken_returnsError() { + let fakeApplication = FakeApplication() + payPalClient.application = fakeApplication + + mockAPIClient.cannedResponseBody = BTJSON(value: [ + "paymentResource": [ + "redirectUrl": "https://www.some-url.com/some-path", + "launchPayPalApp": true + ] + ]) + + let checkoutRequest = BTPayPalCheckoutRequest( + userAuthenticationEmail: "fake-pp@gmail.com", + enablePayPalAppSwitch: true, + amount: "10.00" + ) + + let expectation = expectation(description: "completion block called") + payPalClient.tokenize(checkoutRequest) { nonce, error in + XCTAssertNil(nonce) + + guard let error = error as NSError? else { XCTFail(); return } + XCTAssertEqual(error.code, 14) + XCTAssertEqual(error.localizedDescription, "Missing EC Token for PayPal App Switch.") + XCTAssertEqual(error.domain, "com.braintreepayments.BTPayPalErrorDomain") + expectation.fulfill() + } + + waitForExpectations(timeout: 1) + } func testHandleReturn_whenURLIsUnknown_returnsError() { let request = BTPayPalVaultRequest(