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

feat(GiniHealthSDK): UnitTests for GiniHealthSDK IPC-196 #473

Merged
merged 20 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
13cb78f
feat(GiniHealthSDK): Create unit test for GiniHealth class
razvancapra Mar 21, 2024
88d4ac8
Merge branch 'IPC-153_payment_review_screen' into IPC-194-GiniHealthS…
razvancapra Mar 21, 2024
3f7be42
feat(GiniHealthSDK): Tests for fetchbanking apps + check if document …
razvancapra Mar 22, 2024
bfbcf5c
feat(GiniHealthSDK): Extractions + Poll document tests for GiniHealth…
razvancapra Mar 25, 2024
d8ea8b6
Merge branch 'ipc-health-sdk-update' into IPC-194-GiniHealthSDK-UnitT…
razvancapra Mar 26, 2024
664e575
feat(GiniHealthSDK): GinHealthSDK get extraction tests
razvancapra Mar 27, 2024
2c6c266
feaet(GiniHealthSDK): URL Opener protocol added + tests for opening p…
razvancapra Mar 27, 2024
47dca41
feat(GiniHealtSDK): Tests for fetch data for review method + test for…
razvancapra Mar 27, 2024
a3a0562
feat(GiniHealthSDK): Payment Components Controller tests + mock payme…
razvancapra Mar 27, 2024
7796095
Merge branch 'ipc-health-sdk-update' into IPC-194-GiniHealthSDK-UnitT…
razvancapra Mar 28, 2024
511c892
Merge branch 'main' into IPC-194-GiniHealthSDK-UnitTests
razvancapra Mar 29, 2024
fb3dbc6
feat(GiniHealthSDK): PaymentComponentsController tests
razvancapra Apr 1, 2024
e34946c
feat(GiniHealthSDK): Organise test files
razvancapra Apr 1, 2024
544cef4
fix(GiniHealthSDK): Clean HealthSDKTests automate file generated
razvancapra Apr 2, 2024
9913d76
fix(GiniHealthSDK): Fix private variables in HealthAPI class
razvancapra Apr 2, 2024
3a12241
fix(GiniHealthSDK): rename openWebsite to openLink
razvancapra Apr 8, 2024
0aacac1
fix(GiniHealthSDK): Remove HealthAPI protocol and fix tests
razvancapra Apr 8, 2024
515d3fe
fix(GiniHealthSDK): URLOpener documentation
razvancapra Apr 8, 2024
b09ce45
fix(GiniHealthSDK): Clean DocumentServiceProtocol public protocol
razvancapra Apr 9, 2024
447234f
fix(GiniHealthSDKTests): fix use of forced wrap + small refactoring
razvancapra Apr 10, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,4 @@
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import Foundation
/// The Gini Health API Library
public final class GiniHealthAPI {

private let docService: DocumentService!
private let payService: PaymentService?
private var docService: DocumentService!
private var payService: PaymentService?
static var logLevel: LogLevel = .none
public var sessionDelegate: URLSessionDelegate? = nil

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,9 @@ extension Document.Links: Decodable {
extension Document.Layout: Decodable {

}

extension Document: Equatable {
public static func == (lhs: Document, rhs: Document) -> Bool {
lhs.id == rhs.id
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

struct ExtractionsContainer {
public struct ExtractionsContainer {
let extractions: [Extraction]
let compoundExtractions: [String : [[Extraction]]]?
let candidates: [Extraction.Candidate]
Expand All @@ -23,7 +23,7 @@ struct ExtractionsContainer {

extension ExtractionsContainer: Decodable {

init(from decoder: Decoder) throws {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

let decodedExtractions = try container.decode([String : Extraction].self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public struct PaymentProvider: Codable {
public var name: String
public var appSchemeIOS: String
public var colors: ProviderColors
var minAppVersion: MinAppVersions?
public var minAppVersion: MinAppVersions?
public var iconData: Data
public var appStoreUrlIOS: String?
public var universalLinkIOS: String
Expand All @@ -31,3 +31,9 @@ public struct PaymentProvider: Codable {
}
}
public typealias PaymentProviders = [PaymentProvider]

extension PaymentProvider: Equatable {
public static func == (lhs: PaymentProvider, rhs: PaymentProvider) -> Bool {
lhs.id == rhs.id
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public struct PaymentProviderResponse: Codable {
public var name: String
public var appSchemeIOS: String
public var colors: ProviderColors
var minAppVersion: MinAppVersions?
public var minAppVersion: MinAppVersions?
public var iconLocation: String
public var appStoreUrlIOS: String?
public var universalLinkIOS: String
Expand Down
5 changes: 4 additions & 1 deletion HealthSDK/GiniHealthSDK/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ let package = Package(
dependencies: ["GiniHealthAPILibrary"]),
.testTarget(
name: "GiniHealthSDKTests",
dependencies: ["GiniHealthSDK"]),
dependencies: ["GiniHealthSDK"],
resources: [
.process("Resources")
]),
]
)
52 changes: 28 additions & 24 deletions HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/GiniHealth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public enum GiniHealthError: Error {
/// Error thrown when api didn't returns payment extractions.
case noPaymentDataExtracted
}

extension GiniHealthError: Equatable {}
/**
Data structure for Payment Review Screen initialization.
*/
Expand Down Expand Up @@ -169,7 +171,9 @@ public struct DataForReview {
switch result {
case let .success(extractionResult):
if let paymentExtractions = extractionResult.payment?.first, let iban = paymentExtractions.first(where: { $0.name == "iban" })?.value, !iban.isEmpty {
completion(.success(true))
completion(.success(true))
} else if let ibanExtraction = extractionResult.extractions.first(where: { $0.name == "iban"})?.value, !ibanExtraction.isEmpty {
completion(.success(true))
} else {
completion(.success(false))
}
Expand Down Expand Up @@ -220,32 +224,32 @@ public struct DataForReview {

*/
public func getExtractions(docId: String, completion: @escaping (Result<[Extraction], GiniHealthError>) -> Void){
documentService.fetchDocument(with: docId) { result in
switch result {
case let .success(createdDocument):
self.documentService
.extractions(for: createdDocument,
cancellationToken: CancellationToken()) { result in
DispatchQueue.main.async {
switch result {
case let .success(extractionResult):
if let paymentExtractionsContainer = extractionResult.payment, let paymentExtractions = paymentExtractionsContainer.first {
completion(.success(paymentExtractions))
} else {
completion(.failure(.noPaymentDataExtracted))
}
case let .failure(error):
completion(.failure(.apiError(error)))
documentService.fetchDocument(with: docId) { result in
switch result {
case let .success(createdDocument):
self.documentService
.extractions(for: createdDocument,
cancellationToken: CancellationToken()) { result in
DispatchQueue.main.async {
switch result {
case let .success(extractionResult):
if let paymentExtractionsContainer = extractionResult.payment, let paymentExtractions = paymentExtractionsContainer.first {
completion(.success(paymentExtractions))
} else {
completion(.failure(.noPaymentDataExtracted))
}
case let .failure(error):
completion(.failure(.apiError(error)))
}
}
case let .failure(error):
DispatchQueue.main.async {
completion(.failure(.apiError(error)))
}
}
case let .failure(error):
DispatchQueue.main.async {
completion(.failure(.apiError(error)))
}
}
}
}

/**
Creates a payment request
Expand Down Expand Up @@ -279,16 +283,15 @@ public struct DataForReview {
- Parameters:
- requestID: Id of the created payment request.
- universalLink: Universal link for the selected payment provider

*/
public func openPaymentProviderApp(requestID: String, universalLink: String) {
public func openPaymentProviderApp(requestID: String, universalLink: String, urlOpener: URLOpener = URLOpener(UIApplication.shared), completion: ((Bool) -> Void)? = nil) {
let queryItems = [URLQueryItem(name: "id", value: requestID)]
let urlString = universalLink + "://payment"
var urlComponents = URLComponents(string: urlString)!
urlComponents.queryItems = queryItems
let resultUrl = urlComponents.url!
DispatchQueue.main.async {
UIApplication.shared.open(resultUrl, options: [:], completionHandler: nil)
urlOpener.openLink(url: resultUrl, completion: completion)
}
}

Expand Down Expand Up @@ -365,3 +368,4 @@ public struct DataForReview {
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,21 @@ public protocol PaymentComponentsControllerProtocol: AnyObject {
func didFetchedPaymentProviders()
}

protocol PaymentComponentsProtocol {
var isLoading: Bool { get set }
var selectedPaymentProvider: PaymentProvider? { get set }
func loadPaymentProviders()
func checkIfDocumentIsPayable(docId: String, completion: @escaping (Result<Bool, GiniHealthError>) -> Void)
func paymentView(documentId: String) -> UIView
func bankSelectionBottomSheet() -> UIViewController
func loadPaymentReviewScreenFor(documentID: String, trackingDelegate: GiniHealthTrackingDelegate?, completion: @escaping (UIViewController?, GiniHealthError?) -> Void)
func paymentInfoViewController() -> UIViewController
}

/**
The `PaymentComponentsController` class allows control over the payment components.
*/
public final class PaymentComponentsController: NSObject {
public final class PaymentComponentsController: PaymentComponentsProtocol {
/// handling the Payment Component Controller delegate
public weak var delegate: PaymentComponentsControllerProtocol?
/// handling the Payment Component view delegate
Expand Down Expand Up @@ -53,7 +64,6 @@ public final class PaymentComponentsController: NSObject {
*/
public init(giniHealth: GiniHealth) {
self.giniHealth = giniHealth
super.init()
setupListeners()
}

Expand Down
39 changes: 39 additions & 0 deletions HealthSDK/GiniHealthSDK/Sources/GiniHealthSDK/Core/URLOpener.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// URLOpener.swift
//
// Copyright © 2024 Gini GmbH. All rights reserved.
//

import UIKit

// URLOpener helper structure for better testing of the open AppStore links functionality
public struct URLOpener {
razvancapra marked this conversation as resolved.
Show resolved Hide resolved
private let application: URLOpenerProtocol

public init(_ application: URLOpenerProtocol) {
self.application = application
}

/// Opens AppStore with the provided URL
///
/// - Parameters:
/// - url: link that will be opened
/// - completion: called after opening is completed
/// param is true if website was opened successfully
/// param is false if opening failed

func openLink(url: URL, completion: ((Bool) -> Void)?) {
if application.canOpenURL(url) {
application.open(url, options: [:], completionHandler: completion)
} else {
completion?(false)
}
}
}

public protocol URLOpenerProtocol {
func canOpenURL(_ url: URL) -> Bool
func open(_ url: URL, options: [UIApplication.OpenExternalURLOptionsKey : Any], completionHandler completion: ((Bool) -> Void)?)
}

extension UIApplication: URLOpenerProtocol {}
Loading
Loading