Skip to content

Commit

Permalink
Improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
robertdalmeida committed Feb 25, 2025
1 parent 92ba243 commit e62b678
Show file tree
Hide file tree
Showing 8 changed files with 418 additions and 30 deletions.
16 changes: 16 additions & 0 deletions Adyen.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
21C711152D67FE9A00A08111 /* FingerprintServiceParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C711142D67FE9A00A08111 /* FingerprintServiceParameters.swift */; };
21C711172D67FEA600A08111 /* ChallengeParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C711162D67FEA600A08111 /* ChallengeParameters.swift */; };
21C711192D67FEBE00A08111 /* UnknownError+ThreeDSServiceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C711182D67FEBE00A08111 /* UnknownError+ThreeDSServiceable.swift */; };
21C7111C2D6D36B100A08111 /* ThreeDS2ServiceLegacyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C7111B2D6D36A400A08111 /* ThreeDS2ServiceLegacyTests.swift */; };
21C7111E2D6D386F00A08111 /* ADYServiceAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C7111D2D6D386F00A08111 /* ADYServiceAdapter.swift */; };
21C711202D6D388700A08111 /* AnyADYTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C7111F2D6D388700A08111 /* AnyADYTransaction.swift */; };
21C711242D6D3B2500A08111 /* ThreeDSServiceableMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C711232D6D3B2100A08111 /* ThreeDSServiceableMock.swift */; };
5A1315C926296B100092366D /* ProgressViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A1315C826296B100092366D /* ProgressViewStyle.swift */; };
5A15D589264BB0BD00A8E3C7 /* BoletoComponentExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A15D588264BB0BD00A8E3C7 /* BoletoComponentExtensions.swift */; };
5A15D5A1264BE1E500A8E3C7 /* PrefilledShopperInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A15D5A0264BE1E500A8E3C7 /* PrefilledShopperInformation.swift */; };
Expand Down Expand Up @@ -1586,6 +1590,10 @@
21C711142D67FE9A00A08111 /* FingerprintServiceParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FingerprintServiceParameters.swift; sourceTree = "<group>"; };
21C711162D67FEA600A08111 /* ChallengeParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeParameters.swift; sourceTree = "<group>"; };
21C711182D67FEBE00A08111 /* UnknownError+ThreeDSServiceable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UnknownError+ThreeDSServiceable.swift"; sourceTree = "<group>"; };
21C7111B2D6D36A400A08111 /* ThreeDS2ServiceLegacyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeDS2ServiceLegacyTests.swift; sourceTree = "<group>"; };
21C7111D2D6D386F00A08111 /* ADYServiceAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADYServiceAdapter.swift; sourceTree = "<group>"; };
21C7111F2D6D388700A08111 /* AnyADYTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyADYTransaction.swift; sourceTree = "<group>"; };
21C711232D6D3B2100A08111 /* ThreeDSServiceableMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeDSServiceableMock.swift; sourceTree = "<group>"; };
5A1315C826296B100092366D /* ProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressViewStyle.swift; sourceTree = "<group>"; };
5A15D588264BB0BD00A8E3C7 /* BoletoComponentExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoletoComponentExtensions.swift; sourceTree = "<group>"; };
5A15D5A0264BE1E500A8E3C7 /* PrefilledShopperInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefilledShopperInformation.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2929,6 +2937,8 @@
isa = PBXGroup;
children = (
21C7110C2D67F86700A08111 /* ThreeDSServiceLegacy.swift */,
21C7111F2D6D388700A08111 /* AnyADYTransaction.swift */,
21C7111D2D6D386F00A08111 /* ADYServiceAdapter.swift */,
);
path = LegacySDK;
sourceTree = "<group>";
Expand Down Expand Up @@ -5183,12 +5193,14 @@
F957AA432552C3A90099AD73 /* 3DS2 Component */ = {
isa = PBXGroup;
children = (
21C7111B2D6D36A400A08111 /* ThreeDS2ServiceLegacyTests.swift */,
F957AA442552C3BB0099AD73 /* 3DS2 Fingerprint Submitter */,
F957AA592552D8BB0099AD73 /* ThreeDS2ComponentTests.swift */,
F957AAA52552FDC10099AD73 /* ThreeDS2CompactActionHandlerTests.swift */,
F9842CCF25710BF00063CE5A /* ThreeDS2ClassicActionHandlerTests.swift */,
F9E4725E28CF1A2100FF9550 /* ThreeDS2PlusDACoreActionHandlerTests.swift */,
8149CCB52B0B855F007235E2 /* ThreeDS2PlusDACoreActionHandlerTests+Constants.swift */,
21C711232D6D3B2100A08111 /* ThreeDSServiceableMock.swift */,
F957AAAD2552FDD70099AD73 /* AnyADYServiceMock.swift */,
F957AA712552DBC80099AD73 /* AnyRedirectComponentMock.swift */,
F957AA612552D8D20099AD73 /* AnyThreeDS2ActionHandlerMock.swift */,
Expand Down Expand Up @@ -7173,6 +7185,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
21C711242D6D3B2500A08111 /* ThreeDSServiceableMock.swift in Sources */,
F9B8AF6027DB4E8700DC0894 /* ActionHandlingComponentMock.swift in Sources */,
00EACBC0287EF1D50082B360 /* OnlineBankingComponentTests.swift in Sources */,
F9AC61C0243750D80062A00D /* AppLauncherMock.swift in Sources */,
Expand Down Expand Up @@ -7211,6 +7224,7 @@
F9CA6BC627D7503200D7BE6E /* SessionTests.swift in Sources */,
E79A64812490D98F00368E9F /* CardComponentDelegateMock.swift in Sources */,
E2B317AC22660FB600C1BB30 /* FormCardNumberItemTests.swift in Sources */,
21C7111C2D6D36B100A08111 /* ThreeDS2ServiceLegacyTests.swift in Sources */,
F9EDB794239663C200CFB3C9 /* PaymentMethodMock.swift in Sources */,
E9E3DAC8221EDDAF00697074 /* CardNumbers.swift in Sources */,
E9E3DACF221EEB5300697074 /* CardSecurityCodeValidatorTests.swift in Sources */,
Expand Down Expand Up @@ -7619,6 +7633,7 @@
21B3A71929CA780200F48386 /* DelegatedAuthenticationComponentStyle.swift in Sources */,
F97C850125C17CCD00D7F85C /* VoucherShareableViewProvider.swift in Sources */,
F9175FB42594996000D653BE /* ThreeDS2FingerprintAction.swift in Sources */,
21C7111E2D6D386F00A08111 /* ADYServiceAdapter.swift in Sources */,
21B387BD2C408CA90029101E /* UIImageViewHelper.swift in Sources */,
5A22C2AD262EF99C00F12D97 /* ExpirationTimer.swift in Sources */,
8109FF4C2AD5AD0C000748C8 /* OpenExternalAppDetector+DependencyKey.swift in Sources */,
Expand Down Expand Up @@ -7662,6 +7677,7 @@
F917613825A30B5700D653BE /* ThreeDS2ComponentFingerprint.swift in Sources */,
F970143925D139BE007E74D9 /* VoucherComponentStyle.swift in Sources */,
F917613925A30B5700D653BE /* ThreeDS2ComponentFingerprintToken.swift in Sources */,
21C711202D6D388700A08111 /* AnyADYTransaction.swift in Sources */,
5A2D1951267368580082BCE9 /* ActionComponentStyle.swift in Sources */,
0042EBB22B750B4E001B1F6C /* TwintSDKAction.swift in Sources */,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright (c) 2025 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Adyen3DS2
import Foundation
@_spi(AdyenInternal) import Adyen

internal protocol AnyADYService {
func service(
with parameters: ADYServiceParameters,
appearanceConfiguration: ADYAppearanceConfiguration,
completionHandler: @escaping (_ service: AnyADYService) -> Void
)

func transaction(withMessageVersion: String) throws -> AnyADYTransaction
}

internal final class ADYServiceAdapter: AnyADYService {

private var service: ADYService?

internal func service(
with parameters: ADYServiceParameters,
appearanceConfiguration: ADYAppearanceConfiguration,
completionHandler: @escaping (AnyADYService) -> Void
) {
ADYService.service(with: parameters, appearanceConfiguration: appearanceConfiguration) { [weak self] service in
guard let self else { return }
self.service = service
completionHandler(self)
}
}

internal func transaction(withMessageVersion: String) throws -> AnyADYTransaction {
guard let service else {
throw UnknownError.serviceIsNil
}
return try service.transaction(withMessageVersion: withMessageVersion)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Copyright (c) 2025 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Adyen3DS2
import Foundation

internal protocol AnyADYTransaction {

var authenticationParameters: AnyAuthenticationRequestParameters { get }

func performChallenge(with parameters: ADYChallengeParameters, completionHandler: @escaping (AnyChallengeResult?, Error?) -> Void)
}

extension ADYTransaction: AnyADYTransaction {

internal var authenticationParameters: AnyAuthenticationRequestParameters { authenticationRequestParameters }

internal func performChallenge(
with parameters: ADYChallengeParameters,
completionHandler: @escaping (AnyChallengeResult?, Error?) -> Void
) {
performChallenge(
with: parameters,
completionHandler: { (result: ADYChallengeResult?, error: Error?) in
completionHandler(result, error)
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@ import Foundation
/// This translates simple non specific sdk bound types such as
/// `FingerprintServiceParameters` & `ChallengeParameters` to sdk specific types and performs actions.
internal final class ThreeDSServiceLegacy: ThreeDSServiceable {
private var service: Adyen3DS2.ADYService?
private var transaction: Adyen3DS2.ADYTransaction?

private var service: AnyADYService
private var transaction: AnyADYTransaction?

internal init(
service: AnyADYService = ADYServiceAdapter()
) {
self.service = service
}

internal func performFingerprint(
parameters: FingerprintServiceParameters,
completionHandler: @escaping (Result<AnyAuthenticationRequestParameters, ThreeDSServiceFingerprintError>) -> Void
Expand All @@ -24,16 +30,15 @@ internal final class ThreeDSServiceLegacy: ThreeDSServiceable {
directoryServerPublicKey: parameters.directoryServerPublicKey,
directoryServerRootCertificates: parameters.directoryServerRootCertificates
)
ADYService.service(
service.service(
with: serviceParameters,
appearanceConfiguration: parameters.appearanceConfiguration
) { [weak self] service in
guard let self else { return }
self.service = service
do {
let transaction = try service.transaction(withMessageVersion: parameters.threeDSMessageVersion)
self.transaction = transaction
completionHandler(.success(transaction.authenticationRequestParameters))
completionHandler(.success(transaction.authenticationParameters))

} catch {
completionHandler(
Expand Down Expand Up @@ -100,7 +105,6 @@ internal final class ThreeDSServiceLegacy: ThreeDSServiceable {
}

internal func resetTransaction() {
self.service = nil
self.transaction = nil
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@

extension UnknownError {
internal static let transactionNotInitialized = UnknownError(errorDescription: "Transaction not initialized")
internal static let serviceIsNil = UnknownError(errorDescription: "ADYService is nil.")
internal static let resultAndErrorAreNil = UnknownError(errorDescription: "Both error and result are nil, this should never happen.")
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,31 @@ import Adyen3DS2
@_spi(AdyenInternal) @testable import AdyenActions
import Foundation

final class ThreeDSServiceableMock: ThreeDSServiceable {
func resetTransaction() {}

typealias FingerprintResult = Result<any AnyAuthenticationRequestParameters, ThreeDSServiceFingerprintError>
var onPerformFingerprint: ((FingerprintServiceParameters, (FingerprintResult) -> Void) -> Void)?

func performFingerprint(
parameters: FingerprintServiceParameters,
completionHandler: @escaping (FingerprintResult) -> Void
) {
guard let onPerformFingerprint else {
fatalError("Need to provide a mock data if you are using this mock.")
final class AnyADYServiceMock: AnyADYService {
var onService: ((ADYServiceParameters, ADYAppearanceConfiguration, (AnyADYService) -> Void) -> Void)?

func service(with parameters: ADYServiceParameters, appearanceConfiguration: ADYAppearanceConfiguration, completionHandler: @escaping (AnyADYService) -> Void) {
if let onService {
return onService(parameters, appearanceConfiguration, completionHandler)
} else {
completionHandler(self)
}
onPerformFingerprint(parameters, completionHandler)
}

typealias ChallengeResult = Result<any AnyChallengeResult, ThreeDSServiceChallengeError>
var onPerformChallenge: ((ChallengeParameters, (ChallengeResult) -> Void) -> Void)?

func performChallenge(
with parameters: ChallengeParameters,
completionHandler: @escaping (ChallengeResult) -> Void
) {
guard let onPerformChallenge else {
fatalError("Need to provide a mock data if you are using this mock.")
var authenticationRequestParameters: AnyAuthenticationRequestParameters?

var mockedTransaction: AnyADYTransaction?
var onTransaction: ((String) throws -> AnyADYTransaction)?
func transaction(withMessageVersion: String) throws -> AnyADYTransaction {
if let onTransaction {
return try onTransaction(withMessageVersion)
} else if let mockedTransaction {
return mockedTransaction
} else if let parameters = authenticationRequestParameters {
return AnyADYTransactionMock(parameters: parameters)
} else {
fatalError()
}
onPerformChallenge(parameters, completionHandler)
}
}

Expand All @@ -59,3 +57,19 @@ internal struct AnyChallengeResultMock: AnyChallengeResult {

var transactionStatus: String
}

final class AnyADYTransactionMock: AnyADYTransaction {

let authenticationParameters: AnyAuthenticationRequestParameters

init(parameters: AnyAuthenticationRequestParameters) {
self.authenticationParameters = parameters
}

var onPerformChallenge: ((ADYChallengeParameters, (AnyChallengeResult?, Error?) -> Void) -> Void)?

func performChallenge(with parameters: ADYChallengeParameters, completionHandler: @escaping (AnyChallengeResult?, Error?) -> Void) {
onPerformChallenge?(parameters, completionHandler)
}

}
Loading

0 comments on commit e62b678

Please sign in to comment.