Skip to content

Commit

Permalink
[FX-1362] Only grab the payment_method ref from the ThinPayment (#163)
Browse files Browse the repository at this point in the history
* Only grab the payment_method ref from the ThinPayment

* Update unit tests
  • Loading branch information
djoksimo authored May 9, 2024
1 parent 13e5e44 commit 962e8d2
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
10 changes: 7 additions & 3 deletions Sources/ForageSDK/Foundation/Network/LiveForageService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,11 @@ class LiveForageService: ForageService {

private func getTokenFromPayment(sessionToken: String, merchantID: String, paymentRef: String) async throws -> String {
do {
let payment = try await awaitResult { completion in
/// We only decode what we need here using `ThinPaymentModel`
/// (e.g. the associated `paymentMethodRef`)
/// beacuse many of the `PaymentModel` properties (e.g. `amount`) may be `nil`
/// until the Payment is updated and captured.
let payment: ThinPaymentModel = try await awaitResult { completion in
self.getPayment(
sessionToken: sessionToken,
merchantID: merchantID,
Expand Down Expand Up @@ -306,8 +310,8 @@ class LiveForageService: ForageService {
}
}

internal func getPayment(sessionToken: String, merchantID: String, paymentRef: String, completion: @escaping (Result<PaymentModel, Error>) -> Void) {
do { try provider.execute(model: PaymentModel.self, endpoint: ForageAPI.getPayment(sessionToken: sessionToken, merchantID: merchantID, paymentRef: paymentRef), completion: completion) } catch { completion(.failure(error)) }
internal func getPayment<T : Decodable>(sessionToken: String, merchantID: String, paymentRef: String, completion: @escaping (Result<T, Error>) -> Void) {
do { try provider.execute(model: T.self, endpoint: ForageAPI.getPayment(sessionToken: sessionToken, merchantID: merchantID, paymentRef: paymentRef), completion: completion) } catch { completion(.failure(error)) }
}

internal func getPaymentMethod(
Expand Down
14 changes: 14 additions & 0 deletions Sources/ForageSDK/Foundation/Network/Model/PaymentModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,17 @@ public struct PaymentModel: Codable {
case error
}
}

/// When using the deferred capture flow
/// the Payment may not have some `null` properties
/// (`amount`, `delivery_address`, `is_delivery`, ...) until the
/// payment is updated and captured on the server-side.
/// In turn, we only grab what we need from `ThinPaymentModel` for
/// intermediate internal SDK requests to `GET /payments/`
internal struct ThinPaymentModel: Codable {
internal let paymentMethodRef: String

private enum CodingKeys: String, CodingKey {
case paymentMethodRef = "payment_method"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ protocol ForageService: AnyObject {
/// - merchantID: The unique ID of the Merchant.
/// - paymentRef: The reference hash of the Payment.
/// - completion: The closure returns a `Result` containing either a `PaymentModel` or an `Error`. [Read more](https://docs.joinforage.app/reference/get-payment-details)
func getPayment(
func getPayment<T : Decodable>(
sessionToken: String,
merchantID: String,
paymentRef: String,
completion: @escaping (Result<PaymentModel, Error>) -> Void
completion: @escaping (Result<T, Error>) -> Void
)

/// Tokenize an EBT card using the given *ForagePANRequestModel* object
Expand Down
24 changes: 22 additions & 2 deletions Tests/ForageSDKTests/ForageServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ final class ForageServiceTests: XCTestCase {
let service = createTestService(mockSession)

let expectation = XCTestExpectation(description: "Get the Payment - should succeed")
service.getPayment(sessionToken: "auth1234", merchantID: "1234567", paymentRef: "11767381fd") { result in
service.getPayment(sessionToken: "auth1234", merchantID: "1234567", paymentRef: "11767381fd") { (result: Result<PaymentModel, Error>) in
switch result {
case let .success(payment):
XCTAssertEqual(payment.paymentMethodRef, "81dab02290")
Expand All @@ -199,6 +199,26 @@ final class ForageServiceTests: XCTestCase {
}
wait(for: [expectation], timeout: 1.0)
}

func test_getThinPayment_onSuccess_checkExpectedPayload() {
let mockSession = URLSessionMock()
mockSession.data = forageMocks.capturePaymentSuccess
mockSession.response = forageMocks.mockSuccessResponse
let service = createTestService(mockSession)

let expectation = XCTestExpectation(description: "Get the Payment - should succeed")
service.getPayment(sessionToken: "auth1234", merchantID: "1234567", paymentRef: "11767381fd") { (result: Result<ThinPaymentModel, Error>) in
switch result {
case let .success(payment):
XCTAssertEqual(payment.paymentMethodRef, "81dab02290")
expectation.fulfill()
case .failure:
XCTFail("Expected success")
}
}
wait(for: [expectation], timeout: 1.0)
}


func test_getPayment_onFailure_shouldReturnFailure() {
let mockSession = URLSessionMock()
Expand All @@ -207,7 +227,7 @@ final class ForageServiceTests: XCTestCase {
let service = createTestService(mockSession)

let expectation = XCTestExpectation(description: "Get the Payment - result should be failure")
service.getPayment(sessionToken: "auth1234", merchantID: "1234567", paymentRef: "11767381fd") { result in
service.getPayment(sessionToken: "auth1234", merchantID: "1234567", paymentRef: "11767381fd") { (result: Result<PaymentModel, Error>) in
switch result {
case .success:
XCTFail("Expected failure")
Expand Down

0 comments on commit 962e8d2

Please sign in to comment.