From 28e36d28b91204b4ea8530e4ae5dbaaf7f050c49 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Thu, 14 Sep 2023 08:00:13 -0500 Subject: [PATCH 01/14] extract type from nonce --- Sources/BraintreeCore/BTPaymentMethodNonceParser.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift b/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift index 5f52134092..03e0074921 100644 --- a/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift +++ b/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift @@ -60,7 +60,7 @@ import Foundation if json?["nonce"].isString != false { return BTPaymentMethodNonce( nonce: json?["nonce"].asString() ?? "", - type: "Unknown", + type: json?["type"].asString() ?? "Unknown", isDefault: json?["default"].isTrue ?? false ) } From 93199959ef5de7d8bcd03a6a24ed0d6570e8d5a6 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Thu, 14 Sep 2023 08:00:45 -0500 Subject: [PATCH 02/14] add unit test case to ensure we get the correct type from nonce in fetchPaymentMethodNonces --- UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift b/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift index adaa7fdab3..8d30598c59 100644 --- a/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift +++ b/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift @@ -248,9 +248,11 @@ class BTAPIClient_Tests: XCTestCase { let firstNonce = paymentMethodNonces[0]; XCTAssertEqual(firstNonce.nonce, "fake-nonce1") + XCTAssertEqual(firstNonce.type, "CreditCard") let secondNonce = paymentMethodNonces[1] XCTAssertEqual(secondNonce.nonce, "fake-nonce2") + XCTAssertEqual(secondNonce.type, "PayPalAccount") expectation.fulfill() } From a9a4057ca149425b941759413d1ab134e6d5a746 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Thu, 14 Sep 2023 08:02:25 -0500 Subject: [PATCH 03/14] add CHANGELOG entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 577440f2de..759ebfa750 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Braintree iOS SDK Release Notes +## unreleased +* BraintreeCore + * Fix bug where `type` was always returned as `Unknown` in `fetchPaymentMethodNonces` (fixes #1099) + ## 6.6.0 (2023-08-22) * BraintreePayPalNativeCheckout * Update PayPalCheckout from 1.0.0 to 1.1.0. From c821e2e32d724f4cac09db5408b0836de9adf199 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Thu, 14 Sep 2023 16:24:33 -0500 Subject: [PATCH 04/14] WIP - add card type handling --- .../BTPaymentMethodNonceParser.swift | 48 +++++++++++++++++-- .../BTPaymentMethodNonceParser_Tests.swift | 25 ++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift b/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift index 03e0074921..02174671cd 100644 --- a/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift +++ b/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift @@ -53,18 +53,60 @@ import Foundation return nil } - if let completionHandler = completionHandler { + if let completionHandler { return completionHandler(json) } - if json?["nonce"].isString != false { + if json?["nonce"].isString == false { + return nil + } + + if let cardType = json?["details"]["cardType"].asString() { + return BTPaymentMethodNonce( + nonce: json?["nonce"].asString() ?? "", + type: self.cardType(from: cardType), + isDefault: json?["default"].isTrue ?? false + ) + } else { return BTPaymentMethodNonce( nonce: json?["nonce"].asString() ?? "", type: json?["type"].asString() ?? "Unknown", isDefault: json?["default"].isTrue ?? false ) } + } + + private func cardType(from cardType: String) -> String { + let cardType = cardType.lowercased() + + if cardType == "american express" { + return "AMEX" + } else if cardType == "diners club" { + return "DinersClub" + } else if cardType == "unionpay" { + return "UnionPay" + } else if cardType == "discover" { + return "Discover" + } else if cardType == "mastercard" { + return "MasterCard" + } else if cardType == "jcb" { + return "JCB" + } else if cardType == "hiper" { + return "Hiper" + } else if cardType == "hipercard" { + return "Hipercard" + } else if cardType == "laser" { + return "Laser" + } else if cardType == "solo" { + return "Solo" + } else if cardType == "switch" { + return "Switch" + } else if cardType == "uk maestro" { + return "UKMaestro" + } else if cardType == "visa" { + return "Visa" + } - return nil + return "Unknown" } } diff --git a/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift b/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift index 741ea7471b..79542b1621 100644 --- a/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift +++ b/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift @@ -67,4 +67,29 @@ class BTPaymentMethodNonceParser_Tests: XCTestCase { XCTAssertEqual(unknownNonce.type, "Unknown") XCTAssertTrue(unknownNonce.isDefault) } + + func testSharedParser_whenTypeIsCreditCard_returnsCorrectCardNonce() { + let sharedParser = BTPaymentMethodNonceParser.shared + + let creditCardJSON = BTJSON(value: [ + "consumed": false, + "description": "ending in 31", + "details": [ + "cardType": "American Express", + "lastTwo": "31", + ], + "isLocked": false, + "nonce": "0099b1d0-7a1c-44c3-b1e4-297082290bb9", + "securityQuestions": ["cvv"], + "threeDSecureInfo": NSNull(), + "type": "CreditCard", + "default": true + ]) + + let cardNonce = sharedParser.parseJSON(creditCardJSON, withParsingBlockForType:"CreditCard")! + + XCTAssertEqual(cardNonce.nonce, "0099b1d0-7a1c-44c3-b1e4-297082290bb9") + XCTAssertEqual(cardNonce.type, "AMEX") + XCTAssertTrue(cardNonce.isDefault) + } } From a086353df4f90a97a1fb523555b10747052a1b42 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 18 Sep 2023 09:01:16 -0500 Subject: [PATCH 05/14] add parser tests --- Braintree.xcodeproj/project.pbxproj | 14 ++++++++- ...mentMethodNonceParser_ApplePay_Tests.swift | 24 +++++++++++++++ ...TPaymentMethodNonceParser_Card_Tests.swift | 30 +++++++++++++++++++ .../BTPaymentMethodNonceParser_Tests.swift | 25 ---------------- ...PaymentMethodNonceParser_Venmo_Tests.swift | 26 ++++++++++++++++ 5 files changed, 93 insertions(+), 26 deletions(-) create mode 100644 UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift create mode 100644 UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift create mode 100644 UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index 781021fc4d..d9c5defb13 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -246,6 +246,9 @@ BE9EC0982899CF040022EC63 /* BTAPIPinnedCertificates.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9EC0972899CF040022EC63 /* BTAPIPinnedCertificates.swift */; }; BE9FB82B2898324C00D6FE2F /* BTPaymentMethodNonce.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9FB82A2898324C00D6FE2F /* BTPaymentMethodNonce.swift */; }; BE9FB82D28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9FB82C28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift */; }; + BEA062E02AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA062DF2AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift */; }; + BEA062E22AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA062E12AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift */; }; + BEA062E52AB4933C0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA062E32AB4930D0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift */; }; BEB9BF532A26872B00A3673E /* BTWebAuthenticationSessionClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEB9BF522A26872B00A3673E /* BTWebAuthenticationSessionClient.swift */; }; BEBC222728D25BB400D83186 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80DBE69423A931A600373230 /* Helpers.swift */; }; BEBC6E4B29258FD4004E25A0 /* BraintreeCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570B93AC285397520041BAFE /* BraintreeCore.framework */; }; @@ -861,6 +864,9 @@ BE9EC0972899CF040022EC63 /* BTAPIPinnedCertificates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTAPIPinnedCertificates.swift; sourceTree = ""; }; BE9FB82A2898324C00D6FE2F /* BTPaymentMethodNonce.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonce.swift; sourceTree = ""; }; BE9FB82C28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser.swift; sourceTree = ""; }; + BEA062DF2AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_Venmo_Tests.swift; sourceTree = ""; }; + BEA062E12AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_Card_Tests.swift; sourceTree = ""; }; + BEA062E32AB4930D0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_ApplePay_Tests.swift; sourceTree = ""; }; BEB9BF522A26872B00A3673E /* BTWebAuthenticationSessionClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTWebAuthenticationSessionClient.swift; sourceTree = ""; }; BEBC6E5D2927CF59004E25A0 /* Braintree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Braintree.h; sourceTree = ""; }; BEBC6F252937A510004E25A0 /* BTClientMetadata_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTClientMetadata_Tests.swift; sourceTree = ""; }; @@ -1591,6 +1597,7 @@ BEDB820329B10ADA00075AF3 /* BTApplePayAnalytics_Tests.swift */, 800FC543257FDC5100DEE132 /* BTApplePayCardNonce_Tests.swift */, A95229CA24FD9E41006F7D25 /* BTConfiguration+ApplePay_Tests.swift */, + BEA062E32AB4930D0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift */, A948D6E024FAC6C000F4F178 /* Info.plist */, ); path = BraintreeApplePayTests; @@ -1600,13 +1607,14 @@ isa = PBXGroup; children = ( A9589DD924FEA45C00AF4FF7 /* BTConfiguration+Venmo_Tests.swift */, + BEA062DF2AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift */, 4228D80C2624D8C9001D2564 /* BTVenmoAccountNonce_Tests.swift */, 3B1C529529D637F400B68A58 /* BTVenmoAnalytics_Tests.swift */, 428F48E32624C9B700EC8DB4 /* BTVenmoAppSwitchRedirectURL_Tests.swift */, 4245D668256C255F00F1A413 /* BTVenmoAppSwitchReturnURL_Tests.swift */, A71F7DE61B6180A3005DA1B0 /* BTVenmoClient_Tests.swift */, - 4228D8682624E5C3001D2564 /* BTVenmoRequest_Tests.swift */, 09357DCA2A2FBEC10096D449 /* BTVenmoLineItem_Tests.swift */, + 4228D8682624E5C3001D2564 /* BTVenmoRequest_Tests.swift */, A948D6F424FAC8F900F4F178 /* Info.plist */, ); path = BraintreeVenmoTests; @@ -1620,6 +1628,7 @@ 3B14BFDE29B647AF0047426A /* BTCardAnalytics_Tests.swift */, A75147E01B4217A00005BBBA /* BTCardClient_Tests.swift */, A7A094F51B8276E500D732CC /* BTCardNonce_Tests.swift */, + BEA062E12AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift */, 0301A42E22E2286C008A26BD /* BTThreeDSecureInfo_Tests.swift */, A95C410C24FAEF2100045045 /* Info.plist */, ); @@ -2964,6 +2973,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + BEA062E52AB4933C0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift in Sources */, A95229CB24FD9E41006F7D25 /* BTConfiguration+ApplePay_Tests.swift in Sources */, A948D6E724FAC71A00F4F178 /* BTApplePay_Tests.swift in Sources */, 800FC544257FDC5100DEE132 /* BTApplePayCardNonce_Tests.swift in Sources */, @@ -2975,12 +2985,14 @@ buildActionMask = 2147483647; files = ( A9589DDA24FEA45C00AF4FF7 /* BTConfiguration+Venmo_Tests.swift in Sources */, + BEA062E02AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift in Sources */, 09357DCB2A2FBEC10096D449 /* BTVenmoLineItem_Tests.swift in Sources */, 3B1C529729D638D400B68A58 /* BTVenmoAnalytics_Tests.swift in Sources */, 4228D8692624E5C3001D2564 /* BTVenmoRequest_Tests.swift in Sources */, 428F48E42624C9B700EC8DB4 /* BTVenmoAppSwitchRedirectURL_Tests.swift in Sources */, 4245D669256C255F00F1A413 /* BTVenmoAppSwitchReturnURL_Tests.swift in Sources */, A948D6FD24FAC93100F4F178 /* BTVenmoClient_Tests.swift in Sources */, + BEA062E22AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift in Sources */, 4228D80D2624D8C9001D2564 /* BTVenmoAccountNonce_Tests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift b/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift new file mode 100644 index 0000000000..d69f4e5ee2 --- /dev/null +++ b/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift @@ -0,0 +1,24 @@ +import XCTest +@testable import BraintreeCore +@testable import BraintreeApplePay + +class BTPaymentMethodNonceParser_ApplePay_Tests: XCTestCase { + func testSharedParser_whenTypeIsApplePayCard_returnsApplePayCardNonce() { + let sharedParser = BTPaymentMethodNonceParser.shared + let applePayCard = BTJSON(value: [ + "consumed": false, + "details": [ + "cardType": "American Express" + ], + "isLocked": false, + "nonce": "a-nonce", + "securityQuestions": [] as [Any], + "type": "ApplePayCard", + ] as [String: Any]) + + let applePayCardNonce = sharedParser.parseJSON(applePayCard, withParsingBlockForType: "ApplePayCard") as? BTApplePayCardNonce + + XCTAssertEqual(applePayCardNonce?.nonce, "a-nonce") + XCTAssertEqual(applePayCardNonce?.type, "American Express") + } +} diff --git a/UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift b/UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift new file mode 100644 index 0000000000..99122df1b2 --- /dev/null +++ b/UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift @@ -0,0 +1,30 @@ +import XCTest +@testable import BraintreeCore +@testable import BraintreeCard + +class BTPaymentMethodNonceParser_Card_Tests: XCTestCase { + func testSharedParser_whenTypeIsCreditCard_returnsCorrectCardNonce() { + let sharedParser = BTPaymentMethodNonceParser.shared + + let creditCardJSON = BTJSON(value: [ + "consumed": false, + "description": "ending in 31", + "details": [ + "cardType": "American Express", + "lastTwo": "31", + ], + "isLocked": false, + "nonce": "0099b1d0-7a1c-44c3-b1e4-297082290bb9", + "securityQuestions": ["cvv"], + "threeDSecureInfo": NSNull(), + "type": "CreditCard", + "default": true + ] as [String: Any]) + + let cardNonce = sharedParser.parseJSON(creditCardJSON, withParsingBlockForType:"CreditCard")! + + XCTAssertEqual(cardNonce.nonce, "0099b1d0-7a1c-44c3-b1e4-297082290bb9") + XCTAssertEqual(cardNonce.type, "AMEX") + XCTAssertTrue(cardNonce.isDefault) + } +} diff --git a/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift b/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift index 79542b1621..741ea7471b 100644 --- a/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift +++ b/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift @@ -67,29 +67,4 @@ class BTPaymentMethodNonceParser_Tests: XCTestCase { XCTAssertEqual(unknownNonce.type, "Unknown") XCTAssertTrue(unknownNonce.isDefault) } - - func testSharedParser_whenTypeIsCreditCard_returnsCorrectCardNonce() { - let sharedParser = BTPaymentMethodNonceParser.shared - - let creditCardJSON = BTJSON(value: [ - "consumed": false, - "description": "ending in 31", - "details": [ - "cardType": "American Express", - "lastTwo": "31", - ], - "isLocked": false, - "nonce": "0099b1d0-7a1c-44c3-b1e4-297082290bb9", - "securityQuestions": ["cvv"], - "threeDSecureInfo": NSNull(), - "type": "CreditCard", - "default": true - ]) - - let cardNonce = sharedParser.parseJSON(creditCardJSON, withParsingBlockForType:"CreditCard")! - - XCTAssertEqual(cardNonce.nonce, "0099b1d0-7a1c-44c3-b1e4-297082290bb9") - XCTAssertEqual(cardNonce.type, "AMEX") - XCTAssertTrue(cardNonce.isDefault) - } } diff --git a/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift b/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift new file mode 100644 index 0000000000..add0a1a663 --- /dev/null +++ b/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift @@ -0,0 +1,26 @@ +import XCTest +@testable import BraintreeCore +@testable import BraintreeVenmo + +class BTPaymentMethodNonceParser_Venmo_Tests: XCTestCase { + func testSharedParser_whenTypeIsVenmo_returnsVenmoAccountNonce() { + let sharedParser = BTPaymentMethodNonceParser.shared + + let venmoAccountJSON = BTJSON(value: [ + "consumed": false, + "description": "VenmoAccount", + "details": ["username": "jane.doe.username@example.com", "cardType": "Discover"], + "isLocked": false, + "nonce": "a-nonce", + "securityQuestions": [] as [Any], + "type": "VenmoAccount", + "default": true + ] as [String: Any]) + + let venmoAccountNonce = sharedParser.parseJSON(venmoAccountJSON, withParsingBlockForType: "VenmoAccount") as! BTVenmoAccountNonce + + XCTAssertEqual(venmoAccountNonce.nonce, "a-nonce") + XCTAssertEqual(venmoAccountNonce.type, "Venmo") + XCTAssertEqual(venmoAccountNonce.username, "jane.doe.username@example.com") + } +} From 6cbd5ed756f9423461d9efcfb7883c56d0404fae Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 18 Sep 2023 09:52:55 -0500 Subject: [PATCH 06/14] remove test not actually for parser --- Braintree.xcodeproj/project.pbxproj | 6 +- ...aymentMethodNonceParser_PayPal_Tests.swift | 168 ------------------ 2 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 UnitTests/BraintreePayPalTests/BTPaymentMethodNonceParser_PayPal_Tests.swift diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index d9c5defb13..051b317c04 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 53; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -150,7 +150,6 @@ A95C411724FAEF5100045045 /* BTCardNonce_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A094F51B8276E500D732CC /* BTCardNonce_Tests.swift */; }; A95C411824FAEF5100045045 /* BTThreeDSecureInfo_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0301A42E22E2286C008A26BD /* BTThreeDSecureInfo_Tests.swift */; }; A95C411C24FAF21B00045045 /* BraintreeTestShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A903E1A624F9D34000C314E1 /* BraintreeTestShared.framework */; }; - A977A04124FEC36F006049AB /* BTPaymentMethodNonceParser_PayPal_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A977A04024FEC36F006049AB /* BTPaymentMethodNonceParser_PayPal_Tests.swift */; platformFilter = ios; }; A977A06B24FECFC3006049AB /* NonceValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A977A06A24FECFC3006049AB /* NonceValidator.swift */; }; A9A76CA724F9E92E0044EAEE /* TestClientTokenFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A76CA624F9E92E0044EAEE /* TestClientTokenFactory.swift */; }; A9E5C1A324FD5A7C00EE691F /* BraintreeDataCollector.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A76D7C001BB1CAB00000FA6A /* BraintreeDataCollector.framework */; platformFilter = ios; }; @@ -781,7 +780,6 @@ A9589DD924FEA45C00AF4FF7 /* BTConfiguration+Venmo_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BTConfiguration+Venmo_Tests.swift"; sourceTree = ""; }; A95C410824FAEF2100045045 /* BraintreeCardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BraintreeCardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A95C410C24FAEF2100045045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - A977A04024FEC36F006049AB /* BTPaymentMethodNonceParser_PayPal_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_PayPal_Tests.swift; sourceTree = ""; }; A977A06924FECBAF006049AB /* BraintreeThreeDSecureTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BraintreeThreeDSecureTests-Bridging-Header.h"; sourceTree = ""; }; A977A06A24FECFC3006049AB /* NonceValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonceValidator.swift; sourceTree = ""; }; A9A76CA624F9E92E0044EAEE /* TestClientTokenFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestClientTokenFactory.swift; sourceTree = ""; }; @@ -1650,7 +1648,6 @@ children = ( A9E5C1F724FD672A00EE691F /* BraintreePayPalTests-Bridging-Header.h */, A95229C624FD949D006F7D25 /* BTConfiguration+PayPal_Tests.swift */, - A977A04024FEC36F006049AB /* BTPaymentMethodNonceParser_PayPal_Tests.swift */, 3B7A261229C35B670087059D /* BTPayPalAnalytics_Tests.swift */, 42FC237025CE0E110047C49A /* BTPayPalCheckoutRequest_Tests.swift */, 427F32DF25D1D62D00435294 /* BTPayPalClient_Tests.swift */, @@ -3026,7 +3023,6 @@ 427F32E025D1D62D00435294 /* BTPayPalClient_Tests.swift in Sources */, 42FC218B25CDE0290047C49A /* BTPayPalRequest_Tests.swift in Sources */, 42FC237125CE0E110047C49A /* BTPayPalCheckoutRequest_Tests.swift in Sources */, - A977A04124FEC36F006049AB /* BTPaymentMethodNonceParser_PayPal_Tests.swift in Sources */, 427F329025D1A7B900435294 /* BTPayPalVaultRequest_Tests.swift in Sources */, 3B7A261429C35BD00087059D /* BTPayPalAnalytics_Tests.swift in Sources */, A95229C724FD949D006F7D25 /* BTConfiguration+PayPal_Tests.swift in Sources */, diff --git a/UnitTests/BraintreePayPalTests/BTPaymentMethodNonceParser_PayPal_Tests.swift b/UnitTests/BraintreePayPalTests/BTPaymentMethodNonceParser_PayPal_Tests.swift deleted file mode 100644 index 61ea9439ab..0000000000 --- a/UnitTests/BraintreePayPalTests/BTPaymentMethodNonceParser_PayPal_Tests.swift +++ /dev/null @@ -1,168 +0,0 @@ -import XCTest -@testable import BraintreePayPal - -class BTPaymentMethodNonceParser_PayPal_Tests: XCTestCase { - func testSharedParser_whenTypeIsPayPal_returnsPayPalAccountNonce() { - let payPalAccountNonce = BTPayPalAccountNonce( - json: BTJSON( - value: [ - "consumed": false, - "description": "jane.doe@example.com", - "details": [ - "email": "jane.doe@example.com", - ], - "isLocked": false, - "nonce": "a-nonce", - "securityQuestions": [] as [Any?], - "type": "PayPalAccount", - "default": true - ] as [String: Any] - ) - ) - - XCTAssertEqual(payPalAccountNonce?.nonce, "a-nonce") - XCTAssertEqual(payPalAccountNonce?.type, "PayPal") - XCTAssertEqual(payPalAccountNonce?.email, "jane.doe@example.com") - XCTAssertTrue(payPalAccountNonce!.isDefault) - XCTAssertNil(payPalAccountNonce?.creditFinancing) - } - - func testParsePayPalCreditFinancingAmount() { - let payPalCreditFinancingAmount = BTJSON(value: [ - "currency": "USD", - "value": "123.45", - ]) - - guard let amount = payPalCreditFinancingAmount.asPayPalCreditFinancingAmount() else { - XCTFail("Expected amount") - return - } - XCTAssertEqual(amount.currency, "USD") - XCTAssertEqual(amount.value, "123.45") - } - - func testParsePayPalCreditFinancing() { - let payPalCreditFinancing = BTJSON(value: [ - "cardAmountImmutable": false, - "monthlyPayment": [ - "currency": "USD", - "value": "123.45", - ], - "payerAcceptance": false, - "term": 3, - "totalCost": [ - "currency": "ABC", - "value": "789.01", - ], - "totalInterest": [ - "currency": "XYZ", - "value": "456.78", - ], - ] as [String: Any]) - - guard let creditFinancing = payPalCreditFinancing.asPayPalCreditFinancing() else { - XCTFail("Expected credit financing") - return - } - - XCTAssertFalse(creditFinancing.cardAmountImmutable) - guard let monthlyPayment = creditFinancing.monthlyPayment else { - XCTFail("Expected monthly payment details") - return - } - XCTAssertEqual(monthlyPayment.currency, "USD") - XCTAssertEqual(monthlyPayment.value, "123.45") - - XCTAssertFalse(creditFinancing.payerAcceptance) - XCTAssertEqual(creditFinancing.term, 3) - - XCTAssertNotNil(creditFinancing.totalCost) - - guard let totalCost = creditFinancing.totalCost else { - XCTFail("Expected total cost details") - return - } - XCTAssertEqual(totalCost.currency, "ABC") - XCTAssertEqual(totalCost.value, "789.01") - - guard let totalInterest = creditFinancing.totalInterest else { - XCTFail("Expected total interest details") - return - } - XCTAssertEqual(totalInterest.currency, "XYZ") - XCTAssertEqual(totalInterest.value, "456.78") - } - - func testSharedParser_whenTypeIsPayPal_returnsPayPalAccountNonceWithCreditFinancingOffered() { - let payPalAccountNonce = BTPayPalAccountNonce( - json: BTJSON( - value: [ - "consumed": false, - "description": "jane.doe@example.com", - "details": [ - "email": "jane.doe@example.com", - "creditFinancingOffered": [ - "cardAmountImmutable": true, - "monthlyPayment": [ - "currency": "USD", - "value": "13.88", - ] as [String: Any], - "payerAcceptance": true, - "term": 18, - "totalCost": [ - "currency": "USD", - "value": "250.00", - ], - "totalInterest": [ - "currency": "USD", - "value": "0.00", - ], - ] as [String: Any], - ] as [String: Any], - "isLocked": false, - "nonce": "a-nonce", - "securityQuestions": [] as [Any?], - "type": "PayPalAccount", - "default": true, - ] as [String: Any] - ) - ) - - XCTAssertEqual(payPalAccountNonce?.nonce, "a-nonce") - XCTAssertEqual(payPalAccountNonce?.type, "PayPal") - XCTAssertEqual(payPalAccountNonce?.email, "jane.doe@example.com") - XCTAssertTrue(payPalAccountNonce!.isDefault) - - guard let creditFinancing = payPalAccountNonce?.creditFinancing else { - XCTFail("Expected credit financing terms") - return - } - - XCTAssertTrue(creditFinancing.cardAmountImmutable) - guard let monthlyPayment = creditFinancing.monthlyPayment else { - XCTFail("Expected monthly payment details") - return - } - XCTAssertEqual(monthlyPayment.currency, "USD") - XCTAssertEqual(monthlyPayment.value, "13.88") - - XCTAssertTrue(creditFinancing.payerAcceptance) - XCTAssertEqual(creditFinancing.term, 18) - - XCTAssertNotNil(creditFinancing.totalCost) - - guard let totalCost = creditFinancing.totalCost else { - XCTFail("Expected total cost details") - return - } - XCTAssertEqual(totalCost.currency, "USD") - XCTAssertEqual(totalCost.value, "250.00") - - guard let totalInterest = creditFinancing.totalInterest else { - XCTFail("Expected total interest details") - return - } - XCTAssertEqual(totalInterest.currency, "USD") - XCTAssertEqual(totalInterest.value, "0.00") - } -} From 1d58414c770b7b1399ea1620104898e36d6f4498 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Fri, 22 Sep 2023 08:42:55 -0500 Subject: [PATCH 07/14] add next major version note --- Sources/BraintreeCore/BTAPIClient.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/BraintreeCore/BTAPIClient.swift b/Sources/BraintreeCore/BTAPIClient.swift index a18dcac813..d59b682a23 100644 --- a/Sources/BraintreeCore/BTAPIClient.swift +++ b/Sources/BraintreeCore/BTAPIClient.swift @@ -207,6 +207,9 @@ import Foundation fetchPaymentMethodNonces(false, completion: completion) } + // NEXT_MAJOR_VERSION: this should move into the Drop-in for parity with Android + // This will also allow us to return the types directly which we were doing in the +load method + // previously in Obj-C - this is not available in Swift /// Fetches a customer's vaulted payment method nonces. /// Must be using client token with a customer ID specified. /// - Parameters: From 0310ecb9d7c2de9d43eb94cd9fe16413b92e3d66 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Fri, 22 Sep 2023 14:50:29 -0500 Subject: [PATCH 08/14] add logic for different types --- .../BTPaymentMethodNonceParser.swift | 24 +++++++++++++++++-- ...mentMethodNonceParser_ApplePay_Tests.swift | 2 +- ...PaymentMethodNonceParser_Venmo_Tests.swift | 1 - 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift b/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift index 02174671cd..7268e8bd44 100644 --- a/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift +++ b/Sources/BraintreeCore/BTPaymentMethodNonceParser.swift @@ -61,16 +61,36 @@ import Foundation return nil } - if let cardType = json?["details"]["cardType"].asString() { + let type = json?["type"].asString() + + if type == "CreditCard", let cardType = json?["details"]["cardType"].asString() { return BTPaymentMethodNonce( nonce: json?["nonce"].asString() ?? "", type: self.cardType(from: cardType), isDefault: json?["default"].isTrue ?? false ) + } else if type == "ApplePayCard" { + return BTPaymentMethodNonce( + nonce: json?["nonce"].asString() ?? "", + type: json?["details"]["cardType"].asString() ?? "ApplePayCard", + isDefault: json?["default"].isTrue ?? false + ) + } else if type == "PayPalAccount" { + return BTPaymentMethodNonce( + nonce: json?["nonce"].asString() ?? "", + type: "PayPal", + isDefault: json?["default"].isTrue ?? false + ) + } else if type == "VenmoAccount" { + return BTPaymentMethodNonce( + nonce: json?["nonce"].asString() ?? "", + type: "Venmo", + isDefault: json?["default"].isTrue ?? false + ) } else { return BTPaymentMethodNonce( nonce: json?["nonce"].asString() ?? "", - type: json?["type"].asString() ?? "Unknown", + type: "Unknown", isDefault: json?["default"].isTrue ?? false ) } diff --git a/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift b/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift index d69f4e5ee2..460a79a8c2 100644 --- a/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift +++ b/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift @@ -16,7 +16,7 @@ class BTPaymentMethodNonceParser_ApplePay_Tests: XCTestCase { "type": "ApplePayCard", ] as [String: Any]) - let applePayCardNonce = sharedParser.parseJSON(applePayCard, withParsingBlockForType: "ApplePayCard") as? BTApplePayCardNonce + let applePayCardNonce = sharedParser.parseJSON(applePayCard, withParsingBlockForType: "ApplePayCard") XCTAssertEqual(applePayCardNonce?.nonce, "a-nonce") XCTAssertEqual(applePayCardNonce?.type, "American Express") diff --git a/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift b/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift index add0a1a663..c179a8efc8 100644 --- a/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift +++ b/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift @@ -21,6 +21,5 @@ class BTPaymentMethodNonceParser_Venmo_Tests: XCTestCase { XCTAssertEqual(venmoAccountNonce.nonce, "a-nonce") XCTAssertEqual(venmoAccountNonce.type, "Venmo") - XCTAssertEqual(venmoAccountNonce.username, "jane.doe.username@example.com") } } From 58da86516334efcf771981ad4a0cafce7a99a574 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 25 Sep 2023 09:04:18 -0500 Subject: [PATCH 09/14] move tests for parser into single file --- Braintree.xcodeproj/project.pbxproj | 12 --- ...mentMethodNonceParser_ApplePay_Tests.swift | 24 ------ ...TPaymentMethodNonceParser_Card_Tests.swift | 30 ------- .../BTPaymentMethodNonceParser_Tests.swift | 84 ++++++++++++++++++- ...PaymentMethodNonceParser_Venmo_Tests.swift | 25 ------ 5 files changed, 83 insertions(+), 92 deletions(-) delete mode 100644 UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift delete mode 100644 UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift delete mode 100644 UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index 051b317c04..f51766b495 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -245,9 +245,6 @@ BE9EC0982899CF040022EC63 /* BTAPIPinnedCertificates.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9EC0972899CF040022EC63 /* BTAPIPinnedCertificates.swift */; }; BE9FB82B2898324C00D6FE2F /* BTPaymentMethodNonce.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9FB82A2898324C00D6FE2F /* BTPaymentMethodNonce.swift */; }; BE9FB82D28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9FB82C28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift */; }; - BEA062E02AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA062DF2AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift */; }; - BEA062E22AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA062E12AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift */; }; - BEA062E52AB4933C0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA062E32AB4930D0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift */; }; BEB9BF532A26872B00A3673E /* BTWebAuthenticationSessionClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEB9BF522A26872B00A3673E /* BTWebAuthenticationSessionClient.swift */; }; BEBC222728D25BB400D83186 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80DBE69423A931A600373230 /* Helpers.swift */; }; BEBC6E4B29258FD4004E25A0 /* BraintreeCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570B93AC285397520041BAFE /* BraintreeCore.framework */; }; @@ -862,9 +859,6 @@ BE9EC0972899CF040022EC63 /* BTAPIPinnedCertificates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTAPIPinnedCertificates.swift; sourceTree = ""; }; BE9FB82A2898324C00D6FE2F /* BTPaymentMethodNonce.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonce.swift; sourceTree = ""; }; BE9FB82C28984ADE00D6FE2F /* BTPaymentMethodNonceParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser.swift; sourceTree = ""; }; - BEA062DF2AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_Venmo_Tests.swift; sourceTree = ""; }; - BEA062E12AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_Card_Tests.swift; sourceTree = ""; }; - BEA062E32AB4930D0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPaymentMethodNonceParser_ApplePay_Tests.swift; sourceTree = ""; }; BEB9BF522A26872B00A3673E /* BTWebAuthenticationSessionClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTWebAuthenticationSessionClient.swift; sourceTree = ""; }; BEBC6E5D2927CF59004E25A0 /* Braintree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Braintree.h; sourceTree = ""; }; BEBC6F252937A510004E25A0 /* BTClientMetadata_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTClientMetadata_Tests.swift; sourceTree = ""; }; @@ -1595,7 +1589,6 @@ BEDB820329B10ADA00075AF3 /* BTApplePayAnalytics_Tests.swift */, 800FC543257FDC5100DEE132 /* BTApplePayCardNonce_Tests.swift */, A95229CA24FD9E41006F7D25 /* BTConfiguration+ApplePay_Tests.swift */, - BEA062E32AB4930D0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift */, A948D6E024FAC6C000F4F178 /* Info.plist */, ); path = BraintreeApplePayTests; @@ -1605,7 +1598,6 @@ isa = PBXGroup; children = ( A9589DD924FEA45C00AF4FF7 /* BTConfiguration+Venmo_Tests.swift */, - BEA062DF2AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift */, 4228D80C2624D8C9001D2564 /* BTVenmoAccountNonce_Tests.swift */, 3B1C529529D637F400B68A58 /* BTVenmoAnalytics_Tests.swift */, 428F48E32624C9B700EC8DB4 /* BTVenmoAppSwitchRedirectURL_Tests.swift */, @@ -1626,7 +1618,6 @@ 3B14BFDE29B647AF0047426A /* BTCardAnalytics_Tests.swift */, A75147E01B4217A00005BBBA /* BTCardClient_Tests.swift */, A7A094F51B8276E500D732CC /* BTCardNonce_Tests.swift */, - BEA062E12AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift */, 0301A42E22E2286C008A26BD /* BTThreeDSecureInfo_Tests.swift */, A95C410C24FAEF2100045045 /* Info.plist */, ); @@ -2970,7 +2961,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BEA062E52AB4933C0028E933 /* BTPaymentMethodNonceParser_ApplePay_Tests.swift in Sources */, A95229CB24FD9E41006F7D25 /* BTConfiguration+ApplePay_Tests.swift in Sources */, A948D6E724FAC71A00F4F178 /* BTApplePay_Tests.swift in Sources */, 800FC544257FDC5100DEE132 /* BTApplePayCardNonce_Tests.swift in Sources */, @@ -2982,14 +2972,12 @@ buildActionMask = 2147483647; files = ( A9589DDA24FEA45C00AF4FF7 /* BTConfiguration+Venmo_Tests.swift in Sources */, - BEA062E02AB492250028E933 /* BTPaymentMethodNonceParser_Venmo_Tests.swift in Sources */, 09357DCB2A2FBEC10096D449 /* BTVenmoLineItem_Tests.swift in Sources */, 3B1C529729D638D400B68A58 /* BTVenmoAnalytics_Tests.swift in Sources */, 4228D8692624E5C3001D2564 /* BTVenmoRequest_Tests.swift in Sources */, 428F48E42624C9B700EC8DB4 /* BTVenmoAppSwitchRedirectURL_Tests.swift in Sources */, 4245D669256C255F00F1A413 /* BTVenmoAppSwitchReturnURL_Tests.swift in Sources */, A948D6FD24FAC93100F4F178 /* BTVenmoClient_Tests.swift in Sources */, - BEA062E22AB4926E0028E933 /* BTPaymentMethodNonceParser_Card_Tests.swift in Sources */, 4228D80D2624D8C9001D2564 /* BTVenmoAccountNonce_Tests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift b/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift deleted file mode 100644 index 460a79a8c2..0000000000 --- a/UnitTests/BraintreeApplePayTests/BTPaymentMethodNonceParser_ApplePay_Tests.swift +++ /dev/null @@ -1,24 +0,0 @@ -import XCTest -@testable import BraintreeCore -@testable import BraintreeApplePay - -class BTPaymentMethodNonceParser_ApplePay_Tests: XCTestCase { - func testSharedParser_whenTypeIsApplePayCard_returnsApplePayCardNonce() { - let sharedParser = BTPaymentMethodNonceParser.shared - let applePayCard = BTJSON(value: [ - "consumed": false, - "details": [ - "cardType": "American Express" - ], - "isLocked": false, - "nonce": "a-nonce", - "securityQuestions": [] as [Any], - "type": "ApplePayCard", - ] as [String: Any]) - - let applePayCardNonce = sharedParser.parseJSON(applePayCard, withParsingBlockForType: "ApplePayCard") - - XCTAssertEqual(applePayCardNonce?.nonce, "a-nonce") - XCTAssertEqual(applePayCardNonce?.type, "American Express") - } -} diff --git a/UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift b/UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift deleted file mode 100644 index 99122df1b2..0000000000 --- a/UnitTests/BraintreeCardTests/BTPaymentMethodNonceParser_Card_Tests.swift +++ /dev/null @@ -1,30 +0,0 @@ -import XCTest -@testable import BraintreeCore -@testable import BraintreeCard - -class BTPaymentMethodNonceParser_Card_Tests: XCTestCase { - func testSharedParser_whenTypeIsCreditCard_returnsCorrectCardNonce() { - let sharedParser = BTPaymentMethodNonceParser.shared - - let creditCardJSON = BTJSON(value: [ - "consumed": false, - "description": "ending in 31", - "details": [ - "cardType": "American Express", - "lastTwo": "31", - ], - "isLocked": false, - "nonce": "0099b1d0-7a1c-44c3-b1e4-297082290bb9", - "securityQuestions": ["cvv"], - "threeDSecureInfo": NSNull(), - "type": "CreditCard", - "default": true - ] as [String: Any]) - - let cardNonce = sharedParser.parseJSON(creditCardJSON, withParsingBlockForType:"CreditCard")! - - XCTAssertEqual(cardNonce.nonce, "0099b1d0-7a1c-44c3-b1e4-297082290bb9") - XCTAssertEqual(cardNonce.type, "AMEX") - XCTAssertTrue(cardNonce.isDefault) - } -} diff --git a/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift b/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift index 741ea7471b..733fe12a8b 100644 --- a/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift +++ b/UnitTests/BraintreeCoreTests/BTPaymentMethodNonceParser_Tests.swift @@ -2,7 +2,7 @@ import XCTest @testable import BraintreeCore class BTPaymentMethodNonceParser_Tests: XCTestCase { - var parser : BTPaymentMethodNonceParser = BTPaymentMethodNonceParser() + var parser: BTPaymentMethodNonceParser = BTPaymentMethodNonceParser() func testRegisterType_addsTypeToTypes() { parser.registerType("MyType") { _ -> BTPaymentMethodNonce? in return nil} @@ -67,4 +67,86 @@ class BTPaymentMethodNonceParser_Tests: XCTestCase { XCTAssertEqual(unknownNonce.type, "Unknown") XCTAssertTrue(unknownNonce.isDefault) } + + func testSharedParser_whenTypeIsApplePayCard_returnsApplePayType() { + let sharedParser = BTPaymentMethodNonceParser.shared + let applePayCard = BTJSON(value: [ + "consumed": false, + "details": ["cardType": "American Express"], + "isLocked": false, + "nonce": "a-nonce", + "securityQuestions": [] as [Any], + "type": "ApplePayCard", + ] as [String: Any]) + + let applePayCardNonce = sharedParser.parseJSON(applePayCard, withParsingBlockForType: "ApplePayCard") + + XCTAssertEqual(applePayCardNonce?.nonce, "a-nonce") + XCTAssertEqual(applePayCardNonce?.type, "American Express") + } + + func testSharedParser_whenTypeIsCreditCard_returnsCardType() { + let sharedParser = BTPaymentMethodNonceParser.shared + + let creditCardJSON = BTJSON(value: [ + "consumed": false, + "description": "ending in 31", + "details": [ + "cardType": "American Express", + "lastTwo": "31", + ], + "isLocked": false, + "nonce": "0099b1d0-7a1c-44c3-b1e4-297082290bb9", + "securityQuestions": ["cvv"], + "threeDSecureInfo": NSNull(), + "type": "CreditCard", + "default": true + ] as [String: Any]) + + let cardNonce = sharedParser.parseJSON(creditCardJSON, withParsingBlockForType:"CreditCard")! + + XCTAssertEqual(cardNonce.nonce, "0099b1d0-7a1c-44c3-b1e4-297082290bb9") + XCTAssertEqual(cardNonce.type, "AMEX") + XCTAssertTrue(cardNonce.isDefault) + } + + func testSharedParser_whenTypeIsVenmo_returnsVenmoType() { + let sharedParser = BTPaymentMethodNonceParser.shared + + let venmoAccountJSON = BTJSON(value: [ + "consumed": false, + "description": "VenmoAccount", + "details": ["username": "jane.doe.username@example.com"], + "isLocked": false, + "nonce": "a-nonce", + "securityQuestions": [] as [Any], + "type": "VenmoAccount", + "default": true + ] as [String: Any]) + + let venmoAccountNonce = sharedParser.parseJSON(venmoAccountJSON, withParsingBlockForType: "VenmoAccount") + + XCTAssertEqual(venmoAccountNonce?.nonce, "a-nonce") + XCTAssertEqual(venmoAccountNonce?.type, "Venmo") + } + + func testSharedParser_whenTypeIsPayPal_returnsPayPalType() { + let sharedParser = BTPaymentMethodNonceParser.shared + + let payPalAccountJSON = BTJSON(value: [ + "consumed": false, + "description": "jane.doe@example.com", + "details": ["email": "jane.doe@example.com"], + "isLocked": false, + "nonce": "a-nonce", + "securityQuestions": [] as [Any], + "type": "PayPalAccount", + "default": true + ] as [String: Any]) + + let payPalAccountNonce = sharedParser.parseJSON(payPalAccountJSON, withParsingBlockForType: "PayPalAccount") + + XCTAssertEqual(payPalAccountNonce?.nonce, "a-nonce") + XCTAssertEqual(payPalAccountNonce?.type, "PayPal") + } } diff --git a/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift b/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift deleted file mode 100644 index c179a8efc8..0000000000 --- a/UnitTests/BraintreeVenmoTests/BTPaymentMethodNonceParser_Venmo_Tests.swift +++ /dev/null @@ -1,25 +0,0 @@ -import XCTest -@testable import BraintreeCore -@testable import BraintreeVenmo - -class BTPaymentMethodNonceParser_Venmo_Tests: XCTestCase { - func testSharedParser_whenTypeIsVenmo_returnsVenmoAccountNonce() { - let sharedParser = BTPaymentMethodNonceParser.shared - - let venmoAccountJSON = BTJSON(value: [ - "consumed": false, - "description": "VenmoAccount", - "details": ["username": "jane.doe.username@example.com", "cardType": "Discover"], - "isLocked": false, - "nonce": "a-nonce", - "securityQuestions": [] as [Any], - "type": "VenmoAccount", - "default": true - ] as [String: Any]) - - let venmoAccountNonce = sharedParser.parseJSON(venmoAccountJSON, withParsingBlockForType: "VenmoAccount") as! BTVenmoAccountNonce - - XCTAssertEqual(venmoAccountNonce.nonce, "a-nonce") - XCTAssertEqual(venmoAccountNonce.type, "Venmo") - } -} From 9cee19642d36e613ba870d84929e5b6df35e6d7f Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 25 Sep 2023 09:08:50 -0500 Subject: [PATCH 10/14] add note to docstring --- Sources/BraintreeCore/BTAPIClient.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/BraintreeCore/BTAPIClient.swift b/Sources/BraintreeCore/BTAPIClient.swift index d59b682a23..8f858f265c 100644 --- a/Sources/BraintreeCore/BTAPIClient.swift +++ b/Sources/BraintreeCore/BTAPIClient.swift @@ -203,6 +203,7 @@ import Foundation /// Fetches a customer's vaulted payment method nonces. /// Must be using client token with a customer ID specified. /// - Parameter completion: Callback that returns either an array of payment method nonces or an error + /// - Note: Only the top level `BTPaymentMethodNonce` type is returned, fetching any additional details will need to be done on the server public func fetchPaymentMethodNonces(_ completion: @escaping ([BTPaymentMethodNonce]?, Error?) -> Void) { fetchPaymentMethodNonces(false, completion: completion) } @@ -215,6 +216,7 @@ import Foundation /// - Parameters: /// - defaultFirst: Specifies whether to sort the fetched payment method nonces with the default payment method or the most recently used payment method first /// - completion: Callback that returns either an array of payment method nonces or an error + /// - Note: Only the top level `BTPaymentMethodNonce` type is returned, fetching any additional details will need to be done on the server public func fetchPaymentMethodNonces(_ defaultFirst: Bool, completion: @escaping ([BTPaymentMethodNonce]?, Error?) -> Void) { if clientToken == nil { completion(nil, BTAPIClientError.notAuthorized) From 4b89b344ef4167bf909361d1e3c6d39beb3a5ca1 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 25 Sep 2023 09:10:20 -0500 Subject: [PATCH 11/14] Update Braintree.xcodeproj/project.pbxproj --- Braintree.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index f51766b495..dbd6727714 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 53; objects = { /* Begin PBXBuildFile section */ From c36f2381292aa3600a75796effb9d63575ce2e0c Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 25 Sep 2023 09:16:58 -0500 Subject: [PATCH 12/14] update BTAPIClient_Tests --- UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift b/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift index 8d30598c59..3c77f71ed1 100644 --- a/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift +++ b/UnitTests/BraintreeCoreTests/BTAPIClient_Tests.swift @@ -248,11 +248,11 @@ class BTAPIClient_Tests: XCTestCase { let firstNonce = paymentMethodNonces[0]; XCTAssertEqual(firstNonce.nonce, "fake-nonce1") - XCTAssertEqual(firstNonce.type, "CreditCard") + XCTAssertEqual(firstNonce.type, "AMEX") let secondNonce = paymentMethodNonces[1] XCTAssertEqual(secondNonce.nonce, "fake-nonce2") - XCTAssertEqual(secondNonce.type, "PayPalAccount") + XCTAssertEqual(secondNonce.type, "PayPal") expectation.fulfill() } From 388c36a1e386a5bd914715789ec96237c0ac47ca Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 25 Sep 2023 09:31:09 -0500 Subject: [PATCH 13/14] move tests into BTPayPalAccountNonce_Tests file --- Braintree.xcodeproj/project.pbxproj | 6 +- .../BTPayPalAccountNonce_Tests.swift | 144 ++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 UnitTests/BraintreePayPalTests/BTPayPalAccountNonce_Tests.swift diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index dbd6727714..87412b3cc4 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 53; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -269,6 +269,7 @@ BEDB820629B13F9500075AF3 /* BTPayPalNativeCheckoutAccountNonce_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEDB820529B13F9500075AF3 /* BTPayPalNativeCheckoutAccountNonce_Tests.swift */; }; BEDB820829B675DC00075AF3 /* BTVenmoAccountNonce.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEDB820729B675DC00075AF3 /* BTVenmoAccountNonce.swift */; }; BEDB820A29B7A9E600075AF3 /* BTVenmoClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEDB820929B7A9E600075AF3 /* BTVenmoClient.swift */; }; + BEDEAF112AC1D049004EA970 /* BTPayPalAccountNonce_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEDEAF102AC1D049004EA970 /* BTPayPalAccountNonce_Tests.swift */; }; BEE2E4A728FDB64400C03FDD /* BTAnalyticsService_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE2E4A628FDB64400C03FDD /* BTAnalyticsService_Tests.swift */; }; BEE2E4B9290043A200C03FDD /* PayPalCheckout in Frameworks */ = {isa = PBXBuildFile; productRef = BEE2E4B8290043A200C03FDD /* PayPalCheckout */; }; BEE2E4E6290080BD00C03FDD /* BTAnalyticsServiceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE2E4E5290080BD00C03FDD /* BTAnalyticsServiceError.swift */; }; @@ -881,6 +882,7 @@ BEDB820729B675DC00075AF3 /* BTVenmoAccountNonce.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTVenmoAccountNonce.swift; sourceTree = ""; }; BEDB820929B7A9E600075AF3 /* BTVenmoClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTVenmoClient.swift; sourceTree = ""; }; BEDE06942FEDCD2F91884DA9 /* Pods-Tests-IntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests-IntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-Tests-IntegrationTests/Pods-Tests-IntegrationTests.release.xcconfig"; sourceTree = ""; }; + BEDEAF102AC1D049004EA970 /* BTPayPalAccountNonce_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTPayPalAccountNonce_Tests.swift; sourceTree = ""; }; BEE2E4A628FDB64400C03FDD /* BTAnalyticsService_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTAnalyticsService_Tests.swift; sourceTree = ""; }; BEE2E4E329007FF100C03FDD /* BTAnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTAnalyticsService.swift; sourceTree = ""; }; BEE2E4E5290080BD00C03FDD /* BTAnalyticsServiceError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTAnalyticsServiceError.swift; sourceTree = ""; }; @@ -1639,6 +1641,7 @@ children = ( A9E5C1F724FD672A00EE691F /* BraintreePayPalTests-Bridging-Header.h */, A95229C624FD949D006F7D25 /* BTConfiguration+PayPal_Tests.swift */, + BEDEAF102AC1D049004EA970 /* BTPayPalAccountNonce_Tests.swift */, 3B7A261229C35B670087059D /* BTPayPalAnalytics_Tests.swift */, 42FC237025CE0E110047C49A /* BTPayPalCheckoutRequest_Tests.swift */, 427F32DF25D1D62D00435294 /* BTPayPalClient_Tests.swift */, @@ -3011,6 +3014,7 @@ 427F32E025D1D62D00435294 /* BTPayPalClient_Tests.swift in Sources */, 42FC218B25CDE0290047C49A /* BTPayPalRequest_Tests.swift in Sources */, 42FC237125CE0E110047C49A /* BTPayPalCheckoutRequest_Tests.swift in Sources */, + BEDEAF112AC1D049004EA970 /* BTPayPalAccountNonce_Tests.swift in Sources */, 427F329025D1A7B900435294 /* BTPayPalVaultRequest_Tests.swift in Sources */, 3B7A261429C35BD00087059D /* BTPayPalAnalytics_Tests.swift in Sources */, A95229C724FD949D006F7D25 /* BTConfiguration+PayPal_Tests.swift in Sources */, diff --git a/UnitTests/BraintreePayPalTests/BTPayPalAccountNonce_Tests.swift b/UnitTests/BraintreePayPalTests/BTPayPalAccountNonce_Tests.swift new file mode 100644 index 0000000000..3605d52abe --- /dev/null +++ b/UnitTests/BraintreePayPalTests/BTPayPalAccountNonce_Tests.swift @@ -0,0 +1,144 @@ +import XCTest +@testable import BraintreePayPal + +final class BTPayPalAccountNonce_Tests: XCTestCase { + + func testPayPalAccountNonce_returnsPayPalCreditFinancingAmount() { + let payPalCreditFinancingAmount = BTJSON(value: [ + "currency": "USD", + "value": "123.45", + ]) + + guard let amount = payPalCreditFinancingAmount.asPayPalCreditFinancingAmount() else { + XCTFail("Expected amount") + return + } + XCTAssertEqual(amount.currency, "USD") + XCTAssertEqual(amount.value, "123.45") + } + + func testPayPalAccountNonce_returnsPayPalCreditFinancing() { + let payPalCreditFinancing = BTJSON(value: [ + "cardAmountImmutable": false, + "monthlyPayment": [ + "currency": "USD", + "value": "123.45", + ], + "payerAcceptance": false, + "term": 3, + "totalCost": [ + "currency": "ABC", + "value": "789.01", + ], + "totalInterest": [ + "currency": "XYZ", + "value": "456.78", + ], + ] as [String: Any]) + + guard let creditFinancing = payPalCreditFinancing.asPayPalCreditFinancing() else { + XCTFail("Expected credit financing") + return + } + + XCTAssertFalse(creditFinancing.cardAmountImmutable) + guard let monthlyPayment = creditFinancing.monthlyPayment else { + XCTFail("Expected monthly payment details") + return + } + XCTAssertEqual(monthlyPayment.currency, "USD") + XCTAssertEqual(monthlyPayment.value, "123.45") + + XCTAssertFalse(creditFinancing.payerAcceptance) + XCTAssertEqual(creditFinancing.term, 3) + + XCTAssertNotNil(creditFinancing.totalCost) + + guard let totalCost = creditFinancing.totalCost else { + XCTFail("Expected total cost details") + return + } + XCTAssertEqual(totalCost.currency, "ABC") + XCTAssertEqual(totalCost.value, "789.01") + + guard let totalInterest = creditFinancing.totalInterest else { + XCTFail("Expected total interest details") + return + } + XCTAssertEqual(totalInterest.currency, "XYZ") + XCTAssertEqual(totalInterest.value, "456.78") + } + + func testPayPalAccountNonce_returnsPayPalAccountNonceWithCreditFinancingOffered() { + let payPalAccountNonce = BTPayPalAccountNonce( + json: BTJSON( + value: [ + "consumed": false, + "description": "jane.doe@example.com", + "details": [ + "email": "jane.doe@example.com", + "creditFinancingOffered": [ + "cardAmountImmutable": true, + "monthlyPayment": [ + "currency": "USD", + "value": "13.88", + ] as [String: Any], + "payerAcceptance": true, + "term": 18, + "totalCost": [ + "currency": "USD", + "value": "250.00", + ], + "totalInterest": [ + "currency": "USD", + "value": "0.00", + ], + ] as [String: Any], + ] as [String: Any], + "isLocked": false, + "nonce": "a-nonce", + "securityQuestions": [] as [Any?], + "type": "PayPalAccount", + "default": true, + ] as [String: Any] + ) + ) + + XCTAssertEqual(payPalAccountNonce?.nonce, "a-nonce") + XCTAssertEqual(payPalAccountNonce?.type, "PayPal") + XCTAssertEqual(payPalAccountNonce?.email, "jane.doe@example.com") + XCTAssertTrue(payPalAccountNonce!.isDefault) + + guard let creditFinancing = payPalAccountNonce?.creditFinancing else { + XCTFail("Expected credit financing terms") + return + } + + XCTAssertTrue(creditFinancing.cardAmountImmutable) + guard let monthlyPayment = creditFinancing.monthlyPayment else { + XCTFail("Expected monthly payment details") + return + } + XCTAssertEqual(monthlyPayment.currency, "USD") + XCTAssertEqual(monthlyPayment.value, "13.88") + + XCTAssertTrue(creditFinancing.payerAcceptance) + XCTAssertEqual(creditFinancing.term, 18) + + XCTAssertNotNil(creditFinancing.totalCost) + + guard let totalCost = creditFinancing.totalCost else { + XCTFail("Expected total cost details") + return + } + XCTAssertEqual(totalCost.currency, "USD") + XCTAssertEqual(totalCost.value, "250.00") + + guard let totalInterest = creditFinancing.totalInterest else { + XCTFail("Expected total interest details") + return + } + XCTAssertEqual(totalInterest.currency, "USD") + XCTAssertEqual(totalInterest.value, "0.00") + } +} From bf0a6763d885004fb8e14efcf410c03d3ab072a6 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 25 Sep 2023 09:32:10 -0500 Subject: [PATCH 14/14] Update Braintree.xcodeproj/project.pbxproj --- Braintree.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Braintree.xcodeproj/project.pbxproj b/Braintree.xcodeproj/project.pbxproj index 87412b3cc4..9556cad414 100644 --- a/Braintree.xcodeproj/project.pbxproj +++ b/Braintree.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 53; objects = { /* Begin PBXBuildFile section */