From 8e25efdea1c13fc747e8d3aac534b66598e80c6f Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 6 Mar 2024 13:30:13 +0100 Subject: [PATCH 1/2] Fixed tests + added validation --- AdyenActions/AdyenActionComponent.swift | 29 ++++++++++++++++--- .../SDK/TwintSDKActionComponent.swift | 14 ++++----- .../Protocols/InitialDataFlowProtocol.swift | 2 +- Demo/Configuration.swift | 2 +- .../Twint/TwintSDKActionTests.swift | 9 +++--- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/AdyenActions/AdyenActionComponent.swift b/AdyenActions/AdyenActionComponent.swift index db89241bb5..8d15b879d2 100644 --- a/AdyenActions/AdyenActionComponent.swift +++ b/AdyenActions/AdyenActionComponent.swift @@ -69,10 +69,31 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen public struct Twint { - public var returnUrlScheme: String + /// The callback app scheme invoked once the Twint app is done with the payment + public var callbackAppScheme: String - public init(returnUrlScheme: String) { - self.returnUrlScheme = returnUrlScheme + /// Initializes a new instance + /// + /// - Parameter callbackAppScheme: The callback app scheme invoked once the Twint app is done with the payment + /// + /// - Important: The value of ``callbackAppScheme`` is required to only provide the scheme, + /// without a host/path/... (e.g. "my-app", not a url "my-app://...") + public init(callbackAppScheme: String) { + if !Self.isCallbackSchemeValid(callbackAppScheme) { + assertionFailure("Format of provided callbackAppScheme '\(callbackAppScheme)' is incorrect.") + } + + self.callbackAppScheme = callbackAppScheme + } + + /// Validating whether or not the provided `callbackAppScheme` only contains a scheme + private static func isCallbackSchemeValid(_ callbackAppScheme: String) -> Bool { + if let url = URL(string: callbackAppScheme), url.scheme != nil { + // If the scheme is not nil it means that more information than just the scheme was provided + return false + } + + return true } } @@ -225,7 +246,7 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen context: context, configuration: .init( style: configuration.style.awaitComponentStyle, - returnUrlScheme: twintConfiguration.returnUrlScheme, + callbackAppScheme: twintConfiguration.callbackAppScheme, localizationParameters: configuration.localizationParameters ) ) diff --git a/AdyenActions/Components/SDK/TwintSDKActionComponent.swift b/AdyenActions/Components/SDK/TwintSDKActionComponent.swift index ad65a7499c..8c696c97c3 100644 --- a/AdyenActions/Components/SDK/TwintSDKActionComponent.swift +++ b/AdyenActions/Components/SDK/TwintSDKActionComponent.swift @@ -36,27 +36,27 @@ import Foundation /// The localization parameters, leave it nil to use the default parameters. public var localizationParameters: LocalizationParameters? - /// The return url scheme + /// The callback app scheme invoked once the Twint app is done with the payment /// /// - Important: This value is required to only provide the scheme, without a host/path/.... (e.g. "my-app", not a url "my-app://...") - public let returnUrlScheme: String + public let callbackAppScheme: String /// Initializes an instance of `Configuration` /// /// - Parameters: /// - style: The Component UI style. - /// - returnUrlScheme: The url scheme of the app + /// - callbackAppScheme: The callback app scheme invoked once the Twint app is done with the payment /// - localizationParameters: The localization parameters, leave it nil to use the default parameters. /// - /// - Important: This value of ``returnUrlScheme`` is required to only provide the scheme, without a host/path/... (e.g. "my-app", not a url "my-app://...") + /// - Important: The value of ``callbackAppScheme`` is required to only provide the scheme, without a host/path/... (e.g. "my-app", not a url "my-app://...") public init( style: AwaitComponentStyle = .init(), - returnUrlScheme: String, + callbackAppScheme: String, localizationParameters: LocalizationParameters? = nil ) { self.style = style self.localizationParameters = localizationParameters - self.returnUrlScheme = returnUrlScheme + self.callbackAppScheme = callbackAppScheme } } @@ -114,7 +114,7 @@ import Foundation let error = twint.pay( withCode: action.sdkData.token, appConfiguration: app, - callback: configuration.returnUrlScheme + callback: configuration.callbackAppScheme ) if let error { diff --git a/Demo/Common/IntegrationExamples/Protocols/InitialDataFlowProtocol.swift b/Demo/Common/IntegrationExamples/Protocols/InitialDataFlowProtocol.swift index eb883a22fa..2bf7676554 100644 --- a/Demo/Common/IntegrationExamples/Protocols/InitialDataFlowProtocol.swift +++ b/Demo/Common/IntegrationExamples/Protocols/InitialDataFlowProtocol.swift @@ -48,7 +48,7 @@ extension InitialDataFlowProtocol { requestorAppURL: ConfigurationConstants.returnUrl, delegateAuthentication: ConfigurationConstants.delegatedAuthenticationConfigurations ), - twint: .init(returnUrlScheme: ConfigurationConstants.returnUrl.scheme!) + twint: .init(callbackAppScheme: ConfigurationConstants.returnUrl.scheme!) ) ) return configuration diff --git a/Demo/Configuration.swift b/Demo/Configuration.swift index 8e0adece77..564dc7e725 100644 --- a/Demo/Configuration.swift +++ b/Demo/Configuration.swift @@ -250,7 +250,7 @@ internal struct DemoAppSettings: Codable { if dropInSettings.cashAppPayEnabled { dropInConfig.cashAppPay = .init(redirectURL: ConfigurationConstants.returnUrl) } - dropInConfig.actionComponent.twint = .init(returnUrlScheme: ConfigurationConstants.returnUrl.scheme!) + dropInConfig.actionComponent.twint = .init(callbackAppScheme: ConfigurationConstants.returnUrl.scheme!) return dropInConfig } diff --git a/Tests/Actions Tests/ActionComponent/Twint/TwintSDKActionTests.swift b/Tests/Actions Tests/ActionComponent/Twint/TwintSDKActionTests.swift index 8f9f3e85ee..02536207fc 100644 --- a/Tests/Actions Tests/ActionComponent/Twint/TwintSDKActionTests.swift +++ b/Tests/Actions Tests/ActionComponent/Twint/TwintSDKActionTests.swift @@ -25,7 +25,7 @@ private extension TWAppConfiguration { private extension TwintSDKActionComponent.Configuration { static var dummy: Self { - .init(returnUrl: "ui-host://") + .init(callbackAppScheme: "ui-host") } } @@ -110,7 +110,7 @@ final class TwintSDKActionTests: XCTestCase { XCTAssertEqual(code, TwintSDKAction.dummy.sdkData.token) XCTAssertEqual(appConfiguration.appDisplayName, TWAppConfiguration.dummy.appDisplayName) XCTAssertEqual(appConfiguration.appURLScheme, TWAppConfiguration.dummy.appURLScheme) - XCTAssertEqual(callbackAppScheme, TwintSDKActionComponent.Configuration.dummy.returnUrl) + XCTAssertEqual(callbackAppScheme, TwintSDKActionComponent.Configuration.dummy.callbackAppScheme) return nil } handleController: { installedAppConfigurations, selectionHandler, cancelHandler in XCTFail("Twint controller should not have been shown") @@ -165,7 +165,7 @@ final class TwintSDKActionTests: XCTestCase { XCTAssertEqual(code, TwintSDKAction.dummy.sdkData.token) XCTAssertEqual(appConfiguration.appDisplayName, TWAppConfiguration.dummy.appDisplayName) XCTAssertEqual(appConfiguration.appURLScheme, TWAppConfiguration.dummy.appURLScheme) - XCTAssertEqual(callbackAppScheme, TwintSDKActionComponent.Configuration.dummy.returnUrl) + XCTAssertEqual(callbackAppScheme, TwintSDKActionComponent.Configuration.dummy.callbackAppScheme) return nil } handleController: { installedAppConfigurations, selectionHandler, cancelHandler in XCTAssertEqual(installedAppConfigurations, expectedAppConfigurations) @@ -176,7 +176,7 @@ final class TwintSDKActionTests: XCTestCase { XCTFail("Handle open should not have been called") return false } - + let twintActionComponent = TwintSDKActionComponent( context: Dummy.context, configuration: .dummy, @@ -310,7 +310,6 @@ final class TwintSDKActionTests: XCTestCase { ) } - func testPayError() throws { // TODO: handlePay returns an error } From 201515b296f9f6f6ef2ab5b0b69509fa070c6bc0 Mon Sep 17 00:00:00 2001 From: Neelam Sharma Date: Wed, 6 Mar 2024 16:17:58 +0100 Subject: [PATCH 2/2] Added Adyen action in AdyenTwint podspec and package --- Adyen.podspec | 1 + Package.swift | 1 + 2 files changed, 2 insertions(+) diff --git a/Adyen.podspec b/Adyen.podspec index e28778ac46..7000935333 100644 --- a/Adyen.podspec +++ b/Adyen.podspec @@ -44,6 +44,7 @@ Pod::Spec.new do |s| s.subspec 'AdyenTwint' do |plugin| plugin.source_files = 'AdyenTwint/**/*.swift' plugin.dependency 'Adyen/Core' + plugin.dependency 'Adyen/Actions' plugin.dependency 'Adyen/TwintSDK' end diff --git a/Package.swift b/Package.swift index 2dbacd3888..52288ede5e 100644 --- a/Package.swift +++ b/Package.swift @@ -188,6 +188,7 @@ let package = Package( name: "AdyenTwint", dependencies: [ .target(name: "Adyen"), + .target(name: "AdyenActions"), .target(name: "TwintSDK") ], path: "AdyenTwint"