Skip to content

Commit

Permalink
card vault Result type
Browse files Browse the repository at this point in the history
  • Loading branch information
KunJeongPark committed Jan 17, 2025
1 parent 64c8728 commit 48b1164
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ class CardVaultViewModel: VaultViewModel {
let config = try await configManager.getCoreConfig()
let cardClient = CardClient(config: config)
let cardVaultRequest = CardVaultRequest(card: card, setupTokenID: setupToken)
cardClient.vault(cardVaultRequest) { result, error in
if let result {
self.setUpdateSetupTokenResult(vaultResult: result, vaultError: nil)
} else if let error {
cardClient.vault(cardVaultRequest) { result in
switch result {
case .success(let cardVaultResult):
self.setUpdateSetupTokenResult(vaultResult: cardVaultResult, vaultError: nil)
case .failure(let error):
self.setUpdateSetupTokenResult(vaultResult: nil, vaultError: error)
}
}
Expand Down
45 changes: 23 additions & 22 deletions Sources/CardPayments/CardClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public class CardClient: NSObject {
/// - Parameters:
/// - vaultRequest: The request containing setupTokenID and card
/// - 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?, CoreSDKError?) -> Void) {
/// a `Result` type with `.success(CardVaultResult)` with `setupTokenID` and `status` are returned;
/// if it fails, `Result` type with `.failure(CoreSDKError)` that describes the failure will be returned
public func vault(_ vaultRequest: CardVaultRequest, completion: @escaping (Result<CardVaultResult, CoreSDKError>) -> Void) {
analyticsService = AnalyticsService(coreConfig: config, setupToken: vaultRequest.setupTokenID)
analyticsService?.sendEvent("card-payments:vault-wo-purchase:started")
Task {
Expand Down Expand Up @@ -79,11 +79,12 @@ public class CardClient: NSObject {
/// - Throws: A `CoreSDKError` describing failure
public func vault(_ vaultRequest: CardVaultRequest) async throws -> CardVaultResult {
try await withCheckedThrowingContinuation { continuation in
vault(vaultRequest) { result, error in
if let error {
vault(vaultRequest) { result in
switch result {
case .success(let cardVaultResult):
continuation.resume(returning: cardVaultResult)
case .failure(let error):
continuation.resume(throwing: error)
} else if let result {
continuation.resume(returning: result)
}
}
}
Expand All @@ -95,8 +96,8 @@ public class CardClient: NSObject {
/// - orderId: Order id for approval
/// - request: The request containing the card
/// - completion: A completion block that is invoked when the request is completed. If the request succeeds,
/// a `CardResult` with `orderID` , `status` and `didAttemptThreeDSecureAuthentication` are returned and `error` will be `nil`;
/// if it fails, `CardResult will be `nil` and `error` will describe the failure
/// a `Result` type will be returned with `.success(CardResult)` with `orderID` , `status` and `didAttemptThreeDSecureAuthentication`;
/// if it fails, `Result` type with `.failure(CoreSDKError)` that describes the failure will be returned
public func approveOrder(request: CardRequest, completion: @escaping (Result<CardResult, CoreSDKError>) -> Void) {
analyticsService = AnalyticsService(coreConfig: config, orderID: request.orderID)
analyticsService?.sendEvent("card-payments:approve-order:started")
Expand Down Expand Up @@ -138,10 +139,10 @@ public class CardClient: NSObject {
try await withCheckedThrowingContinuation { continuation in
approveOrder(request: request) { result in
switch result {
case .failure(let error):
continuation.resume(throwing: error)
case .success(let cardResult):
continuation.resume(returning: cardResult)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
Expand Down Expand Up @@ -189,7 +190,7 @@ public class CardClient: NSObject {
private func startVaultThreeDSecureChallenge(
url: URL,
setupTokenID: String,
completion: @escaping (CardVaultResult?, CoreSDKError?) -> Void
completion: @escaping (Result<CardVaultResult, CoreSDKError>) -> Void
) {

webAuthenticationSession.start(
Expand Down Expand Up @@ -246,29 +247,29 @@ public class CardClient: NSObject {
completion(.failure(error))
}

private func notifyVaultSuccess(for vaultResult: CardVaultResult, completion: (CardVaultResult?, CoreSDKError?) -> Void) {
private func notifyVaultSuccess(for vaultResult: CardVaultResult, completion: (Result<CardVaultResult, CoreSDKError>) -> Void) {
analyticsService?.sendEvent("card-payments:vault-wo-purchase:succeeded")
completion(vaultResult, nil)
completion(.success(vaultResult))
}

private func notify3dsVaultSuccess(for vaultResult: CardVaultResult, completion: (CardVaultResult?, CoreSDKError?) -> Void) {
private func notify3dsVaultSuccess(for vaultResult: CardVaultResult, completion: (Result<CardVaultResult, CoreSDKError>) -> Void) {
analyticsService?.sendEvent("card-payments:vault-wo-purchase:auth-challenge:succeeded")
completion(vaultResult, nil)
completion(.success(vaultResult))
}

private func notifyVaultFailure(with vaultError: CoreSDKError, completion: (CardVaultResult?, CoreSDKError?) -> Void) {
private func notifyVaultFailure(with vaultError: CoreSDKError, completion: (Result<CardVaultResult, CoreSDKError>) -> Void) {
analyticsService?.sendEvent("card-payments:vault-wo-purchase:failed")
completion(nil, vaultError)
completion(.failure(vaultError))
}

private func notify3dsVaultFailure(with vaultError: CoreSDKError, completion: (CardVaultResult?, CoreSDKError?) -> Void) {
private func notify3dsVaultFailure(with vaultError: CoreSDKError, completion: (Result<CardVaultResult, CoreSDKError>) -> Void) {
analyticsService?.sendEvent("card-payments:vault-wo-purchase:auth-challenge:failed")
completion(nil, vaultError)
completion(.failure(vaultError))
}

private func notify3dsVaultCancelWithError(with vaultError: CoreSDKError, completion: (CardVaultResult?, CoreSDKError?) -> Void) {
private func notify3dsVaultCancelWithError(with vaultError: CoreSDKError, completion: (Result<CardVaultResult, CoreSDKError>) -> Void) {
analyticsService?.sendEvent("card-payments:vault-wo-purchase:auth-challenge:canceled")
completion(nil, vaultError)
completion(.failure(vaultError))
}
}

Expand Down
98 changes: 50 additions & 48 deletions UnitTests/CardPaymentsTests/CardClient_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,16 @@ class CardClient_Tests: XCTestCase {

let expectation = expectation(description: "vault completed")

sut.vault(vaultRequest) { result, error in
XCTAssertEqual(result?.setupTokenID, setupTokenID)
XCTAssertEqual(result?.status, vaultStatus)
XCTAssertNil(error)
sut.vault(vaultRequest) { result in
switch result {
case .success(let cardVaultResult):
XCTAssertEqual(cardVaultResult.setupTokenID, setupTokenID)
XCTAssertEqual(cardVaultResult.status, vaultStatus)
case .failure:
XCTFail("Expected success with CardVaultResult")
}
expectation.fulfill()
}

waitForExpectations(timeout: 2, handler: nil)
}

Expand All @@ -81,16 +84,15 @@ class CardClient_Tests: XCTestCase {
mockVaultAPI.stubSetupTokenResponse = updateSetupTokenResponse

let expectation = expectation(description: "vault completed")
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")
sut.vault(vaultRequest) { result in
switch result {
case .success(let cardVaultResult):
XCTAssertEqual(cardVaultResult.setupTokenID, setupTokenID)
XCTAssertNil(cardVaultResult.status)
XCTAssertTrue(cardVaultResult.didAttemptThreeDSecureAuthentication)
case .failure:
XCTFail("Expected success with CardVaultResult")
}

XCTAssertNil(error)
expectation.fulfill()
}

Expand All @@ -108,14 +110,14 @@ class CardClient_Tests: XCTestCase {

let expectation = expectation(description: "vault completed")

sut.vault(vaultRequest) { result, error in
XCTAssertNil(result)
if let error {
sut.vault(vaultRequest) { result in
switch result {
case .success:
XCTFail("Expected failure with error")
case .failure(let error):
XCTAssertEqual(error.domain, CardError.domain)
XCTAssertEqual(error.code, CardError.threeDSecureURLError.code)
XCTAssertEqual(error.localizedDescription, CardError.threeDSecureURLError.localizedDescription)
} else {
XCTFail("Expected error not to be nil")
}
expectation.fulfill()
}
Expand All @@ -126,19 +128,19 @@ class CardClient_Tests: XCTestCase {
func testVault_whenVaultAPIError_bubblesError() {
let setupTokenID = "testToken1"
let vaultRequest = CardVaultRequest(card: card, setupTokenID: setupTokenID)

mockVaultAPI.stubError = CoreSDKError(code: 123, domain: "fake-domain", errorDescription: "api-error")

let expectation = expectation(description: "vault completed")

sut.vault(vaultRequest) { result, error in
XCTAssertNil(result)
if let error {
sut.vault(vaultRequest) { result in
switch result {
case .success:
XCTFail("Expected failure with error")
case .failure(let error):
XCTAssertEqual(error.domain, "fake-domain")
XCTAssertEqual(error.code, 123)
XCTAssertEqual(error.localizedDescription, "api-error")
} else {
XCTFail("Expected error not to be nil")
}
expectation.fulfill()
}
Expand All @@ -153,14 +155,14 @@ class CardClient_Tests: XCTestCase {
mockVaultAPI.stubError = NSError(domain: "some-domain", code: 123, userInfo: [NSLocalizedDescriptionKey: "some-description"])

let expectation = expectation(description: "vault completed")
sut.vault(vaultRequest) { result, error in
XCTAssertNil(result)
if let error {
sut.vault(vaultRequest) { result in
switch result {
case .success:
XCTFail("Expected failure with error")
case .failure(let error):
XCTAssertEqual(error.domain, CardError.domain)
XCTAssertEqual(error.code, CardError.Code.vaultTokenError.rawValue)
XCTAssertEqual(error.localizedDescription, "An error occurred while vaulting a card.")
} else {
XCTFail("Expected error not to be nil")
}
expectation.fulfill()
}
Expand All @@ -175,14 +177,14 @@ class CardClient_Tests: XCTestCase {

let expectation = expectation(description: "vault() completed")

sut.vault(cardVaultRequest) { result, error in
XCTAssertNil(error)
if let result {
XCTAssertEqual(result.setupTokenID, "testSetupTokenId")
XCTAssertNil(result.status)
XCTAssertTrue(result.didAttemptThreeDSecureAuthentication)
} else {
XCTFail("Expected result not to be nil")
sut.vault(cardVaultRequest) { result in
switch result {
case .success(let cardVaultResult):
XCTAssertEqual(cardVaultResult.setupTokenID, "testSetupTokenId")
XCTAssertNil(cardVaultResult.status)
XCTAssertTrue(cardVaultResult.didAttemptThreeDSecureAuthentication)
case .failure:
XCTFail("Expected success with CardVaultResult")
}
expectation.fulfill()
}
Expand All @@ -200,14 +202,14 @@ class CardClient_Tests: XCTestCase {

let expectation = expectation(description: "vault() completed")

sut.vault(cardVaultRequest) { result, error in
XCTAssertNil(result)
if let error {
sut.vault(cardVaultRequest) { result in
switch result {
case .success:
XCTFail("Expected failure with error")
case .failure(let error):
XCTAssertEqual(error.domain, CardError.domain)
XCTAssertEqual(error.code, CardError.Code.threeDSecureCanceledError.rawValue)
XCTAssertEqual(error.localizedDescription, CardError.threeDSecureCanceledError.localizedDescription)
} else {
XCTFail("Expected error not to be nil")
}
expectation.fulfill()
}
Expand All @@ -226,14 +228,14 @@ class CardClient_Tests: XCTestCase {

let expectation = expectation(description: "vault() completed")

sut.vault(cardVaultRequest) { result, error in
XCTAssertNil(result)
if let error {
sut.vault(cardVaultRequest) { result in
switch result {
case .success:
XCTFail("Expected failure with error")
case .failure(let error):
XCTAssertEqual(error.domain, CardError.domain)
XCTAssertEqual(error.code, CardError.Code.threeDSecureError.rawValue)
XCTAssertEqual(error.localizedDescription, "Mock web session error description.")
} else {
XCTFail("Expected error not to be nil")
}
expectation.fulfill()
}
Expand Down

0 comments on commit 48b1164

Please sign in to comment.