From c2178bc858f23dd751618bc99cded908e80daa83 Mon Sep 17 00:00:00 2001 From: Victoria Park Date: Tue, 22 Oct 2024 15:27:46 -0700 Subject: [PATCH] Card vault to completion, unit tests --- Demo/Demo/ViewModels/CardVaultViewModel.swift | 42 +--- PayPal.xcodeproj/project.pbxproj | 8 - Sources/CardPayments/CardClient.swift | 39 ++-- Sources/CardPayments/CardClientError.swift | 11 +- Sources/CardPayments/CardVaultDelegate.swift | 35 ---- .../CardPaymentsTests/CardClient_Tests.swift | 194 ++++++++---------- .../Mocks/MockCardVaultDelegate.swift | 45 ---- 7 files changed, 123 insertions(+), 251 deletions(-) delete mode 100644 Sources/CardPayments/CardVaultDelegate.swift delete mode 100644 UnitTests/CardPaymentsTests/Mocks/MockCardVaultDelegate.swift diff --git a/Demo/Demo/ViewModels/CardVaultViewModel.swift b/Demo/Demo/ViewModels/CardVaultViewModel.swift index 8b5f06f6a..5a50f8cb3 100644 --- a/Demo/Demo/ViewModels/CardVaultViewModel.swift +++ b/Demo/Demo/ViewModels/CardVaultViewModel.swift @@ -2,7 +2,7 @@ import Foundation import CardPayments import CorePayments -class CardVaultViewModel: VaultViewModel, CardVaultDelegate { +class CardVaultViewModel: VaultViewModel { let configManager = CoreConfigManager(domain: "Card Vault") @@ -13,11 +13,16 @@ class CardVaultViewModel: VaultViewModel, CardVaultDelegate { do { let config = try await configManager.getCoreConfig() let cardClient = CardClient(config: config) - cardClient.vaultDelegate = self let cardVaultRequest = CardVaultRequest(card: card, setupTokenID: setupToken) - cardClient.vault(cardVaultRequest) + cardClient.vault(cardVaultRequest) { result, error in + if let result { + self.setUpdateSetupTokenResult(vaultResult: result, vaultError: nil) + } else if let error { + self.setUpdateSetupTokenResult(vaultResult: nil, vaultError: error) + } + } } catch { - self.state.updateSetupTokenResponse = .error(message: error.localizedDescription) + self.setUpdateSetupTokenResult(vaultResult: nil, vaultError: error) print("failed in updating setup token. \(error.localizedDescription)") } } @@ -31,7 +36,7 @@ class CardVaultViewModel: VaultViewModel, CardVaultDelegate { return enabled } - func setUpdateSetupTokenResult(vaultResult: CardVaultResult? = nil, vaultError: CoreSDKError? = nil) { + func setUpdateSetupTokenResult(vaultResult: CardVaultResult? = nil, vaultError: Error? = nil) { DispatchQueue.main.async { if let vaultResult { self.state.updateSetupTokenResponse = .loaded( @@ -46,31 +51,4 @@ class CardVaultViewModel: VaultViewModel, CardVaultDelegate { } } } - - // MARK: - CardVault Delegate - - func card(_ cardClient: CardPayments.CardClient, didFinishWithVaultResult vaultResult: CardPayments.CardVaultResult) { - print("vaultResult: \(vaultResult)") - setUpdateSetupTokenResult(vaultResult: vaultResult) - } - - func card(_ cardClient: CardPayments.CardClient, didFinishWithVaultError vaultError: CorePayments.CoreSDKError) { - print("error: \(vaultError.errorDescription ?? "")") - setUpdateSetupTokenResult(vaultError: vaultError) - } - - func cardThreeDSecureDidCancel(_ cardClient: CardClient) { - DispatchQueue.main.async { - self.state.updateSetupTokenResponse = .idle - self.state.updateSetupToken = nil - } - } - - func cardThreeDSecureWillLaunch(_ cardClient: CardPayments.CardClient) { - print("About to launch 3DS") - } - - func cardThreeDSecureDidFinish(_ cardClient: CardPayments.CardClient) { - print("Finished 3DS") - } } diff --git a/PayPal.xcodeproj/project.pbxproj b/PayPal.xcodeproj/project.pbxproj index 13cd616d3..95bdac453 100644 --- a/PayPal.xcodeproj/project.pbxproj +++ b/PayPal.xcodeproj/project.pbxproj @@ -13,8 +13,6 @@ 065A4DBF26FCDA5B0007014A /* CardClient_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065A4DBE26FCDA5B0007014A /* CardClient_Tests.swift */; }; 06CE009926F3D1660000CC46 /* CoreConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06CE009826F3D1660000CC46 /* CoreConfig.swift */; }; 06CE009B26F3D5A40000CC46 /* CardClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06CE009A26F3D5A40000CC46 /* CardClient.swift */; }; - 3B109B3C2A85CC6200D8135F /* MockCardVaultDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B109B3A2A85B54800D8135F /* MockCardVaultDelegate.swift */; }; - 3B22E8B62A840ECF00962E34 /* CardVaultDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B22E8B52A840ECF00962E34 /* CardVaultDelegate.swift */; }; 3B22E8B82A841AEA00962E34 /* CardVaultResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B22E8B72A841AEA00962E34 /* CardVaultResult.swift */; }; 3B29C3972B9148F70077741D /* PayPalVaultRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B29C3962B9148F70077741D /* PayPalVaultRequest.swift */; }; 3B3C511E2B2395B5009125FE /* PayPalVaultResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3C511D2B2395B5009125FE /* PayPalVaultResult.swift */; }; @@ -184,8 +182,6 @@ 06CE009A26F3D5A40000CC46 /* CardClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardClient.swift; sourceTree = ""; }; 06CE009F26F3DF100000CC46 /* ConfirmPaymentSourceRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmPaymentSourceRequest.swift; sourceTree = ""; }; 06CE00A226F3E32A0000CC46 /* ConfirmPaymentSourceResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmPaymentSourceResponse.swift; sourceTree = ""; }; - 3B109B3A2A85B54800D8135F /* MockCardVaultDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCardVaultDelegate.swift; sourceTree = ""; }; - 3B22E8B52A840ECF00962E34 /* CardVaultDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardVaultDelegate.swift; sourceTree = ""; }; 3B22E8B72A841AEA00962E34 /* CardVaultResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardVaultResult.swift; sourceTree = ""; }; 3B29C3962B9148F70077741D /* PayPalVaultRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalVaultRequest.swift; sourceTree = ""; }; 3B3C511D2B2395B5009125FE /* PayPalVaultResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayPalVaultResult.swift; sourceTree = ""; }; @@ -481,7 +477,6 @@ children = ( CB16E6D7285B7A2B00FD6F52 /* FakeConfirmPaymentResponse.swift */, CB16E6D9285B7B7300FD6F52 /* MockCardDelegate.swift */, - 3B109B3A2A85B54800D8135F /* MockCardVaultDelegate.swift */, 808E3EDC2A981F240017FE46 /* MockCheckoutOrdersAPI.swift */, 808E3EDE2A981F390017FE46 /* MockVaultPaymentTokensAPI.swift */, 3B783DC22B7A69C2004623DB /* FakeUpdateSetupTokenResponse.swift */, @@ -547,7 +542,6 @@ 06CE009A26F3D5A40000CC46 /* CardClient.swift */, 80DCC59D2719DB6F00EC7C5A /* CardClientError.swift */, CB4BE27F2847F01000EA2DD1 /* CardDelegate.swift */, - 3B22E8B52A840ECF00962E34 /* CardVaultDelegate.swift */, 80DBC9D829C336D500462539 /* APIRequests */, 065A4DBD26FCDA270007014A /* Models */, 3BE738622B9A482800598F05 /* PrivacyInfo.xcprivacy */, @@ -1223,7 +1217,6 @@ 3B22E8B82A841AEA00962E34 /* CardVaultResult.swift in Sources */, CBC16DD529E99B4600307117 /* PaymentSource.swift in Sources */, 80DCC59E2719DB6F00EC7C5A /* CardClientError.swift in Sources */, - 3B22E8B62A840ECF00962E34 /* CardVaultDelegate.swift in Sources */, 3BDB34942A80CE6E008100D7 /* CardVaultRequest.swift in Sources */, 80B8B2FC2A8EBBFD00AB60CD /* VaultPaymentTokensAPI.swift in Sources */, CB4BE27D2847AF6F00EA2DD1 /* SCA.swift in Sources */, @@ -1238,7 +1231,6 @@ files = ( 065A4DBF26FCDA5B0007014A /* CardClient_Tests.swift in Sources */, 8008D2052A9E54FF0003CAF4 /* CheckoutOrdersAPI_Tests.swift in Sources */, - 3B109B3C2A85CC6200D8135F /* MockCardVaultDelegate.swift in Sources */, 80B27AF12A9E9EE60008EA45 /* VaultPaymentTokensAPI_Tests.swift in Sources */, CB16E6D8285B7A2B00FD6F52 /* FakeConfirmPaymentResponse.swift in Sources */, CB16E6DA285B7B7300FD6F52 /* MockCardDelegate.swift in Sources */, diff --git a/Sources/CardPayments/CardClient.swift b/Sources/CardPayments/CardClient.swift index 8c77236d4..2b9eea07f 100644 --- a/Sources/CardPayments/CardClient.swift +++ b/Sources/CardPayments/CardClient.swift @@ -7,7 +7,6 @@ import CorePayments public class CardClient: NSObject { public weak var delegate: CardDelegate? - public weak var vaultDelegate: CardVaultDelegate? private let checkoutOrdersAPI: CheckoutOrdersAPI private let vaultAPI: VaultPaymentTokensAPI @@ -43,7 +42,10 @@ public class CardClient: NSObject { /// If `didAttempt3DSecureVerification` is `true`, check verification status with `/v3/vault/setup-token/{id}` in your server. /// - Parameters: /// - vaultRequest: The request containing setupTokenID and card - public func vault(_ vaultRequest: CardVaultRequest) { + /// - completion: A completion block that is invoked when the request is completed. If the request succeeds, + /// a `CardVaultResult` with `setupTokenID` and `status` are returned and `error` will be `nil`; + /// if it fails, `CardVaultResult will be `nil` and `error` will describe the failure + public func vault(_ vaultRequest: CardVaultRequest, completion: @escaping (CardVaultResult?, Error?) -> Void) { analyticsService = AnalyticsService(coreConfig: config, setupToken: vaultRequest.setupTokenID) analyticsService?.sendEvent("card-payments:vault-wo-purchase:started") Task { @@ -53,19 +55,19 @@ public class CardClient: NSObject { if result.status == "PAYER_ACTION_REQUIRED", let urlString = result.links.first(where: { $0.rel == "approve" })?.href { guard urlString.contains("helios"), let url = URL(string: urlString) else { - self.notifyVaultFailure(with: CardClientError.threeDSecureURLError) + self.notifyVaultFailure(with: CardClientError.threeDSecureURLError, completion: completion) return } analyticsService?.sendEvent("card-payments:vault-wo-purchase:challenge-required") - startVaultThreeDSecureChallenge(url: url, setupTokenID: vaultRequest.setupTokenID) + startVaultThreeDSecureChallenge(url: url, setupTokenID: vaultRequest.setupTokenID, completion: completion) } else { let vaultResult = CardVaultResult(setupTokenID: result.id, status: result.status, didAttemptThreeDSecureAuthentication: false) - notifyVaultSuccess(for: vaultResult) + notifyVaultSuccess(for: vaultResult, completion: completion) } } catch let error as CoreSDKError { - notifyVaultFailure(with: error) + notifyVaultFailure(with: error, completion: completion) } catch { - notifyVaultFailure(with: CardClientError.vaultTokenError) + notifyVaultFailure(with: CardClientError.vaultTokenError, completion: completion) } } } @@ -149,8 +151,7 @@ public class CardClient: NSObject { return url.queryItems?.first { $0.name == param }?.value } - private func startVaultThreeDSecureChallenge(url: URL, setupTokenID: String) { - vaultDelegate?.cardThreeDSecureWillLaunch(self) + private func startVaultThreeDSecureChallenge(url: URL, setupTokenID: String, completion: @escaping (CardVaultResult?, Error?) -> Void) { webAuthenticationSession.start( url: url, @@ -164,20 +165,19 @@ public class CardClient: NSObject { } }, sessionDidComplete: { _, error in - self.vaultDelegate?.cardThreeDSecureDidFinish(self) if let error = error { switch error { case ASWebAuthenticationSessionError.canceledLogin: - self.notifyVaultCancellation() + self.notifyVaultFailure(with: CardClientError.threeDSecureCancellation, completion: completion) return default: - self.notifyVaultFailure(with: CardClientError.threeDSecureError(error)) + self.notifyVaultFailure(with: CardClientError.threeDSecureError(error), completion: completion) return } } let cardVaultResult = CardVaultResult(setupTokenID: setupTokenID, status: nil, didAttemptThreeDSecureAuthentication: true) - self.notifyVaultSuccess(for: cardVaultResult) + self.notifyVaultSuccess(for: cardVaultResult, completion: completion) } ) } @@ -192,25 +192,20 @@ public class CardClient: NSObject { delegate?.card(self, didFinishWithError: error) } - private func notifyVaultSuccess(for vaultResult: CardVaultResult) { + private func notifyVaultSuccess(for vaultResult: CardVaultResult, completion: (CardVaultResult?, Error?) -> Void) { analyticsService?.sendEvent("card-payments:vault-wo-purchase:succeeded") - vaultDelegate?.card(self, didFinishWithVaultResult: vaultResult) + completion(vaultResult, nil) } - private func notifyVaultFailure(with vaultError: CoreSDKError) { + private func notifyVaultFailure(with vaultError: CoreSDKError, completion: (CardVaultResult?, Error?) -> Void) { analyticsService?.sendEvent("card-payments:vault-wo-purchase:failed") - vaultDelegate?.card(self, didFinishWithVaultError: vaultError) + completion(nil, vaultError) } private func notifyCancellation() { analyticsService?.sendEvent("card-payments:3ds:challenge:user-canceled") delegate?.cardDidCancel(self) } - - private func notifyVaultCancellation() { - analyticsService?.sendEvent("card-payments:vault-wo-purchase:challenge:canceled") - vaultDelegate?.cardThreeDSecureDidCancel(self) - } } // MARK: - ASWebAuthenticationPresentationContextProviding conformance diff --git a/Sources/CardPayments/CardClientError.swift b/Sources/CardPayments/CardClientError.swift index 3a6522626..d068833b4 100644 --- a/Sources/CardPayments/CardClientError.swift +++ b/Sources/CardPayments/CardClientError.swift @@ -37,6 +37,9 @@ enum CardClientError { /// 9. Malformed Deeplink URL from 3DS case malformedDeeplinkURLError + + /// 10. Cancellation from 3DS verification + case threeDSCancellation } static let unknownError = CoreSDKError( @@ -64,7 +67,13 @@ enum CardClientError { domain: domain, errorDescription: "An invalid 3DS URL was returned. Contact developer.paypal.com/support." ) - + + static let threeDSecureCancellation = CoreSDKError( + code: Code.threeDSCancellation.rawValue, + domain: domain, + errorDescription: "3DS verification has been cancelled by the user." + ) + static let noVaultTokenDataError = CoreSDKError( code: Code.noVaultTokenDataError.rawValue, domain: domain, diff --git a/Sources/CardPayments/CardVaultDelegate.swift b/Sources/CardPayments/CardVaultDelegate.swift deleted file mode 100644 index 4a85cb2aa..000000000 --- a/Sources/CardPayments/CardVaultDelegate.swift +++ /dev/null @@ -1,35 +0,0 @@ -import Foundation -#if canImport(CorePayments) -import CorePayments -#endif - -/// CardVault delegate to handle events from CardClient -public protocol CardVaultDelegate: AnyObject { - - /// Notify that the Card vault flow finished with a successful result - /// - Parameters: - /// - client: the CardClient associated with delegate - /// - didFinishWithResult: the successful result from the flow - func card(_ cardClient: CardClient, didFinishWithVaultResult vaultResult: CardVaultResult) - - /// Notify that an error occurred in the Card vault flow - /// - Parameters: - /// - client: the CardClient associated with delegate - /// - didFinishWithError: the error returned by the Card vault flow - func card(_ cardClient: CardClient, didFinishWithVaultError vaultError: CoreSDKError) - - /// Notify that the ThreeDSecure has been cancelled - /// - Parameters: - /// - client: the CardClient associated with delegate - func cardThreeDSecureDidCancel(_ cardClient: CardClient) - - /// Notify that the 3DS challenge will be launched - /// - Parameters: - /// - client: the CardClient associated with delegate - func cardThreeDSecureWillLaunch(_ cardClient: CardClient) - - /// Notify that the 3DS challenge has finished - /// - Parameters: - /// - client: the CardClient associated with delegate - func cardThreeDSecureDidFinish(_ cardClient: CardClient) -} diff --git a/UnitTests/CardPaymentsTests/CardClient_Tests.swift b/UnitTests/CardPaymentsTests/CardClient_Tests.swift index e97295047..e64715f12 100644 --- a/UnitTests/CardPaymentsTests/CardClient_Tests.swift +++ b/UnitTests/CardPaymentsTests/CardClient_Tests.swift @@ -22,7 +22,6 @@ class CardClient_Tests: XCTestCase { let mockWebAuthSession = MockWebAuthenticationSession() var mockNetworkingClient: MockNetworkingClient! - var mockCardVaultDelegate: MockCardVaultDelegate! var mockCheckoutOrdersAPI: MockCheckoutOrdersAPI! var mockVaultAPI: MockVaultPaymentTokensAPI! @@ -60,18 +59,15 @@ class CardClient_Tests: XCTestCase { mockVaultAPI.stubSetupTokenResponse = updateSetupTokenResponse let expectation = expectation(description: "vault completed") - let cardVaultDelegate = MockCardVaultDelegate(success: {_, result in - XCTAssertEqual(result.setupTokenID, setupTokenID) - XCTAssertEqual(result.status, vaultStatus) - XCTAssertFalse(result.didAttemptThreeDSecureAuthentication) + + sut.vault(vaultRequest) { result, error in + XCTAssertEqual(result?.setupTokenID, setupTokenID) + XCTAssertEqual(result?.status, vaultStatus) + XCTAssertNil(error) expectation.fulfill() - }, error: {_, _ in - XCTFail("Invoked error() callback. Should invoke success().") - }) - sut.vaultDelegate = cardVaultDelegate - sut.vault(vaultRequest) - - waitForExpectations(timeout: 10) + } + + waitForExpectations(timeout: 2, handler: nil) } func testVault_withValid3DSURLResponse_returnsSuccess() { @@ -84,21 +80,23 @@ class CardClient_Tests: XCTestCase { mockVaultAPI.stubSetupTokenResponse = updateSetupTokenResponse let expectation = expectation(description: "vault completed") - let cardVaultDelegate = MockCardVaultDelegate(success: {_, result in - XCTAssertEqual(result.setupTokenID, setupTokenID) - XCTAssertNil(result.status) - XCTAssertTrue(result.didAttemptThreeDSecureAuthentication) + sut.vault(vaultRequest) { result, error in + if let result { + XCTAssertEqual(result.setupTokenID, setupTokenID) + XCTAssertNil(result.status) + XCTAssertTrue(result.didAttemptThreeDSecureAuthentication) + } else { + XCTFail("expected result not to be nil") + } + + XCTAssertNil(error) expectation.fulfill() - }, error: {_, _ in - XCTFail("Invoked error() callback. Should invoke success().") - }) - sut.vaultDelegate = cardVaultDelegate - sut.vault(vaultRequest) + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } - func testVault_withInvalid3DSURLResponse_returnsSuccess() { + func testVault_withInvalid3DSURLResponse_returnsError() { let setupTokenID = "testToken1" let vaultStatus = "PAYER_ACTION_REQUIRED" let vaultRequest = CardVaultRequest(card: card, setupTokenID: setupTokenID) @@ -108,18 +106,20 @@ class CardClient_Tests: XCTestCase { mockVaultAPI.stubSetupTokenResponse = updateSetupTokenResponse let expectation = expectation(description: "vault completed") - let cardVaultDelegate = MockCardVaultDelegate(success: {_, _ in - XCTFail("Invoked success() callback. Should invoke error().") - }, error: {_, error in - XCTAssertEqual(error.code, CardClientError.threeDSecureURLError.code) - XCTAssertEqual(error.domain, CardClientError.domain) - XCTAssertEqual(error.localizedDescription, CardClientError.threeDSecureURLError.localizedDescription) + + sut.vault(vaultRequest) { result, error in + XCTAssertNil(result) + if let error = error as? CoreSDKError { + XCTAssertEqual(error.domain, CardClientError.domain) + XCTAssertEqual(error.code, CardClientError.threeDSecureURLError.code) + XCTAssertEqual(error.localizedDescription, CardClientError.threeDSecureURLError.localizedDescription) + } else { + XCTFail("Expected error to be of type CoreSDKError") + } expectation.fulfill() - }) - sut.vaultDelegate = cardVaultDelegate - sut.vault(vaultRequest) + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } func testVault_whenVaultAPIError_bubblesError() { @@ -129,18 +129,20 @@ class CardClient_Tests: XCTestCase { mockVaultAPI.stubError = CoreSDKError(code: 123, domain: "fake-domain", errorDescription: "api-error") let expectation = expectation(description: "vault completed") - let cardVaultDelegate = MockCardVaultDelegate(success: {_, _ in - XCTFail("Invoked success() callback. Should invoke error().") - }, error: {_, error in - XCTAssertEqual(error.domain, "fake-domain") - XCTAssertEqual(error.code, 123) - XCTAssertEqual(error.localizedDescription, "api-error") + + sut.vault(vaultRequest) { result, error in + XCTAssertNil(result) + if let error = error as? CoreSDKError { + XCTAssertEqual(error.domain, "fake-domain") + XCTAssertEqual(error.code, 123) + XCTAssertEqual(error.localizedDescription, "api-error") + } else { + XCTFail("Expected error to be of type CoreSDKError") + } expectation.fulfill() - }) - sut.vaultDelegate = cardVaultDelegate - sut.vault(vaultRequest) + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } func testVault_whenUnknownError_returnsVaultError() { @@ -150,18 +152,19 @@ class CardClient_Tests: XCTestCase { mockVaultAPI.stubError = NSError(domain: "some-domain", code: 123, userInfo: [NSLocalizedDescriptionKey: "some-description"]) let expectation = expectation(description: "vault completed") - let cardVaultDelegate = MockCardVaultDelegate(success: {_, _ in - XCTFail("Invoked success() callback. Should invoke error().") - }, error: {_, error in - XCTAssertEqual(error.domain, CardClientError.domain) - XCTAssertEqual(error.code, CardClientError.Code.vaultTokenError.rawValue) - XCTAssertEqual(error.localizedDescription, "An error occurred while vaulting a card.") + sut.vault(vaultRequest) { result, error in + XCTAssertNil(result) + if let error = error as? CoreSDKError { + XCTAssertEqual(error.domain, CardClientError.domain) + XCTAssertEqual(error.code, CardClientError.Code.vaultTokenError.rawValue) + XCTAssertEqual(error.localizedDescription, "An error occurred while vaulting a card.") + } else { + XCTFail("Expected error to be of type CoreSDKError") + } expectation.fulfill() - }) - sut.vaultDelegate = cardVaultDelegate - sut.vault(vaultRequest) + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } func test_vault_withThreeDSecure_browserSwitchLaunches_vaultReturnsSuccess() { @@ -171,26 +174,19 @@ class CardClient_Tests: XCTestCase { let expectation = expectation(description: "vault() completed") - let mockCardVaultDelegate = MockCardVaultDelegate( - success: {_, result in + sut.vault(cardVaultRequest) { result, error in + XCTAssertNil(error) + if let result { XCTAssertEqual(result.setupTokenID, "testSetupTokenId") XCTAssertNil(result.status) XCTAssertTrue(result.didAttemptThreeDSecureAuthentication) - expectation.fulfill() - }, - error: { _, error in - XCTFail(error.localizedDescription) - expectation.fulfill() - }, - cancel: { _ in XCTFail("Invoked cancel() callback. Should invoke success().") }, - threeDSWillLaunch: { _ in XCTAssert(true) }, - threeDSLaunched: { _ in XCTAssert(true) } - ) - - sut.vaultDelegate = mockCardVaultDelegate - sut.vault(cardVaultRequest) + } else { + XCTFail("Expected result not to be nil") + } + expectation.fulfill() + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } func testVault_withThreeDSecure_userCancelsBrowser() { @@ -203,27 +199,19 @@ class CardClient_Tests: XCTestCase { let expectation = expectation(description: "vault() completed") - let mockCardVaultDelegate = MockCardVaultDelegate( - success: {_, _ in - XCTFail("Invoked success() callback. Should invoke cancel().") - expectation.fulfill() - }, - error: { _, error in - XCTFail(error.localizedDescription) - expectation.fulfill() - }, - cancel: { _ in - XCTAssert(true) - expectation.fulfill() - }, - threeDSWillLaunch: { _ in XCTAssert(true) }, - threeDSLaunched: { _ in XCTAssert(true) } - ) - - sut.vaultDelegate = mockCardVaultDelegate - sut.vault(cardVaultRequest) + sut.vault(cardVaultRequest) { result, error in + XCTAssertNil(result) + if let error = error as? CoreSDKError { + XCTAssertEqual(error.domain, CardClientError.domain) + XCTAssertEqual(error.code, CardClientError.Code.threeDSCancellation.rawValue) + XCTAssertEqual(error.localizedDescription, CardClientError.threeDSecureCancellation.localizedDescription) + } else { + XCTFail("Expected error to be of type CoreSDKError") + } + expectation.fulfill() + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } func testVault_withThreeDSecure_browserReturnsError() { @@ -237,29 +225,19 @@ class CardClient_Tests: XCTestCase { let expectation = expectation(description: "vault() completed") - let mockCardVaultDelegate = MockCardVaultDelegate( - success: {_, _ in - XCTFail("Invoked success() callback. Should invoke error().") - expectation.fulfill() - }, - error: { _, error in + sut.vault(cardVaultRequest) { result, error in + XCTAssertNil(result) + if let error = error as? CoreSDKError { XCTAssertEqual(error.domain, CardClientError.domain) XCTAssertEqual(error.code, CardClientError.Code.threeDSecureError.rawValue) XCTAssertEqual(error.localizedDescription, "Mock web session error description.") - expectation.fulfill() - }, - cancel: { _ in - XCTFail("Invoked cancel() callback. Should invoke error().") - expectation.fulfill() - }, - threeDSWillLaunch: { _ in XCTAssert(true) }, - threeDSLaunched: { _ in XCTAssert(true) } - ) - - sut.vaultDelegate = mockCardVaultDelegate - sut.vault(cardVaultRequest) + } else { + XCTFail("Expected error to be of type CoreSDKError") + } + expectation.fulfill() + } - waitForExpectations(timeout: 10) + waitForExpectations(timeout: 2, handler: nil) } // MARK: - approveOrder() tests diff --git a/UnitTests/CardPaymentsTests/Mocks/MockCardVaultDelegate.swift b/UnitTests/CardPaymentsTests/Mocks/MockCardVaultDelegate.swift deleted file mode 100644 index a27c8cd20..000000000 --- a/UnitTests/CardPaymentsTests/Mocks/MockCardVaultDelegate.swift +++ /dev/null @@ -1,45 +0,0 @@ -@testable import CorePayments -@testable import CardPayments - -class MockCardVaultDelegate: CardVaultDelegate { - - private var success: ((CardClient, CardVaultResult) -> Void)? - private var failure: ((CardClient, CoreSDKError) -> Void)? - private var cancel: ((CardClient) -> Void)? - private var threeDSWillLaunch: ((CardClient) -> Void)? - private var threeDSLaunched: ((CardClient) -> Void)? - - required init( - success: ((CardClient, CardVaultResult) -> Void)? = nil, - error: ((CardClient, CoreSDKError) -> Void)? = nil, - cancel: ((CardClient) -> Void)? = nil, - threeDSWillLaunch: ((CardClient) -> Void)? = nil, - threeDSLaunched: ((CardClient) -> Void)? = nil - ) { - self.success = success - self.failure = error - self.cancel = cancel - self.threeDSWillLaunch = threeDSWillLaunch - self.threeDSLaunched = threeDSLaunched - } - - func card(_ cardClient: CardClient, didFinishWithVaultResult vaultResult: CardPayments.CardVaultResult) { - success?(cardClient, vaultResult) - } - - func card(_ cardClient: CardClient, didFinishWithVaultError vaultError: CorePayments.CoreSDKError) { - failure?(cardClient, vaultError) - } - - func cardThreeDSecureDidCancel(_ cardClient: CardClient) { - cancel?(cardClient) - } - - func cardThreeDSecureWillLaunch(_ cardClient: CardClient) { - threeDSWillLaunch?(cardClient) - } - - func cardThreeDSecureDidFinish(_ cardClient: CardClient) { - threeDSLaunched?(cardClient) - } -}