Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Adding tests for didCancel #1409

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Adyen.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@
81A48DBB2A5709F600242341 /* AddressLookupProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A48DBA2A5709F600242341 /* AddressLookupProvider.swift */; };
81A48DBC2A5709F600242341 /* AddressLookupProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A48DBA2A5709F600242341 /* AddressLookupProvider.swift */; };
81A48DC62A5800EA00242341 /* AddressLookupViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A48DC32A58004A00242341 /* AddressLookupViewControllerTests.swift */; };
81A6B4E32AD53E3300A089A1 /* OpenExternalAppDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A6B4E22AD53E3300A089A1 /* OpenExternalAppDetector.swift */; };
81A6B4E72AD54F6C00A089A1 /* OpenExternalAppDetector+Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A6B4E52AD54F4F00A089A1 /* OpenExternalAppDetector+Mock.swift */; };
81B001B12A543CFD0015BFA3 /* SearchViewController+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81B001B02A543CFD0015BFA3 /* SearchViewController+ViewModel.swift */; };
81B001B62A5470950015BFA3 /* AddressLookupViewController+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81B001B52A5470950015BFA3 /* AddressLookupViewController+ViewModel.swift */; };
81B001B72A5470EA0015BFA3 /* AddressLookupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81B001B22A5468220015BFA3 /* AddressLookupViewController.swift */; };
Expand Down Expand Up @@ -1350,6 +1352,8 @@
81A2E3BF2A5C453F00CF5F9C /* LinkTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkTextView.swift; sourceTree = "<group>"; };
81A48DBA2A5709F600242341 /* AddressLookupProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressLookupProvider.swift; sourceTree = "<group>"; };
81A48DC32A58004A00242341 /* AddressLookupViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressLookupViewControllerTests.swift; sourceTree = "<group>"; };
81A6B4E22AD53E3300A089A1 /* OpenExternalAppDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenExternalAppDetector.swift; sourceTree = "<group>"; };
81A6B4E52AD54F4F00A089A1 /* OpenExternalAppDetector+Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenExternalAppDetector+Mock.swift"; sourceTree = "<group>"; };
81B001B02A543CFD0015BFA3 /* SearchViewController+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewController+ViewModel.swift"; sourceTree = "<group>"; };
81B001B22A5468220015BFA3 /* AddressLookupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressLookupViewController.swift; sourceTree = "<group>"; };
81B001B52A5470950015BFA3 /* AddressLookupViewController+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AddressLookupViewController+ViewModel.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3937,6 +3941,7 @@
E7E8343A24F3C7ED00EC3844 /* Mocks */ = {
isa = PBXGroup;
children = (
81A6B4E52AD54F4F00A089A1 /* OpenExternalAppDetector+Mock.swift */,
E7E8343B24F3C81700EC3844 /* PublicKeyProviderMock.swift */,
E79A64802490D98F00368E9F /* CardComponentDelegateMock.swift */,
E773EA3B2523432B00119499 /* CardTypeProviderMock.swift */,
Expand Down Expand Up @@ -4048,6 +4053,7 @@
isa = PBXGroup;
children = (
E73C54E325EBD2DC00B57758 /* BrowserComponent.swift */,
81A6B4E22AD53E3300A089A1 /* OpenExternalAppDetector.swift */,
F9780B6424338DFE00CC6C73 /* RedirectComponent.swift */,
E9AFF882224CF959005A0D8D /* RedirectListener.swift */,
E9AFF884224D0D3B005A0D8D /* RedirectDetails.swift */,
Expand Down Expand Up @@ -6676,6 +6682,7 @@
E9E3DAD3221EEFF700697074 /* CardExpiryDateValidatorTests.swift in Sources */,
E7D5311C2447065B000046B4 /* PreselectedPaymentComponentTests.swift in Sources */,
81DC5A512A73C52500DBF2D1 /* AdyenContextTests.swift in Sources */,
81A6B4E72AD54F6C00A089A1 /* OpenExternalAppDetector+Mock.swift in Sources */,
81BBB34F2A694C9300AF1F9E /* FormPickerItemTests.swift in Sources */,
F99F08662383F2D300EBB948 /* FormTextItemViewDelegateMock.swift in Sources */,
F926D55523FBF1A800D058D3 /* QiwiWalletComponentTests.swift in Sources */,
Expand Down Expand Up @@ -6866,6 +6873,7 @@
buildActionMask = 2147483647;
files = (
F9175FD02594999600D653BE /* RedirectDetails.swift in Sources */,
81A6B4E32AD53E3300A089A1 /* OpenExternalAppDetector.swift in Sources */,
F9B018B8260A2DB2001F23FC /* EContextATMVoucherAction.swift in Sources */,
F97842D526C2746500677458 /* OXXOVoucherAction.swift in Sources */,
F917613625A30B5700D653BE /* ThreeDS2ComponentChallengeToken.swift in Sources */,
Expand Down
10 changes: 8 additions & 2 deletions AdyenActions/AdyenActionComponent.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Adyen N.V.
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand All @@ -24,6 +24,8 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen
/// The object that acts as the delegate of the action component.
public weak var delegate: ActionComponentDelegate?

public var openAppDetector: OpenExternalAppDetector

/// The object that acts as the presentation delegate of the action component.
public weak var presentationDelegate: PresentationDelegate?

Expand Down Expand Up @@ -88,9 +90,11 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen
/// - context: The context object.
/// - configuration: The configuration.
public init(context: AdyenContext,
configuration: Configuration = Configuration()) {
configuration: Configuration = Configuration(),
openAppDetector: OpenExternalAppDetector) {
self.context = context
self.configuration = configuration
self.openAppDetector = openAppDetector
}

// MARK: - Performing Actions
Expand Down Expand Up @@ -129,6 +133,7 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen
component.delegate = delegate
component._isDropIn = _isDropIn
component.presentationDelegate = presentationDelegate
component.openAppDetector = openAppDetector
currentActionComponent = component

component.handle(action)
Expand Down Expand Up @@ -157,6 +162,7 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen
component._isDropIn = _isDropIn
component.delegate = delegate
component.presentationDelegate = presentationDelegate
component.openAppDetector = openAppDetector

return component
}
Expand Down
5 changes: 4 additions & 1 deletion AdyenActions/Components/3DS2/ThreeDS2Component.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Adyen N.V.
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand All @@ -21,6 +21,8 @@ public final class ThreeDS2Component: ActionComponent {

/// The delegate of the component.
public weak var delegate: ActionComponentDelegate?

public var openAppDetector: OpenExternalAppDetector = .live

/// Delegates `PresentableComponent`'s presentation.
public weak var presentationDelegate: PresentationDelegate?
Expand Down Expand Up @@ -233,6 +235,7 @@ public final class ThreeDS2Component: ActionComponent {
component.delegate = self
component._isDropIn = _isDropIn
component.presentationDelegate = presentationDelegate
component.openAppDetector = openAppDetector

return component
}()
Expand Down
13 changes: 7 additions & 6 deletions AdyenActions/Components/Redirect/BrowserComponent.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Adyen N.V.
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand Down Expand Up @@ -40,6 +40,8 @@ internal final class BrowserComponent: NSObject, PresentableComponent {

internal weak var delegate: BrowserComponentDelegate?

internal var openAppDetector: OpenExternalAppDetector = .live

/// Initializes the component.
///
/// - Parameter url: The URL to where the user should be redirected
Expand All @@ -58,11 +60,11 @@ internal final class BrowserComponent: NSObject, PresentableComponent {
/// - SFSafariViewController deliberately closed by user and current app still in foreground;
/// - SFSafariViewController finished due to a successful redirect to an external app and current app no longer in foreground.
private func finish() {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
if UIApplication.shared.applicationState == .active {
self.delegate?.didCancel()
} else {
openAppDetector.didOpenExternalApp { didOpenExternalApp in
if didOpenExternalApp {
self.delegate?.didOpenExternalApplication()
} else {
self.delegate?.didCancel()
}
}
}
Expand All @@ -87,5 +89,4 @@ extension BrowserComponent: SFSafariViewControllerDelegate, UIAdaptivePresentati
internal func safariViewControllerWillOpenInBrowser(_ controller: SFSafariViewController) {
self.delegate?.didOpenExternalApplication()
}

}
37 changes: 37 additions & 0 deletions AdyenActions/Components/Redirect/OpenExternalAppDetector.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import UIKit

/// Detects if an external app was opened
public struct OpenExternalAppDetector {
/// Calls a completion handler indicating whether or not an external app was opened
internal var didOpenExternalApp: (_ completion: @escaping (_ didOpenExternalApp: Bool) -> Void) -> Void
}

public extension OpenExternalAppDetector {
static var live: Self {
.init { completion in
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
completion(!UIApplication.shared.applicationState.isInForeground)
}
}
}
}

// MARK: - Convenience

private extension UIApplication.State {

/// Whether or not the application is currently in foreground (`.active` or `.inactive`)
var isInForeground: Bool {
switch self {
case .active, .inactive: return true
case .background: return false
@unknown default: return false
}
}
}
5 changes: 4 additions & 1 deletion AdyenActions/Components/Redirect/RedirectComponent.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Adyen N.V.
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
Expand Down Expand Up @@ -58,6 +58,8 @@ public final class RedirectComponent: ActionComponent {
/// Delegates `PresentableComponent`'s presentation.
public weak var presentationDelegate: PresentationDelegate?

internal var openAppDetector: OpenExternalAppDetector = .live

internal var appLauncher: AnyAppLauncher = AppLauncher()

internal lazy var apiClient: AnyRetryAPIClient = {
Expand Down Expand Up @@ -136,6 +138,7 @@ public final class RedirectComponent: ActionComponent {
context: context,
style: configuration.style)
component.delegate = self
component.openAppDetector = openAppDetector
browserComponent = component
presentationDelegate?.present(component: component)
}
Expand Down
7 changes: 6 additions & 1 deletion AdyenDropIn/DropInComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public final class DropInComponent: NSObject,
/// The partial payment flow delegate.
public weak var partialPaymentDelegate: PartialPaymentDelegate?

public var openAppDetector: OpenExternalAppDetector = .live

/// The stored payment methods delegate.
public weak var storedPaymentMethodsDelegate: StoredPaymentMethodsDelegate?

Expand Down Expand Up @@ -176,7 +178,10 @@ public final class DropInComponent: NSObject,
)

private lazy var actionComponent: AdyenActionComponent = {
let handler = AdyenActionComponent(context: context)
let handler = AdyenActionComponent(
context: context,
openAppDetector: openAppDetector
)
handler.configuration.style = configuration.style.actionComponent
handler._isDropIn = true
handler.delegate = self
Expand Down
14 changes: 11 additions & 3 deletions AdyenSession/AdyenSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public final class AdyenSession {
/// The session context information.
public internal(set) var sessionContext: Context

public private(set) var openAppDetector: OpenExternalAppDetector

/// The presentation delegate.
public private(set) weak var presentationDelegate: PresentationDelegate?

Expand All @@ -103,20 +105,23 @@ public final class AdyenSession {
delegate: delegate,
presentationDelegate: presentationDelegate,
baseAPIClient: baseAPIClient,
openAppDetector: .live,
completion: completion)
}

internal static func initialize(with configuration: Configuration,
delegate: AdyenSessionDelegate,
presentationDelegate: PresentationDelegate,
baseAPIClient: APIClientProtocol,
openAppDetector: OpenExternalAppDetector,
completion: @escaping ((Result<AdyenSession, Error>) -> Void)) {
makeSetupCall(with: configuration,
baseAPIClient: baseAPIClient) { result in
switch result {
case let .success(sessionContext):
let session = AdyenSession(configuration: configuration,
sessionContext: sessionContext)
sessionContext: sessionContext,
openAppDetector: openAppDetector)
session.delegate = delegate
session.presentationDelegate = presentationDelegate
completion(.success(session))
Expand Down Expand Up @@ -157,9 +162,11 @@ public final class AdyenSession {

internal lazy var actionComponent: ActionHandlingComponent = {
let handler = AdyenActionComponent(context: configuration.context,
configuration: configuration.actionComponent)
configuration: configuration.actionComponent,
openAppDetector: openAppDetector)
handler.delegate = self
handler.presentationDelegate = presentationDelegate
handler.openAppDetector = openAppDetector
return handler
}()

Expand All @@ -174,9 +181,10 @@ public final class AdyenSession {
.retryOnErrorAPIClient()
}()

private init(configuration: Configuration, sessionContext: Context) {
private init(configuration: Configuration, sessionContext: Context, openAppDetector: OpenExternalAppDetector) {
self.sessionContext = sessionContext
self.configuration = configuration
self.openAppDetector = openAppDetector
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal final class CardComponentAdvancedFlowExample: InitialDataAdvancedFlowPr
// MARK: - Action Handling

private lazy var adyenActionComponent: AdyenActionComponent = {
let handler = AdyenActionComponent(context: context)
let handler = AdyenActionComponent(context: context, openAppDetector: .live)
handler.configuration.threeDS.delegateAuthentication = ConfigurationConstants.delegatedAuthenticationConfigurations
handler.configuration.threeDS.requestorAppURL = URL(string: ConfigurationConstants.returnUrl)
handler.delegate = self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal final class IssuerListComponentAdvancedFlowExample: InitialDataAdvanced
// MARK: - Action Handling

private lazy var adyenActionComponent: AdyenActionComponent = {
let handler = AdyenActionComponent(context: context)
let handler = AdyenActionComponent(context: context, openAppDetector: .live)
handler.delegate = self
handler.presentationDelegate = self
return handler
Expand Down
18 changes: 9 additions & 9 deletions Demo/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,19 @@ internal struct DemoAppSettings: Codable {
)

internal static let defaultCardSettings = CardSettings(showsHolderNameField: false,
showsStorePaymentMethodField: true,
showsStoredCardSecurityCodeField: true,
showsSecurityCodeField: true,
addressMode: .none,
socialSecurityNumberMode: .auto,
koreanAuthenticationMode: .auto)
showsStorePaymentMethodField: true,
showsStoredCardSecurityCodeField: true,
showsSecurityCodeField: true,
addressMode: .none,
socialSecurityNumberMode: .auto,
koreanAuthenticationMode: .auto)

internal static let defaultDropInSettings = DropInSettings(allowDisablingStoredPaymentMethods: false,
allowsSkippingPaymentList: false,
allowPreselectedPaymentView: true)
allowsSkippingPaymentList: false,
allowPreselectedPaymentView: true)

internal static let defaultApplePaySettings = ApplePaySettings(merchantIdentifier: ConfigurationConstants.applePayMerchantIdentifier,
allowOnboarding: false)
allowOnboarding: false)

internal static let defaultAnalyticsSettings = AnalyticsSettings(isEnabled: true)

Expand Down
2 changes: 2 additions & 0 deletions Scripts/test-carthage-integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ schemes:
mkdir -p Tests
mkdir -p Source
cp "../Tests/DropIn Tests/DropInTests.swift" Tests/DropInTests.swift
cp "../Tests/DropIn Tests/DropInDelegateMock.swift" Tests/DropInDelegateMock.swift
cp "../Tests/Card Tests/Mocks/OpenExternalAppDetector+Mock.swift" Tests/OpenExternalAppDetector+Mock.swift
cp "../Tests/Card Tests/3DS2 Component/ThreeDS2PlusDACoreActionHandlerTests.swift" Tests/ThreeDS2PlusDACoreActionHandlerTests.swift
cp "../Tests/Card Tests/3DS2 Component/AnyADYServiceMock.swift" Tests/AnyADYServiceMock.swift
cp "../Tests/Card Tests/3DS2 Component/AuthenticationServiceMock.swift" Tests/AuthenticationServiceMock.swift
Expand Down
Loading
Loading